blob: 5337615306964964890446e596de842b30512a9f [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner4b009652007-07-25 00:24:17 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikove7772382009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenek38591a22007-12-12 18:05:32 +000011// target triple.
Chris Lattner4b009652007-07-25 00:24:17 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner99ca9d62009-06-14 01:05:48 +000015#include "clang/Basic/Builtins.h"
16#include "clang/Basic/TargetBuiltins.h"
Chris Lattner4b009652007-07-25 00:24:17 +000017#include "clang/Basic/TargetInfo.h"
Chris Lattnerddae7102008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Eli Friedmand4011892008-05-20 14:27:34 +000019#include "llvm/ADT/APFloat.h"
Chris Lattnerc345a802009-03-20 16:06:38 +000020#include "llvm/ADT/SmallString.h"
Daniel Dunbar0433a022009-08-19 20:04:03 +000021#include "llvm/ADT/StringRef.h"
Chris Lattnerf54f2212009-08-12 06:24:27 +000022#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/Triple.h"
Chris Lattner43954312009-08-10 19:03:04 +000024#include "llvm/MC/MCSectionMachO.h"
Chris Lattner4b009652007-07-25 00:24:17 +000025using namespace clang;
26
Chris Lattner4b009652007-07-25 00:24:17 +000027//===----------------------------------------------------------------------===//
28// Common code shared among targets.
29//===----------------------------------------------------------------------===//
30
Daniel Dunbar0433a022009-08-19 20:04:03 +000031static void Define(std::vector<char> &Buf, const llvm::StringRef &Macro,
32 const llvm::StringRef &Val = "1") {
Chris Lattner0db667a2007-10-06 06:57:34 +000033 const char *Def = "#define ";
34 Buf.insert(Buf.end(), Def, Def+strlen(Def));
Daniel Dunbar0433a022009-08-19 20:04:03 +000035 Buf.insert(Buf.end(), Macro.begin(), Macro.end());
Chris Lattner0db667a2007-10-06 06:57:34 +000036 Buf.push_back(' ');
Daniel Dunbar0433a022009-08-19 20:04:03 +000037 Buf.insert(Buf.end(), Val.begin(), Val.end());
Chris Lattner0db667a2007-10-06 06:57:34 +000038 Buf.push_back('\n');
39}
40
Chris Lattnerc345a802009-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 Korobeynikove7772382009-05-03 13:42:53 +000044static void DefineStd(std::vector<char> &Buf, const char *MacroName,
Chris Lattnerc345a802009-03-20 16:06:38 +000045 const LangOptions &Opts) {
46 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikove7772382009-05-03 13:42:53 +000047
Chris Lattnerc345a802009-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 Korobeynikove7772382009-05-03 13:42:53 +000052
Chris Lattnerc345a802009-03-20 16:06:38 +000053 // Define __unix.
54 llvm::SmallString<20> TmpStr;
55 TmpStr = "__";
56 TmpStr += MacroName;
Daniel Dunbar0433a022009-08-19 20:04:03 +000057 Define(Buf, TmpStr.str());
Anton Korobeynikove7772382009-05-03 13:42:53 +000058
Chris Lattnerc345a802009-03-20 16:06:38 +000059 // Define __unix__.
60 TmpStr += "__";
Daniel Dunbar0433a022009-08-19 20:04:03 +000061 Define(Buf, TmpStr.str());
Chris Lattnerc345a802009-03-20 16:06:38 +000062}
63
Chris Lattnerbd00eb82008-10-05 21:50:58 +000064//===----------------------------------------------------------------------===//
65// Defines specific to certain operating systems.
66//===----------------------------------------------------------------------===//
Chris Lattner43954312009-08-10 19:03:04 +000067
Edwin Török36565e52009-06-30 17:10:35 +000068namespace {
Douglas Gregor937331f2009-07-01 15:12:53 +000069template<typename TgtInfo>
70class OSTargetInfo : public TgtInfo {
Edwin Török36565e52009-06-30 17:10:35 +000071protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +000072 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +000073 std::vector<char> &Defines) const=0;
74public:
Douglas Gregor937331f2009-07-01 15:12:53 +000075 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Edwin Török36565e52009-06-30 17:10:35 +000076 virtual void getTargetDefines(const LangOptions &Opts,
77 std::vector<char> &Defines) const {
Douglas Gregor937331f2009-07-01 15:12:53 +000078 TgtInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar608b3882009-08-24 09:10:05 +000079 getOSDefines(Opts, TgtInfo::getTriple(), Defines);
Edwin Török2d98f9f2009-06-30 17:00:25 +000080 }
Edwin Török36565e52009-06-30 17:10:35 +000081
82};
Chris Lattnerf54f2212009-08-12 06:24:27 +000083} // end anonymous namespace
Edwin Török2d98f9f2009-06-30 17:00:25 +000084
Chris Lattner43954312009-08-10 19:03:04 +000085
Daniel Dunbar93f64532009-04-10 19:52:24 +000086static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
Chris Lattner59122202009-06-23 00:43:21 +000087 Define(Defs, "__APPLE_CC__", "5621");
Eli Friedman872996c2008-08-20 02:34:37 +000088 Define(Defs, "__APPLE__");
89 Define(Defs, "__MACH__");
Chris Lattner8405e092009-02-05 07:19:24 +000090 Define(Defs, "OBJC_NEW_PROPERTIES");
Anton Korobeynikove7772382009-05-03 13:42:53 +000091
Chris Lattner8181e622009-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 Korobeynikove7772382009-05-03 13:42:53 +000094
Chris Lattner8181e622009-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 Lattner33854aa2009-04-07 04:48:21 +000097 Define(Defs, "__strong", "");
Chris Lattner8181e622009-04-07 16:50:40 +000098 else
Chris Lattner33854aa2009-04-07 04:48:21 +000099 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
Eli Friedmaneff0a422009-06-04 23:00:29 +0000100
101 if (Opts.Static)
102 Define(Defs, "__STATIC__");
103 else
104 Define(Defs, "__DYNAMIC__");
Daniel Dunbar62a7cbc2009-09-03 04:54:28 +0000105
106 if (Opts.POSIXThreads)
107 Define(Defs, "_REENTRANT", "1");
Daniel Dunbar93f64532009-04-10 19:52:24 +0000108}
109
Daniel Dunbar608b3882009-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 Lattnerf54f2212009-08-12 06:24:27 +0000113 return;
Mike Stump25cf7602009-09-09 15:08:12 +0000114
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000115 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Daniel Dunbar93f64532009-04-10 19:52:24 +0000116 unsigned Maj, Min, Rev;
Daniel Dunbar608b3882009-08-24 09:10:05 +0000117 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump25cf7602009-09-09 15:08:12 +0000118
Chris Lattnerf54f2212009-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 Dunbar93f64532009-04-10 19:52:24 +0000123 }
Chris Lattnerf54f2212009-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 Dunbar93f64532009-04-10 19:52:24 +0000129}
130
Anton Korobeynikove7772382009-05-03 13:42:53 +0000131static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
Daniel Dunbar608b3882009-08-24 09:10:05 +0000132 const llvm::Triple &Triple) {
133 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattnerf54f2212009-08-12 06:24:27 +0000134 return;
Mike Stump25cf7602009-09-09 15:08:12 +0000135
Daniel Dunbar93f64532009-04-10 19:52:24 +0000136 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
137 unsigned Maj, Min, Rev;
Daniel Dunbar608b3882009-08-24 09:10:05 +0000138 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump25cf7602009-09-09 15:08:12 +0000139
Chris Lattnerf54f2212009-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 Lattnerc5dc8eb2008-09-30 01:00:25 +0000146 }
Chris Lattnerf54f2212009-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 Friedman872996c2008-08-20 02:34:37 +0000152}
Chris Lattner4b009652007-07-25 00:24:17 +0000153
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000154/// GetDarwinLanguageOptions - Set the default language options for darwin.
155static void GetDarwinLanguageOptions(LangOptions &Opts,
Daniel Dunbar608b3882009-08-24 09:10:05 +0000156 const llvm::Triple &Triple) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000157 Opts.NeXTRuntime = true;
Mike Stump25cf7602009-09-09 15:08:12 +0000158
Daniel Dunbar608b3882009-08-24 09:10:05 +0000159 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000160 return;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000161
Daniel Dunbar608b3882009-08-24 09:10:05 +0000162 unsigned MajorVersion = Triple.getDarwinMajorNumber();
Chris Lattnerf54f2212009-08-12 06:24:27 +0000163
Bill Wendlinge1d4f5d2009-06-28 07:36:13 +0000164 // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
Chris Lattnerf54f2212009-08-12 06:24:27 +0000165 if (MajorVersion > 9) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000166 Opts.Blocks = 1;
Bill Wendling39e99a42009-06-28 23:01:01 +0000167 Opts.setStackProtectorMode(LangOptions::SSPOn);
Bill Wendlinge1d4f5d2009-06-28 07:36:13 +0000168 }
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000169
Bill Wendlinge1d4f5d2009-06-28 07:36:13 +0000170 // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
171 // beyond.
Chris Lattnerf54f2212009-08-12 06:24:27 +0000172 if (MajorVersion >= 9 && Opts.ObjC1 &&
Daniel Dunbar608b3882009-08-24 09:10:05 +0000173 Triple.getArch() == llvm::Triple::x86_64)
Fariborz Jahanian72efecb2009-02-24 23:38:42 +0000174 Opts.ObjCNonFragileABI = 1;
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000175}
176
Chris Lattner43954312009-08-10 19:03:04 +0000177namespace {
Edwin Török36565e52009-06-30 17:10:35 +0000178template<typename Target>
179class DarwinTargetInfo : public OSTargetInfo<Target> {
180protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000181 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000182 std::vector<char> &Defines) const {
183 getDarwinDefines(Defines, Opts);
184 getDarwinOSXDefines(Defines, Triple);
185 }
Mike Stump25cf7602009-09-09 15:08:12 +0000186
Edwin Török36565e52009-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 Dunbar608b3882009-08-24 09:10:05 +0000192 GetDarwinLanguageOptions(Opts, TargetInfo::getTriple());
Edwin Török36565e52009-06-30 17:10:35 +0000193 }
194public:
195 DarwinTargetInfo(const std::string& triple) :
196 OSTargetInfo<Target>(triple) {
197 this->TLSSupported = false;
198 }
199
Edwin Török36565e52009-06-30 17:10:35 +0000200 virtual const char *getUnicodeStringSection() const {
201 return "__TEXT,__ustring";
202 }
Mike Stump25cf7602009-09-09 15:08:12 +0000203
Chris Lattner43954312009-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 }
Edwin Török36565e52009-06-30 17:10:35 +0000211};
212
Chris Lattner43954312009-08-10 19:03:04 +0000213
Edwin Török36565e52009-06-30 17:10:35 +0000214// DragonFlyBSD Target
215template<typename Target>
216class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
217protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000218 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-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 Stump25cf7602009-09-09 15:08:12 +0000229 DragonFlyBSDTargetInfo(const std::string &triple)
Edwin Török36565e52009-06-30 17:10:35 +0000230 : OSTargetInfo<Target>(triple) {}
231};
232
233// FreeBSD Target
234template<typename Target>
235class FreeBSDTargetInfo : public OSTargetInfo<Target> {
236protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000237 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000238 std::vector<char> &Defs) const {
239 // FreeBSD defines; list based off of gcc output
240
Daniel Dunbar608b3882009-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");
Edwin Török36565e52009-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 Stump25cf7602009-09-09 15:08:12 +0000257 FreeBSDTargetInfo(const std::string &triple)
Duncan Sandscd2cb662009-07-08 13:55:08 +0000258 : OSTargetInfo<Target>(triple) {
259 this->UserLabelPrefix = "";
260 }
Edwin Török36565e52009-06-30 17:10:35 +0000261};
262
263// Linux target
264template<typename Target>
265class LinuxTargetInfo : public OSTargetInfo<Target> {
266protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000267 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-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 Dunbar62a7cbc2009-09-03 04:54:28 +0000274 if (Opts.POSIXThreads)
275 Define(Defs, "_REENTRANT", "1");
Edwin Török36565e52009-06-30 17:10:35 +0000276 }
277public:
Mike Stump25cf7602009-09-09 15:08:12 +0000278 LinuxTargetInfo(const std::string& triple)
Edwin Török36565e52009-06-30 17:10:35 +0000279 : OSTargetInfo<Target>(triple) {
280 this->UserLabelPrefix = "";
281 }
282};
283
Chris Lattner25fff082009-07-13 20:29:08 +0000284// NetBSD Target
285template<typename Target>
286class NetBSDTargetInfo : public OSTargetInfo<Target> {
287protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000288 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Chris Lattner25fff082009-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 Dunbar62a7cbc2009-09-03 04:54:28 +0000294 if (Opts.POSIXThreads)
295 Define(Defs, "_POSIX_THREADS", "1");
Chris Lattner25fff082009-07-13 20:29:08 +0000296 }
297public:
Mike Stump25cf7602009-09-09 15:08:12 +0000298 NetBSDTargetInfo(const std::string &triple)
Chris Lattner25fff082009-07-13 20:29:08 +0000299 : OSTargetInfo<Target>(triple) {
300 this->UserLabelPrefix = "";
301 }
302};
303
Edwin Török36565e52009-06-30 17:10:35 +0000304// OpenBSD Target
305template<typename Target>
306class OpenBSDTargetInfo : public OSTargetInfo<Target> {
307protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000308 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-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 Dunbar62a7cbc2009-09-03 04:54:28 +0000315 if (Opts.POSIXThreads)
316 Define(Defs, "_POSIX_THREADS", "1");
Edwin Török36565e52009-06-30 17:10:35 +0000317 }
318public:
Mike Stump25cf7602009-09-09 15:08:12 +0000319 OpenBSDTargetInfo(const std::string &triple)
Edwin Török36565e52009-06-30 17:10:35 +0000320 : OSTargetInfo<Target>(triple) {}
321};
322
323// Solaris target
324template<typename Target>
325class SolarisTargetInfo : public OSTargetInfo<Target> {
326protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000327 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-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 Stump25cf7602009-09-09 15:08:12 +0000336 SolarisTargetInfo(const std::string& triple)
Edwin Török36565e52009-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 Stump25cf7602009-09-09 15:08:12 +0000343} // end anonymous namespace.
Edwin Török36565e52009-06-30 17:10:35 +0000344
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000345//===----------------------------------------------------------------------===//
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000346// Specific target implementations.
347//===----------------------------------------------------------------------===//
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000348
Eli Friedmanfd5a4122008-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 Friedmand9389be2009-06-05 07:05:05 +0000357 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
358
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000359 virtual void getTargetBuiltins(const Builtin::Info *&Records,
360 unsigned &NumRecords) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000361 Records = BuiltinInfo;
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000362 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000363 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000364
Chris Lattner79682402009-03-20 15:52:06 +0000365 virtual void getTargetDefines(const LangOptions &Opts,
366 std::vector<char> &Defines) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000367
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000368 virtual const char *getVAListDeclaration() const {
Chris Lattnera07708f2008-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 Friedmanfd5a4122008-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 Lattnera07708f2008-10-27 01:11:29 +0000377 "} __builtin_va_list[1];";*/
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000378 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000379 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000380 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000381 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000382 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000383 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000384 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000385 switch (*Name) {
Anders Carlsson4ce42302007-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 Lattnerc49cc1a2009-04-26 07:16:29 +0000391 Info.setAllowsRegister();
Anders Carlsson4ce42302007-11-27 04:11:28 +0000392 return true;
393 }
394 }
Eli Friedmand9389be2009-06-05 07:05:05 +0000395 virtual void getDefaultLangOptions(LangOptions &Opts) {
396 TargetInfo::getDefaultLangOptions(Opts);
397 Opts.CharIsSigned = false;
398 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000399 virtual const char *getClobbers() const {
400 return "";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000401 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000402};
Anders Carlsson4ce42302007-11-27 04:11:28 +0000403
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000404const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-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 Lattner99ca9d62009-06-14 01:05:48 +0000407#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000408};
Anton Korobeynikove7772382009-05-03 13:42:53 +0000409
410
Chris Lattnerbef1d722009-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 Lattner79682402009-03-20 15:52:06 +0000413void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
414 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-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 Korobeynikove7772382009-05-03 13:42:53 +0000427
Chris Lattnerbef1d722009-03-02 22:27:17 +0000428 // Target properties.
429 Define(Defs, "_BIG_ENDIAN");
430 Define(Defs, "__BIG_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000431
Chris Lattnerbef1d722009-03-02 22:27:17 +0000432 // Subtarget options.
433 Define(Defs, "__NATURAL_ALIGNMENT__");
434 Define(Defs, "__REGISTER_PREFIX__", "");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000435
Chris Lattnerbef1d722009-03-02 22:27:17 +0000436 // FIXME: Should be controlled by command line option.
437 Define(Defs, "__LONG_DOUBLE_128__");
438}
439
Chris Lattner9fd73612008-04-21 18:56:49 +0000440
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000441const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattner14d2bb72009-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 Friedmanfd5a4122008-08-20 23:11:40 +0000450 "mq", "lr", "ctr", "ap",
Chris Lattner14d2bb72009-09-16 05:05:27 +0000451 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000452 "xer",
Chris Lattner14d2bb72009-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 Friedmanfd5a4122008-08-20 23:11:40 +0000457 "vrsave", "vscr",
458 "spe_acc", "spefscr",
459 "sfp"
460};
Chris Lattner4b009652007-07-25 00:24:17 +0000461
Anton Korobeynikove7772382009-05-03 13:42:53 +0000462void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000463 unsigned &NumNames) const {
464 Names = GCCRegNames;
465 NumNames = llvm::array_lengthof(GCCRegNames);
466}
Chris Lattner4b009652007-07-25 00:24:17 +0000467
Eli Friedmanfd5a4122008-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 Dunbar40b774e2009-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 Stump369c21c2009-09-17 21:15:00 +0000513 { { "fr10" }, "f10" },
Daniel Dunbar40b774e2009-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 Friedmanfd5a4122008-08-20 23:11:40 +0000536};
537
Anton Korobeynikove7772382009-05-03 13:42:53 +0000538void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000539 unsigned &NumAliases) const {
540 Aliases = GCCRegAliases;
541 NumAliases = llvm::array_lengthof(GCCRegAliases);
542}
543} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +0000544
545namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000546class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000547public:
Eli Friedman2b161652008-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 Lattner4b009652007-07-25 00:24:17 +0000552};
553} // end anonymous namespace.
554
555namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000556class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000557public:
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000558 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000559 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman38e31802009-07-01 03:36:11 +0000560 IntMaxType = SignedLong;
561 UIntMaxType = UnsignedLong;
562 Int64Type = SignedLong;
Eli Friedman2b161652008-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 Lattnere5fde952008-05-09 06:17:04 +0000565 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000566};
567} // end anonymous namespace.
568
Chris Lattner4b009652007-07-25 00:24:17 +0000569namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000570// Namespace for x86 abstract base class
571const Builtin::Info BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-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 Lattner99ca9d62009-06-14 01:05:48 +0000574#include "clang/Basic/BuiltinsX86.def"
Eli Friedman872996c2008-08-20 02:34:37 +0000575};
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000576
Eli Friedman872996c2008-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 Lattner715fe4c2009-03-02 22:40:39 +0000601 enum X86SSEEnum {
602 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
603 } SSELevel;
Eli Friedman872996c2008-08-20 02:34:37 +0000604public:
Anton Korobeynikove7772382009-05-03 13:42:53 +0000605 X86TargetInfo(const std::string& triple)
Daniel Dunbar07181d72009-05-06 03:16:41 +0000606 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman872996c2008-08-20 02:34:37 +0000607 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner4b009652007-07-25 00:24:17 +0000608 }
609 virtual void getTargetBuiltins(const Builtin::Info *&Records,
610 unsigned &NumRecords) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000611 Records = BuiltinInfo;
612 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000613 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000614 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman872996c2008-08-20 02:34:37 +0000615 unsigned &NumNames) const {
616 Names = GCCRegNames;
617 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000618 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000619 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000620 unsigned &NumAliases) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000621 Aliases = GCCRegAliases;
622 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000623 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000624 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000625 TargetInfo::ConstraintInfo &info) const;
626 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlsson4ce42302007-11-27 04:11:28 +0000627 virtual const char *getClobbers() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000628 return "~{dirflag},~{fpsr},~{flags}";
629 }
Chris Lattner79682402009-03-20 15:52:06 +0000630 virtual void getTargetDefines(const LangOptions &Opts,
631 std::vector<char> &Defines) const;
Daniel Dunbar0838f962009-05-06 21:07:50 +0000632 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
633 const std::string &Name,
634 bool Enabled) const;
Mike Stump25cf7602009-09-09 15:08:12 +0000635 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar0838f962009-05-06 21:07:50 +0000636 llvm::StringMap<bool> &Features) const;
Daniel Dunbar07181d72009-05-06 03:16:41 +0000637 virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
Chris Lattner4b009652007-07-25 00:24:17 +0000638};
Chris Lattner7d6220c2009-03-02 22:20:04 +0000639
Mike Stump25cf7602009-09-09 15:08:12 +0000640void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar0838f962009-05-06 21:07:50 +0000641 llvm::StringMap<bool> &Features) const {
Daniel Dunbar07181d72009-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 Korobeynikove7772382009-05-03 13:42:53 +0000652
Daniel Dunbar07181d72009-05-06 03:16:41 +0000653 // LLVM does not currently recognize this.
654 // Features["sse4a"] = false;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000655
Daniel Dunbar07181d72009-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 Dunbarc2e55de2009-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 Stump25cf7602009-09-09 15:08:12 +0000684 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarc2e55de2009-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 Stump25cf7602009-09-09 15:08:12 +0000693 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarc2e55de2009-05-06 21:56:32 +0000694 setFeatureEnabled(Features, "3dnowa", true);
695 } else if (CPU == "c3-2")
696 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar07181d72009-05-06 03:16:41 +0000697}
698
Daniel Dunbar0838f962009-05-06 21:07:50 +0000699bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump25cf7602009-09-09 15:08:12 +0000700 const std::string &Name,
Daniel Dunbar0838f962009-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 Stump25cf7602009-09-09 15:08:12 +0000714 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000715 Features["sse3"] = true;
716 else if (Name == "ssse3")
Mike Stump25cf7602009-09-09 15:08:12 +0000717 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000718 Features["ssse3"] = true;
719 else if (Name == "sse4")
Mike Stump25cf7602009-09-09 15:08:12 +0000720 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-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 Stump25cf7602009-09-09 15:08:12 +0000728 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000729 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
730 else if (Name == "sse")
Mike Stump25cf7602009-09-09 15:08:12 +0000731 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000732 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
733 else if (Name == "sse2")
Mike Stump25cf7602009-09-09 15:08:12 +0000734 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000735 Features["sse41"] = Features["sse42"] = false;
736 else if (Name == "sse3")
Mike Stump25cf7602009-09-09 15:08:12 +0000737 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbar0838f962009-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 Dunbar07181d72009-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 Lattner7d6220c2009-03-02 22:20:04 +0000769}
Chris Lattnerbef1d722009-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 Lattner79682402009-03-20 15:52:06 +0000773void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
774 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-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 Lattnerbef1d722009-03-02 22:27:17 +0000783 } else {
Chris Lattnerc345a802009-03-20 16:06:38 +0000784 DefineStd(Defs, "i386", Opts);
Chris Lattnerbef1d722009-03-02 22:27:17 +0000785 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000786
Chris Lattnerbef1d722009-03-02 22:27:17 +0000787 // Target properties.
788 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000789
Chris Lattnerbef1d722009-03-02 22:27:17 +0000790 // Subtarget options.
791 Define(Defs, "__nocona");
792 Define(Defs, "__nocona__");
793 Define(Defs, "__tune_nocona__");
Chris Lattnerbef1d722009-03-02 22:27:17 +0000794 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner715fe4c2009-03-02 22:40:39 +0000795
Chris Lattner25ac1c12009-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 Korobeynikove7772382009-05-03 13:42:53 +0000800
Chris Lattner715fe4c2009-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 Lattnerbef1d722009-03-02 22:27:17 +0000822}
Anton Korobeynikove7772382009-05-03 13:42:53 +0000823
824
Eli Friedman872996c2008-08-20 02:34:37 +0000825bool
Anders Carlsson36834a72009-02-28 17:11:49 +0000826X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000827 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000828 switch (*Name) {
Eli Friedman872996c2008-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 Carlsson2285e622008-10-06 00:41:45 +0000840 case 'y': // Any MMX register.
Anders Carlssond2459f92008-10-06 19:17:39 +0000841 case 'x': // Any SSE register.
Eli Friedman872996c2008-08-20 02:34:37 +0000842 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikove7772382009-05-03 13:42:53 +0000843 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssonff235da2009-01-24 18:03:09 +0000844 // x86_64 instructions.
Anton Korobeynikove7772382009-05-03 13:42:53 +0000845 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssonff235da2009-01-24 18:03:09 +0000846 // x86_64 instructions.
Eli Friedman872996c2008-08-20 02:34:37 +0000847 case 'N': // unsigned 8-bit integer constant for use with in and out
848 // instructions.
Eli Friedman7e17aed2009-06-08 20:45:44 +0000849 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000850 Info.setAllowsRegister();
Eli Friedman872996c2008-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 Friedman872996c2008-08-20 02:34:37 +0000872} // end anonymous namespace
Chris Lattner4b009652007-07-25 00:24:17 +0000873
874namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000875// X86-32 generic target
876class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000877public:
Eli Friedman872996c2008-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 Friedman2b161652008-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 Friedman04ede302009-03-29 20:31:09 +0000885 SizeType = UnsignedInt;
886 PtrDiffType = SignedInt;
887 IntPtrType = SignedInt;
Anton Korobeynikov8fcffeb2009-04-03 23:38:25 +0000888 RegParmMax = 3;
Eli Friedman872996c2008-08-20 02:34:37 +0000889 }
890 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000891 return "typedef char* __builtin_va_list;";
Eli Friedman872996c2008-08-20 02:34:37 +0000892 }
Chris Lattneraa339182009-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 Friedman872996c2008-08-20 02:34:37 +0000899};
900} // end anonymous namespace
901
902namespace {
Eli Friedman1c79f4b2009-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 Friedman96ada022009-07-05 22:31:18 +0000909 PtrDiffType = SignedLong;
Eli Friedman1c79f4b2009-07-05 18:47:56 +0000910 }
911};
912} // end anonymous namespace
913
914namespace {
Edwin Török36565e52009-06-30 17:10:35 +0000915class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman872996c2008-08-20 02:34:37 +0000916public:
Edwin Török36565e52009-06-30 17:10:35 +0000917 DarwinI386TargetInfo(const std::string& triple) :
918 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman872996c2008-08-20 02:34:37 +0000919 LongDoubleWidth = 128;
920 LongDoubleAlign = 128;
Eli Friedman04ede302009-03-29 20:31:09 +0000921 SizeType = UnsignedLong;
922 IntPtrType = SignedLong;
Eli Friedman2b161652008-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";
Edwin Török2d98f9f2009-06-30 17:00:25 +0000926 }
927
Eli Friedman872996c2008-08-20 02:34:37 +0000928};
Daniel Dunbar64c77a12009-06-29 20:52:51 +0000929} // end anonymous namespace
930
931namespace {
Eli Friedman23cb7912008-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 Friedman8f575172009-04-19 21:38:35 +0000937 TLSSupported = false;
Chris Lattnera8a69e12009-06-24 17:12:15 +0000938 WCharType = UnsignedShort;
Eli Friedman6b6ca942009-06-08 06:11:14 +0000939 WCharWidth = WCharAlign = 16;
Eli Friedmanb28055e2009-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 Friedman23cb7912008-08-21 01:40:19 +0000944 }
Chris Lattner79682402009-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 Friedman23cb7912008-08-21 01:40:19 +0000948 // This list is based off of the the list of things MingW defines
Eli Friedman23cb7912008-08-21 01:40:19 +0000949 Define(Defines, "_WIN32");
Chris Lattnerc345a802009-03-20 16:06:38 +0000950 DefineStd(Defines, "WIN32", Opts);
951 DefineStd(Defines, "WINNT", Opts);
Eli Friedman23cb7912008-08-21 01:40:19 +0000952 Define(Defines, "_X86_");
Eli Friedman23cb7912008-08-21 01:40:19 +0000953 }
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +0000954};
955} // end anonymous namespace
Eli Friedman6b6ca942009-06-08 06:11:14 +0000956
Daniel Dunbar8d8e9d62009-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 Friedman6b6ca942009-06-08 06:11:14 +0000978 virtual void getDefaultLangOptions(LangOptions &Opts) {
Daniel Dunbar8d8e9d62009-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__");
Cédric Venet2c16e4e2009-09-27 10:09:11 +0000997 Define(Defines, "__declspec", "__declspec");
Daniel Dunbar8d8e9d62009-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 Friedman6b6ca942009-06-08 06:11:14 +00001022 }
Eli Friedman23cb7912008-08-21 01:40:19 +00001023};
1024} // end anonymous namespace
1025
1026namespace {
Eli Friedman872996c2008-08-20 02:34:37 +00001027// x86-64 generic target
1028class X86_64TargetInfo : public X86TargetInfo {
1029public:
Chris Lattner79682402009-03-20 15:52:06 +00001030 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +00001031 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001032 LongDoubleWidth = 128;
1033 LongDoubleAlign = 128;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +00001034 IntMaxType = SignedLong;
1035 UIntMaxType = UnsignedLong;
Eli Friedman38e31802009-07-01 03:36:11 +00001036 Int64Type = SignedLong;
Anton Korobeynikov8fcffeb2009-04-03 23:38:25 +00001037 RegParmMax = 6;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +00001038
Eli Friedman2b161652008-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 Dunbarea390922009-06-08 22:39:13 +00001041 "a0:0:64-s0:64:64-f80:128:128";
Chris Lattner4b009652007-07-25 00:24:17 +00001042 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +00001043 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-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 Friedman3c79eee2009-07-03 00:45:06 +00001049 "} __va_list_tag;"
1050 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson7dd1c952007-11-24 23:38:12 +00001051 }
Chris Lattneraa339182009-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 Friedman872996c2008-08-20 02:34:37 +00001058};
1059} // end anonymous namespace
1060
1061namespace {
Daniel Dunbar8d8e9d62009-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 Stump4da7a162009-10-08 23:00:00 +00001070 LongWidth = LongAlign = 32;
Daniel Dunbar8d8e9d62009-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 Friedman38e31802009-07-01 03:36:11 +00001118class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1119public:
Mike Stump25cf7602009-09-09 15:08:12 +00001120 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman38e31802009-07-01 03:36:11 +00001121 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1122 Int64Type = SignedLongLong;
1123 }
1124};
1125} // end anonymous namespace
1126
1127namespace {
Eli Friedman96ada022009-07-05 22:31:18 +00001128class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1129public:
Mike Stump25cf7602009-09-09 15:08:12 +00001130 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman96ada022009-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 Friedmanbe727fe2008-08-20 07:44:10 +00001140class ARMTargetInfo : public TargetInfo {
Mike Stumpf90a29f2009-04-08 02:07:04 +00001141 enum {
1142 Armv4t,
1143 Armv5,
1144 Armv6,
Mike Stump4e21ba42009-08-04 19:48:52 +00001145 Armv7a,
Mike Stumpf90a29f2009-04-08 02:07:04 +00001146 XScale
1147 } ArmArch;
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001148
Daniel Dunbar40b774e2009-09-17 07:03:19 +00001149 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1150 static const char * const GCCRegNames[];
1151
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001152 std::string ABI;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001153 bool IsThumb;
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001154
Chris Lattner9fd73612008-04-21 18:56:49 +00001155public:
Daniel Dunbarf0156562009-09-17 16:21:10 +00001156 ARMTargetInfo(const std::string &TripleStr)
1157 : TargetInfo(TripleStr), ABI("aapcs-linux"), IsThumb(false)
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001158 {
Daniel Dunbarf0156562009-09-17 16:21:10 +00001159 llvm::Triple Triple(TripleStr);
1160
Daniel Dunbarb9531632009-09-14 00:02:24 +00001161 SizeType = UnsignedInt;
1162 PtrDiffType = SignedInt;
Daniel Dunbarf0156562009-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 Stump4e21ba42009-08-04 19:48:52 +00001172 ArmArch = Armv7a;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001173 else if (Version.empty() || Version == "v6" || Version == "v6t2")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001174 ArmArch = Armv6;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001175 else if (Version == "v5")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001176 ArmArch = Armv5;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001177 else if (Version == "v4t")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001178 ArmArch = Armv4t;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001179 else if (Arch == "xscale" || Arch == "thumbv5e")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001180 ArmArch = XScale;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001181 else
Chris Lattner433d9722009-04-23 04:22:04 +00001182 ArmArch = Armv6;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001183
1184 if (Arch.startswith("thumb"))
1185 IsThumb = true;
Daniel Dunbar54f62dc2009-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 Friedman0b7b1cb2008-05-20 14:21:01 +00001196 }
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001197 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbarb9531632009-09-14 00:02:24 +00001198 virtual bool setABI(const std::string &Name) {
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001199 ABI = Name;
1200
Daniel Dunbarb9531632009-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 Dunbar54f62dc2009-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 Dunbarb9531632009-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 Lattner79682402009-03-20 15:52:06 +00001229 virtual void getTargetDefines(const LangOptions &Opts,
1230 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +00001231 // Target identification.
1232 Define(Defs, "__arm");
1233 Define(Defs, "__arm__");
Anton Korobeynikove7772382009-05-03 13:42:53 +00001234
Chris Lattnerbef1d722009-03-02 22:27:17 +00001235 // Target properties.
1236 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +00001237
Mike Stumpf90a29f2009-04-08 02:07:04 +00001238 // Subtarget options.
Daniel Dunbarf0156562009-09-17 16:21:10 +00001239 //
1240 // FIXME: Neither THUMB_INTERWORK nor SOFTFP is not being set correctly
1241 // here.
Mike Stump4e21ba42009-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 Stumpf90a29f2009-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 Dunbarf0156562009-09-17 16:21:10 +00001260
Chris Lattnerbef1d722009-03-02 22:27:17 +00001261 Define(Defs, "__ARMEL__");
Daniel Dunbarf0156562009-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 Friedman468ca6d2009-05-29 19:00:15 +00001271 Define(Defs, "__APCS_32__");
Daniel Dunbarf0156562009-09-17 16:21:10 +00001272 // FIXME: This should be conditional on VFP instruction support.
Eli Friedman468ca6d2009-05-29 19:00:15 +00001273 Define(Defs, "__VFP_FP__");
Daniel Dunbarf0156562009-09-17 16:21:10 +00001274
1275 Define(Defs, "__USING_SJLJ_EXCEPTIONS__");
Chris Lattner9fd73612008-04-21 18:56:49 +00001276 }
1277 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1278 unsigned &NumRecords) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001279 // FIXME: Implement.
1280 Records = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +00001281 NumRecords = 0;
1282 }
1283 virtual const char *getVAListDeclaration() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001284 return "typedef char* __builtin_va_list;";
Chris Lattner9fd73612008-04-21 18:56:49 +00001285 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001286 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar40b774e2009-09-17 07:03:19 +00001287 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +00001288 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar40b774e2009-09-17 07:03:19 +00001289 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +00001290 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +00001291 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001292 // FIXME: Check if this is complete
Anders Carlsson36834a72009-02-28 17:11:49 +00001293 switch (*Name) {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001294 default:
Nate Begeman222823a2008-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 Lattnerc49cc1a2009-04-26 07:16:29 +00001299 Info.setAllowsRegister();
Nate Begeman222823a2008-04-22 05:03:19 +00001300 return true;
1301 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001302 return false;
1303 }
1304 virtual const char *getClobbers() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001305 // FIXME: Is this really right?
Chris Lattner9fd73612008-04-21 18:56:49 +00001306 return "";
1307 }
1308};
Daniel Dunbar40b774e2009-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 Lattner9fd73612008-04-21 18:56:49 +00001346} // end anonymous namespace.
1347
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001348
1349namespace {
Mike Stump25cf7602009-09-09 15:08:12 +00001350class DarwinARMTargetInfo :
Edwin Török36565e52009-06-30 17:10:35 +00001351 public DarwinTargetInfo<ARMTargetInfo> {
1352protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +00001353 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +00001354 std::vector<char> &Defines) const {
1355 getDarwinDefines(Defines, Opts);
1356 getDarwinIPhoneOSDefines(Defines, Triple);
Eli Friedman8f575172009-04-19 21:38:35 +00001357 }
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001358
Edwin Török36565e52009-06-30 17:10:35 +00001359public:
Mike Stump25cf7602009-09-09 15:08:12 +00001360 DarwinARMTargetInfo(const std::string& triple)
Edwin Török36565e52009-06-30 17:10:35 +00001361 : DarwinTargetInfo<ARMTargetInfo>(triple) {}
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001362};
1363} // end anonymous namespace.
1364
Chris Lattner4b009652007-07-25 00:24:17 +00001365namespace {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001366class SparcV8TargetInfo : public TargetInfo {
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001367 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1368 static const char * const GCCRegNames[];
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001369public:
Eli Friedmanff158dd2008-08-20 07:28:14 +00001370 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1371 // FIXME: Support Sparc quad-precision long double?
Eli Friedman2b161652008-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 Friedmanff158dd2008-08-20 07:28:14 +00001374 }
Chris Lattner79682402009-03-20 15:52:06 +00001375 virtual void getTargetDefines(const LangOptions &Opts,
1376 std::vector<char> &Defines) const {
Eli Friedmana456b7f2009-05-22 01:12:57 +00001377 DefineStd(Defines, "sparc", Opts);
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001378 Define(Defines, "__sparcv8");
Eli Friedmana456b7f2009-05-22 01:12:57 +00001379 Define(Defines, "__REGISTER_PREFIX__", "");
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001380 }
1381 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1382 unsigned &NumRecords) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001383 // FIXME: Implement!
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001384 }
1385 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001386 return "typedef void* __builtin_va_list;";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001387 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001388 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001389 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +00001390 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001391 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +00001392 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001393 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001394 // FIXME: Implement!
1395 return false;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001396 }
1397 virtual const char *getClobbers() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001398 // FIXME: Implement!
1399 return "";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001400 }
1401};
1402
Chris Lattnerff7c53d2009-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 Korobeynikove7772382009-05-03 13:42:53 +00001410void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-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 Korobeynikove7772382009-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 Lattnerff7c53d2009-01-27 01:58:38 +00001449};
1450
Anton Korobeynikove7772382009-05-03 13:42:53 +00001451void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001452 unsigned &NumAliases) const {
1453 Aliases = GCCRegAliases;
1454 NumAliases = llvm::array_lengthof(GCCRegAliases);
1455}
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001456} // end anonymous namespace.
1457
Eli Friedmanff158dd2008-08-20 07:28:14 +00001458namespace {
Edwin Török36565e52009-06-30 17:10:35 +00001459class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001460public:
1461 SolarisSparcV8TargetInfo(const std::string& triple) :
Edwin Török36565e52009-06-30 17:10:35 +00001462 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedman7cca0982008-11-02 02:43:55 +00001463 SizeType = UnsignedInt;
1464 PtrDiffType = SignedInt;
Eli Friedmanff158dd2008-08-20 07:28:14 +00001465 }
1466};
1467} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +00001468
Chris Lattner85970f32008-05-08 05:58:21 +00001469namespace {
1470 class PIC16TargetInfo : public TargetInfo{
1471 public:
1472 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedman8f575172009-04-19 21:38:35 +00001473 TLSSupported = false;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001474 IntWidth = 16;
1475 LongWidth = LongLongWidth = 32;
Eli Friedman78a2f412009-05-16 23:30:57 +00001476 IntMaxTWidth = 32;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001477 PointerWidth = 16;
1478 IntAlign = 8;
1479 LongAlign = LongLongAlign = 8;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001480 PointerAlign = 8;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001481 SizeType = UnsignedInt;
1482 IntMaxType = SignedLong;
1483 UIntMaxType = UnsignedLong;
Chris Lattnerd9ef7242009-02-13 22:28:55 +00001484 IntPtrType = SignedShort;
Eli Friedman7cca0982008-11-02 02:43:55 +00001485 PtrDiffType = SignedInt;
Sanjiv Guptaae8f1e82009-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 Lattner85970f32008-05-08 05:58:21 +00001497 }
Chris Lattner727b3c42008-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 Lattner79682402009-03-20 15:52:06 +00001500 virtual void getTargetDefines(const LangOptions &Opts,
1501 std::vector<char> &Defines) const {
Chris Lattner85970f32008-05-08 05:58:21 +00001502 Define(Defines, "__pic16");
Sanjiv Guptad75fd0b2009-07-07 04:42:23 +00001503 Define(Defines, "rom", "__attribute__((address_space(1)))");
1504 Define(Defines, "ram", "__attribute__((address_space(0)))");
Mike Stump25cf7602009-09-09 15:08:12 +00001505 Define(Defines, "_section(SectName)",
Sanjiv Gupta9e2b9e02009-08-20 17:48:52 +00001506 "__attribute__((section(SectName)))");
1507 Define(Defines, "_address(Addr)",
1508 "__attribute__((section(\"Address=\"#Addr)))");
Sanjiv Guptad75fd0b2009-07-07 04:42:23 +00001509 Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
Sanjiv Gupta9e2b9e02009-08-20 17:48:52 +00001510 Define(Defines, "_interrupt",
1511 "__attribute__((section(\"interrupt=0x4\"))) \
1512 __attribute__((used))");
Chris Lattner85970f32008-05-08 05:58:21 +00001513 }
1514 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1515 unsigned &NumRecords) const {}
Mike Stump25cf7602009-09-09 15:08:12 +00001516 virtual const char *getVAListDeclaration() const {
Daniel Dunbar2e967de2009-08-24 09:54:37 +00001517 return "";
1518 }
1519 virtual const char *getClobbers() const {
1520 return "";
1521 }
Anton Korobeynikove7772382009-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 Lattner85970f32008-05-08 05:58:21 +00001525 TargetInfo::ConstraintInfo &info) const {
1526 return true;
1527 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001528 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner85970f32008-05-08 05:58:21 +00001529 unsigned &NumAliases) const {}
1530 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1531 };
1532}
1533
Anton Korobeynikov954bd3f2009-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 Friedman78a2f412009-05-16 23:30:57 +00001542 IntMaxTWidth = 32;
Anton Korobeynikov954bd3f2009-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 Korobeynikov954bd3f2009-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 Korobeynikov174219b2009-10-15 23:17:13 +00001576 // No target constraints for now.
1577 return false;
Anton Korobeynikov954bd3f2009-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 Korobeynikovf5955592009-05-08 18:24:57 +00001585 return "typedef char* __builtin_va_list;";
Anton Korobeynikov954bd3f2009-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 Korobeynikov57f236f2009-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 Korobeynikov57f236f2009-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 Olesen61774372009-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 Olesen61774372009-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 Friedmanf0ff32f2009-08-19 20:47:07 +00001739namespace {
1740
Mike Stump25cf7602009-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 Friedmanf0ff32f2009-08-19 20:47:07 +00001743 // type and alignment information.
Mike Stump25cf7602009-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 Friedmanf0ff32f2009-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 Dunbar2e967de2009-08-24 09:54:37 +00001787 virtual const char *getClobbers() const {
1788 return "";
1789 }
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001790 virtual const char *getVAListDeclaration() const {
1791 return "typedef void* __builtin_va_list;";
1792 }
Eli Friedmanf0ff32f2009-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 Lattner4b009652007-07-25 00:24:17 +00001804//===----------------------------------------------------------------------===//
1805// Driver code
1806//===----------------------------------------------------------------------===//
1807
Chris Lattnerfc457002008-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 Dunbar8ba3de02009-08-18 05:47:58 +00001811 llvm::Triple Triple(T);
1812 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001813
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001814 switch (Triple.getArch()) {
1815 default:
1816 return NULL;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001817
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001818 case llvm::Triple::arm:
Daniel Dunbar3f361b52009-09-11 01:14:50 +00001819 case llvm::Triple::thumb:
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001820 switch (os) {
1821 case llvm::Triple::Darwin:
Eli Friedman2b161652008-08-21 00:13:15 +00001822 return new DarwinARMTargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001823 case llvm::Triple::FreeBSD:
Edwin Török36565e52009-06-30 17:10:35 +00001824 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001825 default:
1826 return new ARMTargetInfo(T);
1827 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001828
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001829 case llvm::Triple::bfin:
Jakob Stoklund Olesen61774372009-08-17 20:08:44 +00001830 return new BlackfinTargetInfo(T);
1831
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001832 case llvm::Triple::msp430:
1833 return new MSP430TargetInfo(T);
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001834
Daniel Dunbar8ba3de02009-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 Friedmanf0ff32f2009-08-19 20:47:07 +00001856 case llvm::Triple::tce:
1857 return new TCETargetInfo(T);
1858
Daniel Dunbar8ba3de02009-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 Dunbar8d8e9d62009-09-23 07:31:35 +00001876 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001877 case llvm::Triple::MinGW32:
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001878 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001879 case llvm::Triple::Win32:
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001880 return new VisualStudioWindowsX86_32TargetInfo(T);
Daniel Dunbar8ba3de02009-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 Dunbar8d8e9d62009-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 Dunbar8ba3de02009-08-18 05:47:58 +00001903 default:
1904 return new X86_64TargetInfo(T);
1905 }
1906 }
Chris Lattner4b009652007-07-25 00:24:17 +00001907}