blob: 5337615306964964890446e596de842b30512a9f [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 Lattner5abdec72009-06-14 01:05:48 +000015#include "clang/Basic/Builtins.h"
16#include "clang/Basic/TargetBuiltins.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000017#include "clang/Basic/TargetInfo.h"
Chris Lattnerc7c6dd42008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Eli Friedman7cef49e2008-05-20 14:27:34 +000019#include "llvm/ADT/APFloat.h"
Chris Lattner1e1c0b92009-03-20 16:06:38 +000020#include "llvm/ADT/SmallString.h"
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000021#include "llvm/ADT/StringRef.h"
Chris Lattner859c37a2009-08-12 06:24:27 +000022#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/Triple.h"
Chris Lattner30ba6742009-08-10 19:03:04 +000024#include "llvm/MC/MCSectionMachO.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000025using namespace clang;
26
Chris Lattner5ba61f02006-10-14 07:39:34 +000027//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000028// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000029//===----------------------------------------------------------------------===//
30
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000031static void Define(std::vector<char> &Buf, const llvm::StringRef &Macro,
32 const llvm::StringRef &Val = "1") {
Chris Lattnerb2d486a2007-10-06 06:57:34 +000033 const char *Def = "#define ";
34 Buf.insert(Buf.end(), Def, Def+strlen(Def));
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000035 Buf.insert(Buf.end(), Macro.begin(), Macro.end());
Chris Lattnerb2d486a2007-10-06 06:57:34 +000036 Buf.push_back(' ');
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000037 Buf.insert(Buf.end(), Val.begin(), Val.end());
Chris Lattnerb2d486a2007-10-06 06:57:34 +000038 Buf.push_back('\n');
39}
40
Chris Lattner1e1c0b92009-03-20 16:06:38 +000041/// DefineStd - Define a macro name and standard variants. For example if
42/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
43/// when in GNU mode.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000044static void DefineStd(std::vector<char> &Buf, const char *MacroName,
Chris Lattner1e1c0b92009-03-20 16:06:38 +000045 const LangOptions &Opts) {
46 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000047
Chris Lattner1e1c0b92009-03-20 16:06:38 +000048 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
49 // in the user's namespace.
50 if (Opts.GNUMode)
51 Define(Buf, MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000052
Chris Lattner1e1c0b92009-03-20 16:06:38 +000053 // Define __unix.
54 llvm::SmallString<20> TmpStr;
55 TmpStr = "__";
56 TmpStr += MacroName;
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000057 Define(Buf, TmpStr.str());
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000058
Chris Lattner1e1c0b92009-03-20 16:06:38 +000059 // Define __unix__.
60 TmpStr += "__";
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000061 Define(Buf, TmpStr.str());
Chris Lattner1e1c0b92009-03-20 16:06:38 +000062}
63
Chris Lattner09d98f52008-10-05 21:50:58 +000064//===----------------------------------------------------------------------===//
65// Defines specific to certain operating systems.
66//===----------------------------------------------------------------------===//
Chris Lattner30ba6742009-08-10 19:03:04 +000067
Torok Edwinb2b37c62009-06-30 17:10:35 +000068namespace {
Douglas Gregorc05d2a12009-07-01 15:12:53 +000069template<typename TgtInfo>
70class OSTargetInfo : public TgtInfo {
Torok Edwinb2b37c62009-06-30 17:10:35 +000071protected:
Daniel Dunbar40165182009-08-24 09:10:05 +000072 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +000073 std::vector<char> &Defines) const=0;
74public:
Douglas Gregorc05d2a12009-07-01 15:12:53 +000075 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwinb2b37c62009-06-30 17:10:35 +000076 virtual void getTargetDefines(const LangOptions &Opts,
77 std::vector<char> &Defines) const {
Douglas Gregorc05d2a12009-07-01 15:12:53 +000078 TgtInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar40165182009-08-24 09:10:05 +000079 getOSDefines(Opts, TgtInfo::getTriple(), Defines);
Torok Edwin4e054162009-06-30 17:00:25 +000080 }
Torok Edwinb2b37c62009-06-30 17:10:35 +000081
82};
Chris Lattner859c37a2009-08-12 06:24:27 +000083} // end anonymous namespace
Torok Edwin4e054162009-06-30 17:00:25 +000084
Chris Lattner30ba6742009-08-10 19:03:04 +000085
Daniel Dunbar497ff132009-04-10 19:52:24 +000086static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
Chris Lattner2fe5b262009-06-23 00:43:21 +000087 Define(Defs, "__APPLE_CC__", "5621");
Eli Friedman3fd920a2008-08-20 02:34:37 +000088 Define(Defs, "__APPLE__");
89 Define(Defs, "__MACH__");
Chris Lattner81813122009-02-05 07:19:24 +000090 Define(Defs, "OBJC_NEW_PROPERTIES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000091
Chris Lattner2a5c0a32009-04-07 16:50:40 +000092 // __weak is always defined, for use in blocks and with objc pointers.
93 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000094
Chris Lattner2a5c0a32009-04-07 16:50:40 +000095 // Darwin defines __strong even in C mode (just to nothing).
96 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Chris Lattnerc2d14012009-04-07 04:48:21 +000097 Define(Defs, "__strong", "");
Chris Lattner2a5c0a32009-04-07 16:50:40 +000098 else
Chris Lattnerc2d14012009-04-07 04:48:21 +000099 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
Eli Friedmanfd4b1552009-06-04 23:00:29 +0000100
101 if (Opts.Static)
102 Define(Defs, "__STATIC__");
103 else
104 Define(Defs, "__DYNAMIC__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000105
106 if (Opts.POSIXThreads)
107 Define(Defs, "_REENTRANT", "1");
Daniel Dunbar497ff132009-04-10 19:52:24 +0000108}
109
Daniel Dunbar40165182009-08-24 09:10:05 +0000110static void getDarwinOSXDefines(std::vector<char> &Defs,
111 const llvm::Triple &Triple) {
112 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner859c37a2009-08-12 06:24:27 +0000113 return;
Mike Stump11289f42009-09-09 15:08:12 +0000114
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000115 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Daniel Dunbar497ff132009-04-10 19:52:24 +0000116 unsigned Maj, Min, Rev;
Daniel Dunbar40165182009-08-24 09:10:05 +0000117 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump11289f42009-09-09 15:08:12 +0000118
Chris Lattner859c37a2009-08-12 06:24:27 +0000119 char MacOSXStr[] = "1000";
120 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
121 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
122 MacOSXStr[2] = '0' + Maj-4;
Daniel Dunbar497ff132009-04-10 19:52:24 +0000123 }
Chris Lattner859c37a2009-08-12 06:24:27 +0000124
125 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
126 // Cap 10.4.11 -> darwin8.11 -> "1049"
127 MacOSXStr[3] = std::min(Min, 9U)+'0';
128 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
Daniel Dunbar497ff132009-04-10 19:52:24 +0000129}
130
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000131static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
Daniel Dunbar40165182009-08-24 09:10:05 +0000132 const llvm::Triple &Triple) {
133 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner859c37a2009-08-12 06:24:27 +0000134 return;
Mike Stump11289f42009-09-09 15:08:12 +0000135
Daniel Dunbar497ff132009-04-10 19:52:24 +0000136 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
137 unsigned Maj, Min, Rev;
Daniel Dunbar40165182009-08-24 09:10:05 +0000138 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump11289f42009-09-09 15:08:12 +0000139
Chris Lattner859c37a2009-08-12 06:24:27 +0000140 // When targetting iPhone OS, interpret the minor version and
141 // revision as the iPhone OS version
142 char iPhoneOSStr[] = "10000";
143 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
144 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
145 iPhoneOSStr[0] = '0' + Min;
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000146 }
Chris Lattner859c37a2009-08-12 06:24:27 +0000147
148 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
149 iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
150 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
151 iPhoneOSStr);
Eli Friedman3fd920a2008-08-20 02:34:37 +0000152}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000153
Chris Lattner2ca529c2008-12-04 23:20:07 +0000154/// GetDarwinLanguageOptions - Set the default language options for darwin.
155static void GetDarwinLanguageOptions(LangOptions &Opts,
Daniel Dunbar40165182009-08-24 09:10:05 +0000156 const llvm::Triple &Triple) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000157 Opts.NeXTRuntime = true;
Mike Stump11289f42009-09-09 15:08:12 +0000158
Daniel Dunbar40165182009-08-24 09:10:05 +0000159 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner2ca529c2008-12-04 23:20:07 +0000160 return;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000161
Daniel Dunbar40165182009-08-24 09:10:05 +0000162 unsigned MajorVersion = Triple.getDarwinMajorNumber();
Chris Lattner859c37a2009-08-12 06:24:27 +0000163
Bill Wendlingd63bbad2009-06-28 07:36:13 +0000164 // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
Chris Lattner859c37a2009-08-12 06:24:27 +0000165 if (MajorVersion > 9) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000166 Opts.Blocks = 1;
Bill Wendling18351072009-06-28 23:01:01 +0000167 Opts.setStackProtectorMode(LangOptions::SSPOn);
Bill Wendlingd63bbad2009-06-28 07:36:13 +0000168 }
Fariborz Jahanian240f2b72009-02-24 23:34:44 +0000169
Bill Wendlingd63bbad2009-06-28 07:36:13 +0000170 // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
171 // beyond.
Chris Lattner859c37a2009-08-12 06:24:27 +0000172 if (MajorVersion >= 9 && Opts.ObjC1 &&
Daniel Dunbar40165182009-08-24 09:10:05 +0000173 Triple.getArch() == llvm::Triple::x86_64)
Fariborz Jahanian30b3ac52009-02-24 23:38:42 +0000174 Opts.ObjCNonFragileABI = 1;
Chris Lattner2ca529c2008-12-04 23:20:07 +0000175}
176
Chris Lattner30ba6742009-08-10 19:03:04 +0000177namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000178template<typename Target>
179class DarwinTargetInfo : public OSTargetInfo<Target> {
180protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000181 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000182 std::vector<char> &Defines) const {
183 getDarwinDefines(Defines, Opts);
184 getDarwinOSXDefines(Defines, Triple);
185 }
Mike Stump11289f42009-09-09 15:08:12 +0000186
Torok Edwinb2b37c62009-06-30 17:10:35 +0000187 /// getDefaultLangOptions - Allow the target to specify default settings for
188 /// various language options. These may be overridden by command line
189 /// options.
190 virtual void getDefaultLangOptions(LangOptions &Opts) {
191 TargetInfo::getDefaultLangOptions(Opts);
Daniel Dunbar40165182009-08-24 09:10:05 +0000192 GetDarwinLanguageOptions(Opts, TargetInfo::getTriple());
Torok Edwinb2b37c62009-06-30 17:10:35 +0000193 }
194public:
195 DarwinTargetInfo(const std::string& triple) :
196 OSTargetInfo<Target>(triple) {
197 this->TLSSupported = false;
198 }
199
Torok Edwinb2b37c62009-06-30 17:10:35 +0000200 virtual const char *getUnicodeStringSection() const {
201 return "__TEXT,__ustring";
202 }
Mike Stump11289f42009-09-09 15:08:12 +0000203
Chris Lattner30ba6742009-08-10 19:03:04 +0000204 virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
205 // Let MCSectionMachO validate this.
206 llvm::StringRef Segment, Section;
207 unsigned TAA, StubSize;
208 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
209 TAA, StubSize);
210 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000211};
212
Chris Lattner30ba6742009-08-10 19:03:04 +0000213
Torok Edwinb2b37c62009-06-30 17:10:35 +0000214// DragonFlyBSD Target
215template<typename Target>
216class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
217protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000218 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000219 std::vector<char> &Defs) const {
220 // DragonFly defines; list based off of gcc output
221 Define(Defs, "__DragonFly__");
222 Define(Defs, "__DragonFly_cc_version", "100001");
223 Define(Defs, "__ELF__");
224 Define(Defs, "__KPRINTF_ATTRIBUTE__");
225 Define(Defs, "__tune_i386__");
226 DefineStd(Defs, "unix", Opts);
227 }
228public:
Mike Stump11289f42009-09-09 15:08:12 +0000229 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000230 : OSTargetInfo<Target>(triple) {}
231};
232
233// FreeBSD Target
234template<typename Target>
235class FreeBSDTargetInfo : public OSTargetInfo<Target> {
236protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000237 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000238 std::vector<char> &Defs) const {
239 // FreeBSD defines; list based off of gcc output
240
Daniel Dunbar40165182009-08-24 09:10:05 +0000241 // FIXME: Move version number handling to llvm::Triple.
242 const char *FreeBSD = strstr(Triple.getTriple().c_str(),
243 "-freebsd");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000244 FreeBSD += strlen("-freebsd");
245 char release[] = "X";
246 release[0] = FreeBSD[0];
247 char version[] = "X00001";
248 version[0] = FreeBSD[0];
249
250 Define(Defs, "__FreeBSD__", release);
251 Define(Defs, "__FreeBSD_cc_version", version);
252 Define(Defs, "__KPRINTF_ATTRIBUTE__");
253 DefineStd(Defs, "unix", Opts);
254 Define(Defs, "__ELF__", "1");
255 }
256public:
Mike Stump11289f42009-09-09 15:08:12 +0000257 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands9cb27e92009-07-08 13:55:08 +0000258 : OSTargetInfo<Target>(triple) {
259 this->UserLabelPrefix = "";
260 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000261};
262
263// Linux target
264template<typename Target>
265class LinuxTargetInfo : public OSTargetInfo<Target> {
266protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000267 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000268 std::vector<char> &Defs) const {
269 // Linux defines; list based off of gcc output
270 DefineStd(Defs, "unix", Opts);
271 DefineStd(Defs, "linux", Opts);
272 Define(Defs, "__gnu_linux__");
273 Define(Defs, "__ELF__", "1");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000274 if (Opts.POSIXThreads)
275 Define(Defs, "_REENTRANT", "1");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000276 }
277public:
Mike Stump11289f42009-09-09 15:08:12 +0000278 LinuxTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000279 : OSTargetInfo<Target>(triple) {
280 this->UserLabelPrefix = "";
281 }
282};
283
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000284// NetBSD Target
285template<typename Target>
286class NetBSDTargetInfo : public OSTargetInfo<Target> {
287protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000288 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000289 std::vector<char> &Defs) const {
290 // NetBSD defines; list based off of gcc output
291 Define(Defs, "__NetBSD__", "1");
292 Define(Defs, "__unix__", "1");
293 Define(Defs, "__ELF__", "1");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000294 if (Opts.POSIXThreads)
295 Define(Defs, "_POSIX_THREADS", "1");
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000296 }
297public:
Mike Stump11289f42009-09-09 15:08:12 +0000298 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000299 : OSTargetInfo<Target>(triple) {
300 this->UserLabelPrefix = "";
301 }
302};
303
Torok Edwinb2b37c62009-06-30 17:10:35 +0000304// OpenBSD Target
305template<typename Target>
306class OpenBSDTargetInfo : public OSTargetInfo<Target> {
307protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000308 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000309 std::vector<char> &Defs) const {
310 // OpenBSD defines; list based off of gcc output
311
312 Define(Defs, "__OpenBSD__", "1");
313 DefineStd(Defs, "unix", Opts);
314 Define(Defs, "__ELF__", "1");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000315 if (Opts.POSIXThreads)
316 Define(Defs, "_POSIX_THREADS", "1");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000317 }
318public:
Mike Stump11289f42009-09-09 15:08:12 +0000319 OpenBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000320 : OSTargetInfo<Target>(triple) {}
321};
322
323// Solaris target
324template<typename Target>
325class SolarisTargetInfo : public OSTargetInfo<Target> {
326protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000327 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000328 std::vector<char> &Defs) const {
329 DefineStd(Defs, "sun", Opts);
330 DefineStd(Defs, "unix", Opts);
331 Define(Defs, "__ELF__");
332 Define(Defs, "__svr4__");
333 Define(Defs, "__SVR4");
334 }
335public:
Mike Stump11289f42009-09-09 15:08:12 +0000336 SolarisTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000337 : OSTargetInfo<Target>(triple) {
338 this->UserLabelPrefix = "";
339 this->WCharType = this->SignedLong;
340 // FIXME: WIntType should be SignedLong
341 }
342};
Mike Stump11289f42009-09-09 15:08:12 +0000343} // end anonymous namespace.
Torok Edwinb2b37c62009-06-30 17:10:35 +0000344
Chris Lattner09d98f52008-10-05 21:50:58 +0000345//===----------------------------------------------------------------------===//
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000346// Specific target implementations.
347//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000348
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000349namespace {
350// PPC abstract base class
351class PPCTargetInfo : public TargetInfo {
352 static const Builtin::Info BuiltinInfo[];
353 static const char * const GCCRegNames[];
354 static const TargetInfo::GCCRegAlias GCCRegAliases[];
355
356public:
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000357 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
358
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000359 virtual void getTargetBuiltins(const Builtin::Info *&Records,
360 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000361 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000362 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000363 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000364
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000365 virtual void getTargetDefines(const LangOptions &Opts,
366 std::vector<char> &Defines) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000367
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000368 virtual const char *getVAListDeclaration() const {
Chris Lattner69f9bc22008-10-27 01:11:29 +0000369 return "typedef char* __builtin_va_list;";
370 // This is the right definition for ABI/V4: System V.4/eabi.
371 /*return "typedef struct __va_list_tag {"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000372 " unsigned char gpr;"
373 " unsigned char fpr;"
374 " unsigned short reserved;"
375 " void* overflow_arg_area;"
376 " void* reg_save_area;"
Chris Lattner69f9bc22008-10-27 01:11:29 +0000377 "} __builtin_va_list[1];";*/
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000378 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000379 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000380 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000381 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000382 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000383 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000384 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000385 switch (*Name) {
Anders Carlssonf511f642007-11-27 04:11:28 +0000386 default: return false;
387 case 'O': // Zero
388 return true;
389 case 'b': // Base register
390 case 'f': // Floating point register
Chris Lattnerd9725f72009-04-26 07:16:29 +0000391 Info.setAllowsRegister();
Anders Carlssonf511f642007-11-27 04:11:28 +0000392 return true;
393 }
394 }
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000395 virtual void getDefaultLangOptions(LangOptions &Opts) {
396 TargetInfo::getDefaultLangOptions(Opts);
397 Opts.CharIsSigned = false;
398 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000399 virtual const char *getClobbers() const {
400 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000401 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000402};
Anders Carlssonf511f642007-11-27 04:11:28 +0000403
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000404const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000405#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
406#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000407#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000408};
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000409
410
Chris Lattnerecd49032009-03-02 22:27:17 +0000411/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
412/// #defines that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000413void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
414 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000415 // Target identification.
416 Define(Defs, "__ppc__");
417 Define(Defs, "_ARCH_PPC");
418 Define(Defs, "__POWERPC__");
419 if (PointerWidth == 64) {
420 Define(Defs, "_ARCH_PPC64");
421 Define(Defs, "_LP64");
422 Define(Defs, "__LP64__");
423 Define(Defs, "__ppc64__");
424 } else {
425 Define(Defs, "__ppc__");
426 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000427
Chris Lattnerecd49032009-03-02 22:27:17 +0000428 // Target properties.
429 Define(Defs, "_BIG_ENDIAN");
430 Define(Defs, "__BIG_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000431
Chris Lattnerecd49032009-03-02 22:27:17 +0000432 // Subtarget options.
433 Define(Defs, "__NATURAL_ALIGNMENT__");
434 Define(Defs, "__REGISTER_PREFIX__", "");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000435
Chris Lattnerecd49032009-03-02 22:27:17 +0000436 // FIXME: Should be controlled by command line option.
437 Define(Defs, "__LONG_DOUBLE_128__");
438}
439
Chris Lattner17df24e2008-04-21 18:56:49 +0000440
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000441const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000442 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
443 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
444 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
445 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
446 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
447 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
448 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
449 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000450 "mq", "lr", "ctr", "ap",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000451 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000452 "xer",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000453 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
454 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
455 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
456 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000457 "vrsave", "vscr",
458 "spe_acc", "spefscr",
459 "sfp"
460};
Chris Lattner10a5b382007-01-29 05:24:35 +0000461
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000462void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000463 unsigned &NumNames) const {
464 Names = GCCRegNames;
465 NumNames = llvm::array_lengthof(GCCRegNames);
466}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000467
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000468const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
469 // While some of these aliases do map to different registers
470 // they still share the same register name.
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000471 { { "0" }, "r0" },
472 { { "1"}, "r1" },
473 { { "2" }, "r2" },
474 { { "3" }, "r3" },
475 { { "4" }, "r4" },
476 { { "5" }, "r5" },
477 { { "6" }, "r6" },
478 { { "7" }, "r7" },
479 { { "8" }, "r8" },
480 { { "9" }, "r9" },
481 { { "10" }, "r10" },
482 { { "11" }, "r11" },
483 { { "12" }, "r12" },
484 { { "13" }, "r13" },
485 { { "14" }, "r14" },
486 { { "15" }, "r15" },
487 { { "16" }, "r16" },
488 { { "17" }, "r17" },
489 { { "18" }, "r18" },
490 { { "19" }, "r19" },
491 { { "20" }, "r20" },
492 { { "21" }, "r21" },
493 { { "22" }, "r22" },
494 { { "23" }, "r23" },
495 { { "24" }, "r24" },
496 { { "25" }, "r25" },
497 { { "26" }, "r26" },
498 { { "27" }, "r27" },
499 { { "28" }, "r28" },
500 { { "29" }, "r29" },
501 { { "30" }, "r30" },
502 { { "31" }, "r31" },
503 { { "fr0" }, "f0" },
504 { { "fr1" }, "f1" },
505 { { "fr2" }, "f2" },
506 { { "fr3" }, "f3" },
507 { { "fr4" }, "f4" },
508 { { "fr5" }, "f5" },
509 { { "fr6" }, "f6" },
510 { { "fr7" }, "f7" },
511 { { "fr8" }, "f8" },
512 { { "fr9" }, "f9" },
Mike Stumpfaacf012009-09-17 21:15:00 +0000513 { { "fr10" }, "f10" },
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000514 { { "fr11" }, "f11" },
515 { { "fr12" }, "f12" },
516 { { "fr13" }, "f13" },
517 { { "fr14" }, "f14" },
518 { { "fr15" }, "f15" },
519 { { "fr16" }, "f16" },
520 { { "fr17" }, "f17" },
521 { { "fr18" }, "f18" },
522 { { "fr19" }, "f19" },
523 { { "fr20" }, "f20" },
524 { { "fr21" }, "f21" },
525 { { "fr22" }, "f22" },
526 { { "fr23" }, "f23" },
527 { { "fr24" }, "f24" },
528 { { "fr25" }, "f25" },
529 { { "fr26" }, "f26" },
530 { { "fr27" }, "f27" },
531 { { "fr28" }, "f28" },
532 { { "fr29" }, "f29" },
533 { { "fr30" }, "f30" },
534 { { "fr31" }, "f31" },
535 { { "cc" }, "cr0" },
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000536};
537
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000538void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000539 unsigned &NumAliases) const {
540 Aliases = GCCRegAliases;
541 NumAliases = llvm::array_lengthof(GCCRegAliases);
542}
543} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000544
Chris Lattner5ba61f02006-10-14 07:39:34 +0000545namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000546class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000547public:
Eli Friedman873f65a2008-08-21 00:13:15 +0000548 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
549 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
550 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
551 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000552};
553} // end anonymous namespace.
554
555namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000556class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000557public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000558 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000559 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2857ccb2009-07-01 03:36:11 +0000560 IntMaxType = SignedLong;
561 UIntMaxType = UnsignedLong;
562 Int64Type = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000563 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
564 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000565 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000566};
567} // end anonymous namespace.
568
Chris Lattner5ba61f02006-10-14 07:39:34 +0000569namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000570// Namespace for x86 abstract base class
571const Builtin::Info BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000572#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
573#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000574#include "clang/Basic/BuiltinsX86.def"
Eli Friedman3fd920a2008-08-20 02:34:37 +0000575};
Eli Friedmanb5366062008-05-20 14:21:01 +0000576
Eli Friedman3fd920a2008-08-20 02:34:37 +0000577const char *GCCRegNames[] = {
578 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
579 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
580 "argp", "flags", "fspr", "dirflag", "frame",
581 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
582 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
583 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
584 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
585};
586
587const TargetInfo::GCCRegAlias GCCRegAliases[] = {
588 { { "al", "ah", "eax", "rax" }, "ax" },
589 { { "bl", "bh", "ebx", "rbx" }, "bx" },
590 { { "cl", "ch", "ecx", "rcx" }, "cx" },
591 { { "dl", "dh", "edx", "rdx" }, "dx" },
592 { { "esi", "rsi" }, "si" },
593 { { "edi", "rdi" }, "di" },
594 { { "esp", "rsp" }, "sp" },
595 { { "ebp", "rbp" }, "bp" },
596};
597
598// X86 target abstract base class; x86-32 and x86-64 are very close, so
599// most of the implementation can be shared.
600class X86TargetInfo : public TargetInfo {
Chris Lattner96e43572009-03-02 22:40:39 +0000601 enum X86SSEEnum {
602 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
603 } SSELevel;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000604public:
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000605 X86TargetInfo(const std::string& triple)
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000606 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000607 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +0000608 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000609 virtual void getTargetBuiltins(const Builtin::Info *&Records,
610 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000611 Records = BuiltinInfo;
612 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000613 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000614 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000615 unsigned &NumNames) const {
616 Names = GCCRegNames;
617 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000618 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000619 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000620 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000621 Aliases = GCCRegAliases;
622 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +0000623 }
Anders Carlsson58436352009-02-28 17:11:49 +0000624 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000625 TargetInfo::ConstraintInfo &info) const;
626 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +0000627 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000628 return "~{dirflag},~{fpsr},~{flags}";
629 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000630 virtual void getTargetDefines(const LangOptions &Opts,
631 std::vector<char> &Defines) const;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000632 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
633 const std::string &Name,
634 bool Enabled) const;
Mike Stump11289f42009-09-09 15:08:12 +0000635 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000636 llvm::StringMap<bool> &Features) const;
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000637 virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
Chris Lattner5ba61f02006-10-14 07:39:34 +0000638};
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000639
Mike Stump11289f42009-09-09 15:08:12 +0000640void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000641 llvm::StringMap<bool> &Features) const {
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000642 // FIXME: This should not be here.
643 Features["3dnow"] = false;
644 Features["3dnowa"] = false;
645 Features["mmx"] = false;
646 Features["sse"] = false;
647 Features["sse2"] = false;
648 Features["sse3"] = false;
649 Features["ssse3"] = false;
650 Features["sse41"] = false;
651 Features["sse42"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000652
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000653 // LLVM does not currently recognize this.
654 // Features["sse4a"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000655
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000656 // FIXME: This *really* should not be here.
657
658 // X86_64 always has SSE2.
659 if (PointerWidth == 64)
660 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
661
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000662 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
663 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
664 ;
665 else if (CPU == "pentium-mmx" || CPU == "pentium2")
666 setFeatureEnabled(Features, "mmx", true);
667 else if (CPU == "pentium3")
668 setFeatureEnabled(Features, "sse", true);
669 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
670 setFeatureEnabled(Features, "sse2", true);
671 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
672 setFeatureEnabled(Features, "sse3", true);
673 else if (CPU == "core2")
674 setFeatureEnabled(Features, "ssse3", true);
675 else if (CPU == "penryn") {
676 setFeatureEnabled(Features, "sse4", true);
677 Features["sse42"] = false;
678 } else if (CPU == "atom")
679 setFeatureEnabled(Features, "sse3", true);
680 else if (CPU == "corei7")
681 setFeatureEnabled(Features, "sse4", true);
682 else if (CPU == "k6" || CPU == "winchip-c6")
683 setFeatureEnabled(Features, "mmx", true);
Mike Stump11289f42009-09-09 15:08:12 +0000684 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000685 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
686 setFeatureEnabled(Features, "mmx", true);
687 setFeatureEnabled(Features, "3dnow", true);
688 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
689 setFeatureEnabled(Features, "sse", true);
690 setFeatureEnabled(Features, "3dnowa", true);
691 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
692 CPU == "athlon-fx") {
Mike Stump11289f42009-09-09 15:08:12 +0000693 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000694 setFeatureEnabled(Features, "3dnowa", true);
695 } else if (CPU == "c3-2")
696 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000697}
698
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000699bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump11289f42009-09-09 15:08:12 +0000700 const std::string &Name,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000701 bool Enabled) const {
702 // FIXME: This *really* should not be here.
703 if (!Features.count(Name) && Name != "sse4")
704 return false;
705
706 if (Enabled) {
707 if (Name == "mmx")
708 Features["mmx"] = true;
709 else if (Name == "sse")
710 Features["mmx"] = Features["sse"] = true;
711 else if (Name == "sse2")
712 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
713 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000714 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000715 Features["sse3"] = true;
716 else if (Name == "ssse3")
Mike Stump11289f42009-09-09 15:08:12 +0000717 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000718 Features["ssse3"] = true;
719 else if (Name == "sse4")
Mike Stump11289f42009-09-09 15:08:12 +0000720 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000721 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
722 else if (Name == "3dnow")
723 Features["3dnowa"] = true;
724 else if (Name == "3dnowa")
725 Features["3dnow"] = Features["3dnowa"] = true;
726 } else {
727 if (Name == "mmx")
Mike Stump11289f42009-09-09 15:08:12 +0000728 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000729 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
730 else if (Name == "sse")
Mike Stump11289f42009-09-09 15:08:12 +0000731 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000732 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
733 else if (Name == "sse2")
Mike Stump11289f42009-09-09 15:08:12 +0000734 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000735 Features["sse41"] = Features["sse42"] = false;
736 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000737 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000738 Features["sse42"] = false;
739 else if (Name == "ssse3")
740 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
741 else if (Name == "sse4")
742 Features["sse41"] = Features["sse42"] = false;
743 else if (Name == "3dnow")
744 Features["3dnow"] = Features["3dnowa"] = false;
745 else if (Name == "3dnowa")
746 Features["3dnowa"] = false;
747 }
748
749 return true;
750}
751
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000752/// HandleTargetOptions - Perform initialization based on the user
753/// configured set of features.
754void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
755 if (Features.lookup("sse42"))
756 SSELevel = SSE42;
757 else if (Features.lookup("sse41"))
758 SSELevel = SSE41;
759 else if (Features.lookup("ssse3"))
760 SSELevel = SSSE3;
761 else if (Features.lookup("sse3"))
762 SSELevel = SSE3;
763 else if (Features.lookup("sse2"))
764 SSELevel = SSE2;
765 else if (Features.lookup("sse"))
766 SSELevel = SSE1;
767 else if (Features.lookup("mmx"))
768 SSELevel = MMX;
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000769}
Chris Lattnerecd49032009-03-02 22:27:17 +0000770
771/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
772/// that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000773void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
774 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000775 // Target identification.
776 if (PointerWidth == 64) {
777 Define(Defs, "_LP64");
778 Define(Defs, "__LP64__");
779 Define(Defs, "__amd64__");
780 Define(Defs, "__amd64");
781 Define(Defs, "__x86_64");
782 Define(Defs, "__x86_64__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000783 } else {
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000784 DefineStd(Defs, "i386", Opts);
Chris Lattnerecd49032009-03-02 22:27:17 +0000785 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000786
Chris Lattnerecd49032009-03-02 22:27:17 +0000787 // Target properties.
788 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000789
Chris Lattnerecd49032009-03-02 22:27:17 +0000790 // Subtarget options.
791 Define(Defs, "__nocona");
792 Define(Defs, "__nocona__");
793 Define(Defs, "__tune_nocona__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000794 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner96e43572009-03-02 22:40:39 +0000795
Chris Lattner6df41af2009-04-19 17:32:33 +0000796 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
797 // functions in glibc header files that use FP Stack inline asm which the
798 // backend can't deal with (PR879).
799 Define(Defs, "__NO_MATH_INLINES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000800
Chris Lattner96e43572009-03-02 22:40:39 +0000801 // Each case falls through to the previous one here.
802 switch (SSELevel) {
803 case SSE42:
804 Define(Defs, "__SSE4_2__");
805 case SSE41:
806 Define(Defs, "__SSE4_1__");
807 case SSSE3:
808 Define(Defs, "__SSSE3__");
809 case SSE3:
810 Define(Defs, "__SSE3__");
811 case SSE2:
812 Define(Defs, "__SSE2__");
813 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
814 case SSE1:
815 Define(Defs, "__SSE__");
816 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
817 case MMX:
818 Define(Defs, "__MMX__");
819 case NoMMXSSE:
820 break;
821 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000822}
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000823
824
Eli Friedman3fd920a2008-08-20 02:34:37 +0000825bool
Anders Carlsson58436352009-02-28 17:11:49 +0000826X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000827 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000828 switch (*Name) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000829 default: return false;
830 case 'a': // eax.
831 case 'b': // ebx.
832 case 'c': // ecx.
833 case 'd': // edx.
834 case 'S': // esi.
835 case 'D': // edi.
836 case 'A': // edx:eax.
837 case 't': // top of floating point stack.
838 case 'u': // second from top of floating point stack.
839 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +0000840 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +0000841 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000842 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000843 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000844 // x86_64 instructions.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000845 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000846 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000847 case 'N': // unsigned 8-bit integer constant for use with in and out
848 // instructions.
Eli Friedmancf432d32009-06-08 20:45:44 +0000849 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
Chris Lattnerd9725f72009-04-26 07:16:29 +0000850 Info.setAllowsRegister();
Eli Friedman3fd920a2008-08-20 02:34:37 +0000851 return true;
852 }
853}
854
855std::string
856X86TargetInfo::convertConstraint(const char Constraint) const {
857 switch (Constraint) {
858 case 'a': return std::string("{ax}");
859 case 'b': return std::string("{bx}");
860 case 'c': return std::string("{cx}");
861 case 'd': return std::string("{dx}");
862 case 'S': return std::string("{si}");
863 case 'D': return std::string("{di}");
864 case 't': // top of floating point stack.
865 return std::string("{st}");
866 case 'u': // second from top of floating point stack.
867 return std::string("{st(1)}"); // second from top of floating point stack.
868 default:
869 return std::string(1, Constraint);
870 }
871}
Eli Friedman3fd920a2008-08-20 02:34:37 +0000872} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +0000873
874namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000875// X86-32 generic target
876class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000877public:
Eli Friedman3fd920a2008-08-20 02:34:37 +0000878 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
879 DoubleAlign = LongLongAlign = 32;
880 LongDoubleWidth = 96;
881 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +0000882 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
883 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
884 "a0:0:64-f80:32:32";
Eli Friedman32ca82a2009-03-29 20:31:09 +0000885 SizeType = UnsignedInt;
886 PtrDiffType = SignedInt;
887 IntPtrType = SignedInt;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +0000888 RegParmMax = 3;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000889 }
890 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000891 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000892 }
Chris Lattnerd545ad12009-09-23 06:06:36 +0000893
894 int getEHDataRegisterNumber(unsigned RegNo) const {
895 if (RegNo == 0) return 0;
896 if (RegNo == 1) return 2;
897 return -1;
898 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000899};
900} // end anonymous namespace
901
902namespace {
Eli Friedmane3aa4542009-07-05 18:47:56 +0000903class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
904public:
905 OpenBSDI386TargetInfo(const std::string& triple) :
906 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
907 SizeType = UnsignedLong;
908 IntPtrType = SignedLong;
Eli Friedman245f2292009-07-05 22:31:18 +0000909 PtrDiffType = SignedLong;
Eli Friedmane3aa4542009-07-05 18:47:56 +0000910 }
911};
912} // end anonymous namespace
913
914namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000915class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000916public:
Torok Edwinb2b37c62009-06-30 17:10:35 +0000917 DarwinI386TargetInfo(const std::string& triple) :
918 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000919 LongDoubleWidth = 128;
920 LongDoubleAlign = 128;
Eli Friedman32ca82a2009-03-29 20:31:09 +0000921 SizeType = UnsignedLong;
922 IntPtrType = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000923 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
924 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
925 "a0:0:64-f80:128:128";
Torok Edwin4e054162009-06-30 17:00:25 +0000926 }
927
Eli Friedman3fd920a2008-08-20 02:34:37 +0000928};
Daniel Dunbar10de9e62009-06-29 20:52:51 +0000929} // end anonymous namespace
930
931namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000932// x86-32 Windows target
933class WindowsX86_32TargetInfo : public X86_32TargetInfo {
934public:
935 WindowsX86_32TargetInfo(const std::string& triple)
936 : X86_32TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +0000937 TLSSupported = false;
Chris Lattner46be2e12009-06-24 17:12:15 +0000938 WCharType = UnsignedShort;
Eli Friedmanaa27a872009-06-08 06:11:14 +0000939 WCharWidth = WCharAlign = 16;
Eli Friedmanebb9e4d2009-06-08 21:16:17 +0000940 DoubleAlign = LongLongAlign = 64;
941 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
942 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
943 "a0:0:64-f80:32:32";
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000944 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000945 virtual void getTargetDefines(const LangOptions &Opts,
946 std::vector<char> &Defines) const {
947 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000948 // This list is based off of the the list of things MingW defines
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000949 Define(Defines, "_WIN32");
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000950 DefineStd(Defines, "WIN32", Opts);
951 DefineStd(Defines, "WINNT", Opts);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000952 Define(Defines, "_X86_");
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000953 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +0000954};
955} // end anonymous namespace
Eli Friedmanaa27a872009-06-08 06:11:14 +0000956
Daniel Dunbar3e7a7232009-09-23 07:31:35 +0000957namespace {
958
959/// GetWindowsVisualStudioLanguageOptions - Set the default language options for Windows.
960static void GetWindowsVisualStudioLanguageOptions(LangOptions &Opts) {
961 Opts.Microsoft = true;
962}
963
964// x86-32 Windows Visual Studio target
965class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
966public:
967 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
968 : WindowsX86_32TargetInfo(triple) {
969 }
970 virtual void getTargetDefines(const LangOptions &Opts,
971 std::vector<char> &Defines) const {
972 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
973 // The value of the following reflects processor type.
974 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
975 // We lost the original triple, so we use the default.
976 Define(Defines, "_M_IX86", "600");
977 }
Eli Friedmanaa27a872009-06-08 06:11:14 +0000978 virtual void getDefaultLangOptions(LangOptions &Opts) {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +0000979 WindowsX86_32TargetInfo::getDefaultLangOptions(Opts);
980 GetWindowsVisualStudioLanguageOptions(Opts);
981 }
982};
983} // end anonymous namespace
984
985namespace {
986// x86-32 MinGW target
987class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
988public:
989 MinGWX86_32TargetInfo(const std::string& triple)
990 : WindowsX86_32TargetInfo(triple) {
991 }
992 virtual void getTargetDefines(const LangOptions &Opts,
993 std::vector<char> &Defines) const {
994 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
995 Define(Defines, "__MSVCRT__");
996 Define(Defines, "__MINGW32__");
Cedric Venetbc8d0de2009-09-27 10:09:11 +0000997 Define(Defines, "__declspec", "__declspec");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +0000998 }
999};
1000} // end anonymous namespace
1001
1002namespace {
1003// x86-32 Cygwin target
1004class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1005public:
1006 CygwinX86_32TargetInfo(const std::string& triple)
1007 : X86_32TargetInfo(triple) {
1008 TLSSupported = false;
1009 WCharType = UnsignedShort;
1010 WCharWidth = WCharAlign = 16;
1011 DoubleAlign = LongLongAlign = 64;
1012 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1013 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
1014 "a0:0:64-f80:32:32";
1015 }
1016 virtual void getTargetDefines(const LangOptions &Opts,
1017 std::vector<char> &Defines) const {
1018 X86_32TargetInfo::getTargetDefines(Opts, Defines);
1019 Define(Defines, "__CYGWIN__");
1020 Define(Defines, "__CYGWIN32__");
1021 DefineStd(Defines, "unix", Opts);
Eli Friedmanaa27a872009-06-08 06:11:14 +00001022 }
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001023};
1024} // end anonymous namespace
1025
1026namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001027// x86-64 generic target
1028class X86_64TargetInfo : public X86TargetInfo {
1029public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001030 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +00001031 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +00001032 LongDoubleWidth = 128;
1033 LongDoubleAlign = 128;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001034 IntMaxType = SignedLong;
1035 UIntMaxType = UnsignedLong;
Eli Friedman2857ccb2009-07-01 03:36:11 +00001036 Int64Type = SignedLong;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001037 RegParmMax = 6;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001038
Eli Friedman873f65a2008-08-21 00:13:15 +00001039 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1040 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Daniel Dunbareed62b72009-06-08 22:39:13 +00001041 "a0:0:64-s0:64:64-f80:128:128";
Chris Lattner10a5b382007-01-29 05:24:35 +00001042 }
Anders Carlssona7408e72007-10-13 00:45:48 +00001043 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001044 return "typedef struct __va_list_tag {"
1045 " unsigned gp_offset;"
1046 " unsigned fp_offset;"
1047 " void* overflow_arg_area;"
1048 " void* reg_save_area;"
Eli Friedmanfb36b022009-07-03 00:45:06 +00001049 "} __va_list_tag;"
1050 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001051 }
Chris Lattnerd545ad12009-09-23 06:06:36 +00001052
1053 int getEHDataRegisterNumber(unsigned RegNo) const {
1054 if (RegNo == 0) return 0;
1055 if (RegNo == 1) return 1;
1056 return -1;
1057 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001058};
1059} // end anonymous namespace
1060
1061namespace {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001062// x86-64 Windows target
1063class WindowsX86_64TargetInfo : public X86_64TargetInfo {
1064public:
1065 WindowsX86_64TargetInfo(const std::string& triple)
1066 : X86_64TargetInfo(triple) {
1067 TLSSupported = false;
1068 WCharType = UnsignedShort;
1069 WCharWidth = WCharAlign = 16;
Mike Stumpaf9afe92009-10-08 23:00:00 +00001070 LongWidth = LongAlign = 32;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001071 DoubleAlign = LongLongAlign = 64;
1072 }
1073 virtual void getTargetDefines(const LangOptions &Opts,
1074 std::vector<char> &Defines) const {
1075 X86_64TargetInfo::getTargetDefines(Opts, Defines);
1076 Define(Defines, "_WIN64");
1077 DefineStd(Defines, "WIN64", Opts);
1078 }
1079};
1080} // end anonymous namespace
1081
1082namespace {
1083// x86-64 Windows Visual Studio target
1084class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1085public:
1086 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1087 : WindowsX86_64TargetInfo(triple) {
1088 }
1089 virtual void getTargetDefines(const LangOptions &Opts,
1090 std::vector<char> &Defines) const {
1091 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1092 Define(Defines, "_M_X64");
1093 }
1094 virtual const char *getVAListDeclaration() const {
1095 return "typedef char* va_list;";
1096 }
1097};
1098} // end anonymous namespace
1099
1100namespace {
1101// x86-64 MinGW target
1102class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1103public:
1104 MinGWX86_64TargetInfo(const std::string& triple)
1105 : WindowsX86_64TargetInfo(triple) {
1106 }
1107 virtual void getTargetDefines(const LangOptions &Opts,
1108 std::vector<char> &Defines) const {
1109 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1110 Define(Defines, "__MSVCRT__");
1111 Define(Defines, "__MINGW64__");
1112 Define(Defines, "__declspec");
1113 }
1114};
1115} // end anonymous namespace
1116
1117namespace {
Eli Friedman2857ccb2009-07-01 03:36:11 +00001118class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1119public:
Mike Stump11289f42009-09-09 15:08:12 +00001120 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman2857ccb2009-07-01 03:36:11 +00001121 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1122 Int64Type = SignedLongLong;
1123 }
1124};
1125} // end anonymous namespace
1126
1127namespace {
Eli Friedman245f2292009-07-05 22:31:18 +00001128class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1129public:
Mike Stump11289f42009-09-09 15:08:12 +00001130 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman245f2292009-07-05 22:31:18 +00001131 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1132 IntMaxType = SignedLongLong;
1133 UIntMaxType = UnsignedLongLong;
1134 Int64Type = SignedLongLong;
1135 }
1136};
1137} // end anonymous namespace
1138
1139namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001140class ARMTargetInfo : public TargetInfo {
Mike Stump9d54bd72009-04-08 02:07:04 +00001141 enum {
1142 Armv4t,
1143 Armv5,
1144 Armv6,
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001145 Armv7a,
Mike Stump9d54bd72009-04-08 02:07:04 +00001146 XScale
1147 } ArmArch;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001148
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001149 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1150 static const char * const GCCRegNames[];
1151
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001152 std::string ABI;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001153 bool IsThumb;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001154
Chris Lattner17df24e2008-04-21 18:56:49 +00001155public:
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001156 ARMTargetInfo(const std::string &TripleStr)
1157 : TargetInfo(TripleStr), ABI("aapcs-linux"), IsThumb(false)
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001158 {
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001159 llvm::Triple Triple(TripleStr);
1160
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001161 SizeType = UnsignedInt;
1162 PtrDiffType = SignedInt;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001163
1164 // FIXME: This shouldn't be done this way, we should use features to
1165 // indicate the arch. See lib/Driver/Tools.cpp.
1166 llvm::StringRef Version(""), Arch = Triple.getArchName();
1167 if (Arch.startswith("arm"))
1168 Version = Arch.substr(3);
1169 else if (Arch.startswith("thumb"))
1170 Version = Arch.substr(5);
1171 if (Version == "v7")
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001172 ArmArch = Armv7a;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001173 else if (Version.empty() || Version == "v6" || Version == "v6t2")
Mike Stump9d54bd72009-04-08 02:07:04 +00001174 ArmArch = Armv6;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001175 else if (Version == "v5")
Mike Stump9d54bd72009-04-08 02:07:04 +00001176 ArmArch = Armv5;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001177 else if (Version == "v4t")
Mike Stump9d54bd72009-04-08 02:07:04 +00001178 ArmArch = Armv4t;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001179 else if (Arch == "xscale" || Arch == "thumbv5e")
Mike Stump9d54bd72009-04-08 02:07:04 +00001180 ArmArch = XScale;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001181 else
Chris Lattner0dc10262009-04-23 04:22:04 +00001182 ArmArch = Armv6;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001183
1184 if (Arch.startswith("thumb"))
1185 IsThumb = true;
Daniel Dunbar03184792009-09-22 21:44:58 +00001186
1187 if (IsThumb) {
1188 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1189 "i64:64:64-f32:32:32-f64:64:64-"
1190 "v64:64:64-v128:128:128-a0:0:32");
1191 } else {
1192 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1193 "i64:64:64-f32:32:32-f64:64:64-"
1194 "v64:64:64-v128:128:128-a0:0:64");
1195 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001196 }
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001197 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001198 virtual bool setABI(const std::string &Name) {
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001199 ABI = Name;
1200
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001201 // The defaults (above) are for AAPCS, check if we need to change them.
1202 //
1203 // FIXME: We need support for -meabi... we could just mangle it into the
1204 // name.
1205 if (Name == "apcs-gnu") {
1206 DoubleAlign = LongLongAlign = 32;
1207 SizeType = UnsignedLong;
1208
Daniel Dunbar03184792009-09-22 21:44:58 +00001209 if (IsThumb) {
1210 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1211 "i64:32:32-f32:32:32-f64:32:32-"
1212 "v64:64:64-v128:128:128-a0:0:32");
1213 } else {
1214 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1215 "i64:32:32-f32:32:32-f64:32:32-"
1216 "v64:64:64-v128:128:128-a0:0:64");
1217 }
1218
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001219 // FIXME: Override "preferred align" for double and long long.
1220 } else if (Name == "aapcs") {
1221 // FIXME: Enumerated types are variable width in straight AAPCS.
1222 } else if (Name == "aapcs-linux") {
1223 ;
1224 } else
1225 return false;
1226
1227 return true;
1228 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001229 virtual void getTargetDefines(const LangOptions &Opts,
1230 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001231 // Target identification.
1232 Define(Defs, "__arm");
1233 Define(Defs, "__arm__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001234
Chris Lattnerecd49032009-03-02 22:27:17 +00001235 // Target properties.
1236 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001237
Mike Stump9d54bd72009-04-08 02:07:04 +00001238 // Subtarget options.
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001239 //
1240 // FIXME: Neither THUMB_INTERWORK nor SOFTFP is not being set correctly
1241 // here.
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001242 if (ArmArch == Armv7a) {
1243 Define(Defs, "__ARM_ARCH_7A__");
1244 Define(Defs, "__THUMB_INTERWORK__");
1245 } else if (ArmArch == Armv6) {
Mike Stump9d54bd72009-04-08 02:07:04 +00001246 Define(Defs, "__ARM_ARCH_6K__");
1247 Define(Defs, "__THUMB_INTERWORK__");
1248 } else if (ArmArch == Armv5) {
1249 Define(Defs, "__ARM_ARCH_5TEJ__");
1250 Define(Defs, "__THUMB_INTERWORK__");
1251 Define(Defs, "__SOFTFP__");
1252 } else if (ArmArch == Armv4t) {
1253 Define(Defs, "__ARM_ARCH_4T__");
1254 Define(Defs, "__SOFTFP__");
1255 } else if (ArmArch == XScale) {
1256 Define(Defs, "__ARM_ARCH_5TE__");
1257 Define(Defs, "__XSCALE__");
1258 Define(Defs, "__SOFTFP__");
1259 }
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001260
Chris Lattnerecd49032009-03-02 22:27:17 +00001261 Define(Defs, "__ARMEL__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001262
1263 if (IsThumb) {
1264 Define(Defs, "__THUMBEL__");
1265 Define(Defs, "__thumb__");
1266 if (ArmArch == Armv7a)
1267 Define(Defs, "__thumb2__");
1268 }
1269
1270 // Note, this is always on in gcc, even though it doesn't make sense.
Eli Friedman20da71e2009-05-29 19:00:15 +00001271 Define(Defs, "__APCS_32__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001272 // FIXME: This should be conditional on VFP instruction support.
Eli Friedman20da71e2009-05-29 19:00:15 +00001273 Define(Defs, "__VFP_FP__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001274
1275 Define(Defs, "__USING_SJLJ_EXCEPTIONS__");
Chris Lattner17df24e2008-04-21 18:56:49 +00001276 }
1277 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1278 unsigned &NumRecords) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001279 // FIXME: Implement.
1280 Records = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +00001281 NumRecords = 0;
1282 }
1283 virtual const char *getVAListDeclaration() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001284 return "typedef char* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +00001285 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001286 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001287 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001288 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001289 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001290 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00001291 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001292 // FIXME: Check if this is complete
Anders Carlsson58436352009-02-28 17:11:49 +00001293 switch (*Name) {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001294 default:
Nate Begeman2908fa02008-04-22 05:03:19 +00001295 case 'l': // r0-r7
1296 case 'h': // r8-r15
1297 case 'w': // VFP Floating point register single precision
1298 case 'P': // VFP Floating point register double precision
Chris Lattnerd9725f72009-04-26 07:16:29 +00001299 Info.setAllowsRegister();
Nate Begeman2908fa02008-04-22 05:03:19 +00001300 return true;
1301 }
Chris Lattner17df24e2008-04-21 18:56:49 +00001302 return false;
1303 }
1304 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001305 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +00001306 return "";
1307 }
1308};
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001309
1310const char * const ARMTargetInfo::GCCRegNames[] = {
1311 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1312 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1313};
1314
1315void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
1316 unsigned &NumNames) const {
1317 Names = GCCRegNames;
1318 NumNames = llvm::array_lengthof(GCCRegNames);
1319}
1320
1321const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1322
1323 { { "a1" }, "r0" },
1324 { { "a2" }, "r1" },
1325 { { "a3" }, "r2" },
1326 { { "a4" }, "r3" },
1327 { { "v1" }, "r4" },
1328 { { "v2" }, "r5" },
1329 { { "v3" }, "r6" },
1330 { { "v4" }, "r7" },
1331 { { "v5" }, "r8" },
1332 { { "v6", "rfp" }, "r9" },
1333 { { "sl" }, "r10" },
1334 { { "fp" }, "r11" },
1335 { { "ip" }, "r12" },
1336 { { "sp" }, "r13" },
1337 { { "lr" }, "r14" },
1338 { { "pc" }, "r15" },
1339};
1340
1341void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1342 unsigned &NumAliases) const {
1343 Aliases = GCCRegAliases;
1344 NumAliases = llvm::array_lengthof(GCCRegAliases);
1345}
Chris Lattner17df24e2008-04-21 18:56:49 +00001346} // end anonymous namespace.
1347
Eli Friedmanf05b7722008-08-20 07:44:10 +00001348
1349namespace {
Mike Stump11289f42009-09-09 15:08:12 +00001350class DarwinARMTargetInfo :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001351 public DarwinTargetInfo<ARMTargetInfo> {
1352protected:
Daniel Dunbar40165182009-08-24 09:10:05 +00001353 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +00001354 std::vector<char> &Defines) const {
1355 getDarwinDefines(Defines, Opts);
1356 getDarwinIPhoneOSDefines(Defines, Triple);
Eli Friedmand88c8a12009-04-19 21:38:35 +00001357 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00001358
Torok Edwinb2b37c62009-06-30 17:10:35 +00001359public:
Mike Stump11289f42009-09-09 15:08:12 +00001360 DarwinARMTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +00001361 : DarwinTargetInfo<ARMTargetInfo>(triple) {}
Eli Friedmanf05b7722008-08-20 07:44:10 +00001362};
1363} // end anonymous namespace.
1364
Chris Lattner5ba61f02006-10-14 07:39:34 +00001365namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001366class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +00001367 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1368 static const char * const GCCRegNames[];
Gabor Greif49991682008-02-21 16:29:08 +00001369public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001370 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1371 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +00001372 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1373 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001374 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001375 virtual void getTargetDefines(const LangOptions &Opts,
1376 std::vector<char> &Defines) const {
Eli Friedman79426742009-05-22 01:12:57 +00001377 DefineStd(Defines, "sparc", Opts);
Gabor Greif49991682008-02-21 16:29:08 +00001378 Define(Defines, "__sparcv8");
Eli Friedman79426742009-05-22 01:12:57 +00001379 Define(Defines, "__REGISTER_PREFIX__", "");
Gabor Greif49991682008-02-21 16:29:08 +00001380 }
1381 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1382 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001383 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +00001384 }
1385 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001386 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +00001387 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001388 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001389 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001390 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001391 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001392 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif49991682008-02-21 16:29:08 +00001393 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001394 // FIXME: Implement!
1395 return false;
Gabor Greif49991682008-02-21 16:29:08 +00001396 }
1397 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001398 // FIXME: Implement!
1399 return "";
Gabor Greif49991682008-02-21 16:29:08 +00001400 }
1401};
1402
Chris Lattner9b415d62009-01-27 01:58:38 +00001403const char * const SparcV8TargetInfo::GCCRegNames[] = {
1404 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1405 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1406 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1407 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1408};
1409
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001410void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001411 unsigned &NumNames) const {
1412 Names = GCCRegNames;
1413 NumNames = llvm::array_lengthof(GCCRegNames);
1414}
1415
1416const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001417 { { "g0" }, "r0" },
1418 { { "g1" }, "r1" },
1419 { { "g2" }, "r2" },
1420 { { "g3" }, "r3" },
1421 { { "g4" }, "r4" },
1422 { { "g5" }, "r5" },
1423 { { "g6" }, "r6" },
1424 { { "g7" }, "r7" },
1425 { { "o0" }, "r8" },
1426 { { "o1" }, "r9" },
1427 { { "o2" }, "r10" },
1428 { { "o3" }, "r11" },
1429 { { "o4" }, "r12" },
1430 { { "o5" }, "r13" },
1431 { { "o6", "sp" }, "r14" },
1432 { { "o7" }, "r15" },
1433 { { "l0" }, "r16" },
1434 { { "l1" }, "r17" },
1435 { { "l2" }, "r18" },
1436 { { "l3" }, "r19" },
1437 { { "l4" }, "r20" },
1438 { { "l5" }, "r21" },
1439 { { "l6" }, "r22" },
1440 { { "l7" }, "r23" },
1441 { { "i0" }, "r24" },
1442 { { "i1" }, "r25" },
1443 { { "i2" }, "r26" },
1444 { { "i3" }, "r27" },
1445 { { "i4" }, "r28" },
1446 { { "i5" }, "r29" },
1447 { { "i6", "fp" }, "r30" },
1448 { { "i7" }, "r31" },
Chris Lattner9b415d62009-01-27 01:58:38 +00001449};
1450
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001451void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001452 unsigned &NumAliases) const {
1453 Aliases = GCCRegAliases;
1454 NumAliases = llvm::array_lengthof(GCCRegAliases);
1455}
Gabor Greif49991682008-02-21 16:29:08 +00001456} // end anonymous namespace.
1457
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001458namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +00001459class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001460public:
1461 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001462 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmand50881c2008-11-02 02:43:55 +00001463 SizeType = UnsignedInt;
1464 PtrDiffType = SignedInt;
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001465 }
1466};
1467} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +00001468
Chris Lattnerb781dc792008-05-08 05:58:21 +00001469namespace {
1470 class PIC16TargetInfo : public TargetInfo{
1471 public:
1472 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +00001473 TLSSupported = false;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001474 IntWidth = 16;
1475 LongWidth = LongLongWidth = 32;
Eli Friedman678d3ba2009-05-16 23:30:57 +00001476 IntMaxTWidth = 32;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001477 PointerWidth = 16;
1478 IntAlign = 8;
1479 LongAlign = LongLongAlign = 8;
Eli Friedmanb5366062008-05-20 14:21:01 +00001480 PointerAlign = 8;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001481 SizeType = UnsignedInt;
1482 IntMaxType = SignedLong;
1483 UIntMaxType = UnsignedLong;
Chris Lattner7e4c81c2009-02-13 22:28:55 +00001484 IntPtrType = SignedShort;
Eli Friedmand50881c2008-11-02 02:43:55 +00001485 PtrDiffType = SignedInt;
Sanjiv Gupta7c720072009-06-02 04:43:46 +00001486 FloatWidth = 32;
1487 FloatAlign = 32;
1488 DoubleWidth = 32;
1489 DoubleAlign = 32;
1490 LongDoubleWidth = 32;
1491 LongDoubleAlign = 32;
1492 FloatFormat = &llvm::APFloat::IEEEsingle;
1493 DoubleFormat = &llvm::APFloat::IEEEsingle;
1494 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1495 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32";
1496
Chris Lattnerb781dc792008-05-08 05:58:21 +00001497 }
Chris Lattner5e2ef0c2008-05-09 06:08:39 +00001498 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1499 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001500 virtual void getTargetDefines(const LangOptions &Opts,
1501 std::vector<char> &Defines) const {
Chris Lattnerb781dc792008-05-08 05:58:21 +00001502 Define(Defines, "__pic16");
Sanjiv Gupta30f95ec2009-07-07 04:42:23 +00001503 Define(Defines, "rom", "__attribute__((address_space(1)))");
1504 Define(Defines, "ram", "__attribute__((address_space(0)))");
Mike Stump11289f42009-09-09 15:08:12 +00001505 Define(Defines, "_section(SectName)",
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001506 "__attribute__((section(SectName)))");
1507 Define(Defines, "_address(Addr)",
1508 "__attribute__((section(\"Address=\"#Addr)))");
Sanjiv Gupta30f95ec2009-07-07 04:42:23 +00001509 Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001510 Define(Defines, "_interrupt",
1511 "__attribute__((section(\"interrupt=0x4\"))) \
1512 __attribute__((used))");
Chris Lattnerb781dc792008-05-08 05:58:21 +00001513 }
1514 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1515 unsigned &NumRecords) const {}
Mike Stump11289f42009-09-09 15:08:12 +00001516 virtual const char *getVAListDeclaration() const {
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001517 return "";
1518 }
1519 virtual const char *getClobbers() const {
1520 return "";
1521 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001522 virtual void getGCCRegNames(const char * const *&Names,
1523 unsigned &NumNames) const {}
1524 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001525 TargetInfo::ConstraintInfo &info) const {
1526 return true;
1527 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001528 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001529 unsigned &NumAliases) const {}
1530 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1531 };
1532}
1533
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001534namespace {
1535 class MSP430TargetInfo : public TargetInfo {
1536 static const char * const GCCRegNames[];
1537 public:
1538 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1539 TLSSupported = false;
1540 IntWidth = 16;
1541 LongWidth = LongLongWidth = 32;
Eli Friedman678d3ba2009-05-16 23:30:57 +00001542 IntMaxTWidth = 32;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001543 PointerWidth = 16;
1544 IntAlign = 8;
1545 LongAlign = LongLongAlign = 8;
1546 PointerAlign = 8;
1547 SizeType = UnsignedInt;
1548 IntMaxType = SignedLong;
1549 UIntMaxType = UnsignedLong;
1550 IntPtrType = SignedShort;
1551 PtrDiffType = SignedInt;
1552 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
1553 }
1554 virtual void getTargetDefines(const LangOptions &Opts,
1555 std::vector<char> &Defines) const {
1556 Define(Defines, "MSP430");
1557 Define(Defines, "__MSP430__");
1558 // FIXME: defines for different 'flavours' of MCU
1559 }
1560 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1561 unsigned &NumRecords) const {
1562 // FIXME: Implement.
1563 Records = 0;
1564 NumRecords = 0;
1565 }
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001566 virtual void getGCCRegNames(const char * const *&Names,
1567 unsigned &NumNames) const;
1568 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1569 unsigned &NumAliases) const {
1570 // No aliases.
1571 Aliases = 0;
1572 NumAliases = 0;
1573 }
1574 virtual bool validateAsmConstraint(const char *&Name,
1575 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov051913b2009-10-15 23:17:13 +00001576 // No target constraints for now.
1577 return false;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001578 }
1579 virtual const char *getClobbers() const {
1580 // FIXME: Is this really right?
1581 return "";
1582 }
1583 virtual const char *getVAListDeclaration() const {
1584 // FIXME: implement
Anton Korobeynikov2f910822009-05-08 18:24:57 +00001585 return "typedef char* __builtin_va_list;";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001586 }
1587 };
1588
1589 const char * const MSP430TargetInfo::GCCRegNames[] = {
1590 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1591 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1592 };
1593
1594 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1595 unsigned &NumNames) const {
1596 Names = GCCRegNames;
1597 NumNames = llvm::array_lengthof(GCCRegNames);
1598 }
1599}
1600
1601
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001602namespace {
1603 class SystemZTargetInfo : public TargetInfo {
1604 static const char * const GCCRegNames[];
1605 public:
1606 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
1607 TLSSupported = false;
1608 IntWidth = IntAlign = 32;
1609 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
1610 PointerWidth = PointerAlign = 64;
1611 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16";
1612 }
1613 virtual void getTargetDefines(const LangOptions &Opts,
1614 std::vector<char> &Defines) const {
1615 Define(Defines, "__s390__");
1616 Define(Defines, "__s390x__");
1617 }
1618 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1619 unsigned &NumRecords) const {
1620 // FIXME: Implement.
1621 Records = 0;
1622 NumRecords = 0;
1623 }
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001624
1625 virtual void getDefaultLangOptions(LangOptions &Opts) {
1626 TargetInfo::getDefaultLangOptions(Opts);
1627 Opts.CharIsSigned = false;
1628 }
1629
1630 virtual void getGCCRegNames(const char * const *&Names,
1631 unsigned &NumNames) const;
1632 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1633 unsigned &NumAliases) const {
1634 // No aliases.
1635 Aliases = 0;
1636 NumAliases = 0;
1637 }
1638 virtual bool validateAsmConstraint(const char *&Name,
1639 TargetInfo::ConstraintInfo &info) const {
1640 // FIXME: implement
1641 return true;
1642 }
1643 virtual const char *getClobbers() const {
1644 // FIXME: Is this really right?
1645 return "";
1646 }
1647 virtual const char *getVAListDeclaration() const {
1648 // FIXME: implement
1649 return "typedef char* __builtin_va_list;";
1650 }
1651 };
1652
1653 const char * const SystemZTargetInfo::GCCRegNames[] = {
1654 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1655 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1656 };
1657
1658 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
1659 unsigned &NumNames) const {
1660 Names = GCCRegNames;
1661 NumNames = llvm::array_lengthof(GCCRegNames);
1662 }
1663}
1664
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001665namespace {
1666 class BlackfinTargetInfo : public TargetInfo {
1667 static const char * const GCCRegNames[];
1668 public:
1669 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
1670 TLSSupported = false;
1671 DoubleAlign = 32;
1672 LongLongAlign = 32;
1673 LongDoubleAlign = 32;
1674 DescriptionString = "e-p:32:32-i64:32-f64:32";
1675 }
1676
1677 virtual void getTargetDefines(const LangOptions &Opts,
1678 std::vector<char> &Defines) const {
1679 DefineStd(Defines, "bfin", Opts);
1680 DefineStd(Defines, "BFIN", Opts);
1681 Define(Defines, "__ADSPBLACKFIN__");
1682 // FIXME: This one is really dependent on -mcpu
1683 Define(Defines, "__ADSPLPBLACKFIN__");
1684 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
1685 }
1686
1687 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1688 unsigned &NumRecords) const {
1689 // FIXME: Implement.
1690 Records = 0;
1691 NumRecords = 0;
1692 }
1693
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001694 virtual void getGCCRegNames(const char * const *&Names,
1695 unsigned &NumNames) const;
1696
1697 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1698 unsigned &NumAliases) const {
1699 // No aliases.
1700 Aliases = 0;
1701 NumAliases = 0;
1702 }
1703
1704 virtual bool validateAsmConstraint(const char *&Name,
1705 TargetInfo::ConstraintInfo &Info) const {
1706 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
1707 Info.setAllowsRegister();
1708 return true;
1709 }
1710 return false;
1711 }
1712
1713 virtual const char *getClobbers() const {
1714 return "";
1715 }
1716
1717 virtual const char *getVAListDeclaration() const {
1718 return "typedef char* __builtin_va_list;";
1719 }
1720 };
1721
1722 const char * const BlackfinTargetInfo::GCCRegNames[] = {
1723 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1724 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
1725 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
1726 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
1727 "a0", "a1", "cc",
1728 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
1729 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
1730 };
1731
1732 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
1733 unsigned &NumNames) const {
1734 Names = GCCRegNames;
1735 NumNames = llvm::array_lengthof(GCCRegNames);
1736 }
1737}
1738
Eli Friedmana9c3d712009-08-19 20:47:07 +00001739namespace {
1740
Mike Stump11289f42009-09-09 15:08:12 +00001741 // LLVM and Clang cannot be used directly to output native binaries for
1742 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmana9c3d712009-08-19 20:47:07 +00001743 // type and alignment information.
Mike Stump11289f42009-09-09 15:08:12 +00001744 //
1745 // TCE uses the llvm bitcode as input and uses it for generating customized
1746 // target processor and program binary. TCE co-design environment is
Eli Friedmana9c3d712009-08-19 20:47:07 +00001747 // publicly available in http://tce.cs.tut.fi
1748
1749 class TCETargetInfo : public TargetInfo{
1750 public:
1751 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
1752 TLSSupported = false;
1753 IntWidth = 32;
1754 LongWidth = LongLongWidth = 32;
1755 IntMaxTWidth = 32;
1756 PointerWidth = 32;
1757 IntAlign = 32;
1758 LongAlign = LongLongAlign = 32;
1759 PointerAlign = 32;
1760 SizeType = UnsignedInt;
1761 IntMaxType = SignedLong;
1762 UIntMaxType = UnsignedLong;
1763 IntPtrType = SignedInt;
1764 PtrDiffType = SignedInt;
1765 FloatWidth = 32;
1766 FloatAlign = 32;
1767 DoubleWidth = 32;
1768 DoubleAlign = 32;
1769 LongDoubleWidth = 32;
1770 LongDoubleAlign = 32;
1771 FloatFormat = &llvm::APFloat::IEEEsingle;
1772 DoubleFormat = &llvm::APFloat::IEEEsingle;
1773 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1774 DescriptionString = "E-p:32:32:32-a0:32:32"
1775 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64"
1776 "-f32:32:32-f64:32:64";
1777 }
1778
1779 virtual void getTargetDefines(const LangOptions &Opts,
1780 std::vector<char> &Defines) const {
1781 DefineStd(Defines, "tce", Opts);
1782 Define(Defines, "__TCE__");
1783 Define(Defines, "__TCE_V1__");
1784 }
1785 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1786 unsigned &NumRecords) const {}
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001787 virtual const char *getClobbers() const {
1788 return "";
1789 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001790 virtual const char *getVAListDeclaration() const {
1791 return "typedef void* __builtin_va_list;";
1792 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001793 virtual void getGCCRegNames(const char * const *&Names,
1794 unsigned &NumNames) const {}
1795 virtual bool validateAsmConstraint(const char *&Name,
1796 TargetInfo::ConstraintInfo &info) const {
1797 return true;
1798 }
1799 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1800 unsigned &NumAliases) const {}
1801 };
1802}
1803
Chris Lattner5ba61f02006-10-14 07:39:34 +00001804//===----------------------------------------------------------------------===//
1805// Driver code
1806//===----------------------------------------------------------------------===//
1807
Chris Lattner855d0242008-03-05 01:18:20 +00001808/// CreateTargetInfo - Return the target info object for the specified target
1809/// triple.
1810TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Daniel Dunbar52322032009-08-18 05:47:58 +00001811 llvm::Triple Triple(T);
1812 llvm::Triple::OSType os = Triple.getOS();
Eli Friedmanb5366062008-05-20 14:21:01 +00001813
Daniel Dunbar52322032009-08-18 05:47:58 +00001814 switch (Triple.getArch()) {
1815 default:
1816 return NULL;
Eli Friedmanb5366062008-05-20 14:21:01 +00001817
Daniel Dunbar52322032009-08-18 05:47:58 +00001818 case llvm::Triple::arm:
Daniel Dunbar33a004e2009-09-11 01:14:50 +00001819 case llvm::Triple::thumb:
Daniel Dunbar52322032009-08-18 05:47:58 +00001820 switch (os) {
1821 case llvm::Triple::Darwin:
Eli Friedman873f65a2008-08-21 00:13:15 +00001822 return new DarwinARMTargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001823 case llvm::Triple::FreeBSD:
Torok Edwinb2b37c62009-06-30 17:10:35 +00001824 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001825 default:
1826 return new ARMTargetInfo(T);
1827 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001828
Daniel Dunbar52322032009-08-18 05:47:58 +00001829 case llvm::Triple::bfin:
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001830 return new BlackfinTargetInfo(T);
1831
Daniel Dunbar52322032009-08-18 05:47:58 +00001832 case llvm::Triple::msp430:
1833 return new MSP430TargetInfo(T);
Eli Friedmanb5366062008-05-20 14:21:01 +00001834
Daniel Dunbar52322032009-08-18 05:47:58 +00001835 case llvm::Triple::pic16:
1836 return new PIC16TargetInfo(T);
1837
1838 case llvm::Triple::ppc:
1839 if (os == llvm::Triple::Darwin)
1840 return new DarwinTargetInfo<PPCTargetInfo>(T);
1841 return new PPC32TargetInfo(T);
1842
1843 case llvm::Triple::ppc64:
1844 if (os == llvm::Triple::Darwin)
1845 return new DarwinTargetInfo<PPC64TargetInfo>(T);
1846 return new PPC64TargetInfo(T);
1847
1848 case llvm::Triple::sparc:
1849 if (os == llvm::Triple::Solaris)
1850 return new SolarisSparcV8TargetInfo(T);
1851 return new SparcV8TargetInfo(T);
1852
1853 case llvm::Triple::systemz:
1854 return new SystemZTargetInfo(T);
1855
Eli Friedmana9c3d712009-08-19 20:47:07 +00001856 case llvm::Triple::tce:
1857 return new TCETargetInfo(T);
1858
Daniel Dunbar52322032009-08-18 05:47:58 +00001859 case llvm::Triple::x86:
1860 switch (os) {
1861 case llvm::Triple::Darwin:
1862 return new DarwinI386TargetInfo(T);
1863 case llvm::Triple::Linux:
1864 return new LinuxTargetInfo<X86_32TargetInfo>(T);
1865 case llvm::Triple::DragonFly:
1866 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
1867 case llvm::Triple::NetBSD:
1868 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
1869 case llvm::Triple::OpenBSD:
1870 return new OpenBSDI386TargetInfo(T);
1871 case llvm::Triple::FreeBSD:
1872 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
1873 case llvm::Triple::Solaris:
1874 return new SolarisTargetInfo<X86_32TargetInfo>(T);
1875 case llvm::Triple::Cygwin:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001876 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001877 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001878 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001879 case llvm::Triple::Win32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001880 return new VisualStudioWindowsX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001881 default:
1882 return new X86_32TargetInfo(T);
1883 }
1884
1885 case llvm::Triple::x86_64:
1886 switch (os) {
1887 case llvm::Triple::Darwin:
1888 return new DarwinX86_64TargetInfo(T);
1889 case llvm::Triple::Linux:
1890 return new LinuxTargetInfo<X86_64TargetInfo>(T);
1891 case llvm::Triple::NetBSD:
1892 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
1893 case llvm::Triple::OpenBSD:
1894 return new OpenBSDX86_64TargetInfo(T);
1895 case llvm::Triple::FreeBSD:
1896 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
1897 case llvm::Triple::Solaris:
1898 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001899 case llvm::Triple::MinGW64:
1900 return new MinGWX86_64TargetInfo(T);
1901 case llvm::Triple::Win32: // This is what Triple.h supports now.
1902 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001903 default:
1904 return new X86_64TargetInfo(T);
1905 }
1906 }
Chris Lattner5ba61f02006-10-14 07:39:34 +00001907}