blob: d1888df8c3cf9eb7d1720b21a828d116479ac81c [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"
Daniel Dunbar8dd8f262009-11-11 09:38:56 +000020#include "llvm/ADT/STLExtras.h"
Chris Lattnerc345a802009-03-20 16:06:38 +000021#include "llvm/ADT/SmallString.h"
Daniel Dunbar0433a022009-08-19 20:04:03 +000022#include "llvm/ADT/StringRef.h"
Daniel Dunbar8dd8f262009-11-11 09:38:56 +000023#include "llvm/ADT/StringSwitch.h"
Chris Lattnerf54f2212009-08-12 06:24:27 +000024#include "llvm/ADT/Triple.h"
Chris Lattner43954312009-08-10 19:03:04 +000025#include "llvm/MC/MCSectionMachO.h"
Chris Lattner4b009652007-07-25 00:24:17 +000026using namespace clang;
27
Chris Lattner4b009652007-07-25 00:24:17 +000028//===----------------------------------------------------------------------===//
29// Common code shared among targets.
30//===----------------------------------------------------------------------===//
31
Daniel Dunbar0433a022009-08-19 20:04:03 +000032static void Define(std::vector<char> &Buf, const llvm::StringRef &Macro,
33 const llvm::StringRef &Val = "1") {
Chris Lattner0db667a2007-10-06 06:57:34 +000034 const char *Def = "#define ";
35 Buf.insert(Buf.end(), Def, Def+strlen(Def));
Daniel Dunbar0433a022009-08-19 20:04:03 +000036 Buf.insert(Buf.end(), Macro.begin(), Macro.end());
Chris Lattner0db667a2007-10-06 06:57:34 +000037 Buf.push_back(' ');
Daniel Dunbar0433a022009-08-19 20:04:03 +000038 Buf.insert(Buf.end(), Val.begin(), Val.end());
Chris Lattner0db667a2007-10-06 06:57:34 +000039 Buf.push_back('\n');
40}
41
Chris Lattnerc345a802009-03-20 16:06:38 +000042/// DefineStd - Define a macro name and standard variants. For example if
43/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
44/// when in GNU mode.
Anton Korobeynikove7772382009-05-03 13:42:53 +000045static void DefineStd(std::vector<char> &Buf, const char *MacroName,
Chris Lattnerc345a802009-03-20 16:06:38 +000046 const LangOptions &Opts) {
47 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikove7772382009-05-03 13:42:53 +000048
Chris Lattnerc345a802009-03-20 16:06:38 +000049 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
50 // in the user's namespace.
51 if (Opts.GNUMode)
52 Define(Buf, MacroName);
Anton Korobeynikove7772382009-05-03 13:42:53 +000053
Chris Lattnerc345a802009-03-20 16:06:38 +000054 // Define __unix.
55 llvm::SmallString<20> TmpStr;
56 TmpStr = "__";
57 TmpStr += MacroName;
Daniel Dunbar0433a022009-08-19 20:04:03 +000058 Define(Buf, TmpStr.str());
Anton Korobeynikove7772382009-05-03 13:42:53 +000059
Chris Lattnerc345a802009-03-20 16:06:38 +000060 // Define __unix__.
61 TmpStr += "__";
Daniel Dunbar0433a022009-08-19 20:04:03 +000062 Define(Buf, TmpStr.str());
Chris Lattnerc345a802009-03-20 16:06:38 +000063}
64
Chris Lattnerbd00eb82008-10-05 21:50:58 +000065//===----------------------------------------------------------------------===//
66// Defines specific to certain operating systems.
67//===----------------------------------------------------------------------===//
Chris Lattner43954312009-08-10 19:03:04 +000068
Edwin Török36565e52009-06-30 17:10:35 +000069namespace {
Douglas Gregor937331f2009-07-01 15:12:53 +000070template<typename TgtInfo>
71class OSTargetInfo : public TgtInfo {
Edwin Török36565e52009-06-30 17:10:35 +000072protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +000073 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +000074 std::vector<char> &Defines) const=0;
75public:
Douglas Gregor937331f2009-07-01 15:12:53 +000076 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Edwin Török36565e52009-06-30 17:10:35 +000077 virtual void getTargetDefines(const LangOptions &Opts,
78 std::vector<char> &Defines) const {
Douglas Gregor937331f2009-07-01 15:12:53 +000079 TgtInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar608b3882009-08-24 09:10:05 +000080 getOSDefines(Opts, TgtInfo::getTriple(), Defines);
Edwin Török2d98f9f2009-06-30 17:00:25 +000081 }
Edwin Török36565e52009-06-30 17:10:35 +000082
83};
Chris Lattnerf54f2212009-08-12 06:24:27 +000084} // end anonymous namespace
Edwin Török2d98f9f2009-06-30 17:00:25 +000085
Chris Lattner43954312009-08-10 19:03:04 +000086
Daniel Dunbar93f64532009-04-10 19:52:24 +000087static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
Chris Lattner59122202009-06-23 00:43:21 +000088 Define(Defs, "__APPLE_CC__", "5621");
Eli Friedman872996c2008-08-20 02:34:37 +000089 Define(Defs, "__APPLE__");
90 Define(Defs, "__MACH__");
Chris Lattner8405e092009-02-05 07:19:24 +000091 Define(Defs, "OBJC_NEW_PROPERTIES");
Anton Korobeynikove7772382009-05-03 13:42:53 +000092
Chris Lattner8181e622009-04-07 16:50:40 +000093 // __weak is always defined, for use in blocks and with objc pointers.
94 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikove7772382009-05-03 13:42:53 +000095
Chris Lattner8181e622009-04-07 16:50:40 +000096 // Darwin defines __strong even in C mode (just to nothing).
97 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Chris Lattner33854aa2009-04-07 04:48:21 +000098 Define(Defs, "__strong", "");
Chris Lattner8181e622009-04-07 16:50:40 +000099 else
Chris Lattner33854aa2009-04-07 04:48:21 +0000100 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
Eli Friedmaneff0a422009-06-04 23:00:29 +0000101
102 if (Opts.Static)
103 Define(Defs, "__STATIC__");
104 else
105 Define(Defs, "__DYNAMIC__");
Daniel Dunbar62a7cbc2009-09-03 04:54:28 +0000106
107 if (Opts.POSIXThreads)
108 Define(Defs, "_REENTRANT", "1");
Daniel Dunbar93f64532009-04-10 19:52:24 +0000109}
110
Daniel Dunbar608b3882009-08-24 09:10:05 +0000111static void getDarwinOSXDefines(std::vector<char> &Defs,
112 const llvm::Triple &Triple) {
113 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattnerf54f2212009-08-12 06:24:27 +0000114 return;
Mike Stump25cf7602009-09-09 15:08:12 +0000115
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000116 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Daniel Dunbar93f64532009-04-10 19:52:24 +0000117 unsigned Maj, Min, Rev;
Daniel Dunbar608b3882009-08-24 09:10:05 +0000118 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump25cf7602009-09-09 15:08:12 +0000119
Chris Lattnerf54f2212009-08-12 06:24:27 +0000120 char MacOSXStr[] = "1000";
121 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
122 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
123 MacOSXStr[2] = '0' + Maj-4;
Daniel Dunbar93f64532009-04-10 19:52:24 +0000124 }
Chris Lattnerf54f2212009-08-12 06:24:27 +0000125
126 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
127 // Cap 10.4.11 -> darwin8.11 -> "1049"
128 MacOSXStr[3] = std::min(Min, 9U)+'0';
129 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
Daniel Dunbar93f64532009-04-10 19:52:24 +0000130}
131
Anton Korobeynikove7772382009-05-03 13:42:53 +0000132static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
Daniel Dunbar608b3882009-08-24 09:10:05 +0000133 const llvm::Triple &Triple) {
134 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattnerf54f2212009-08-12 06:24:27 +0000135 return;
Mike Stump25cf7602009-09-09 15:08:12 +0000136
Daniel Dunbar93f64532009-04-10 19:52:24 +0000137 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
138 unsigned Maj, Min, Rev;
Daniel Dunbar608b3882009-08-24 09:10:05 +0000139 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump25cf7602009-09-09 15:08:12 +0000140
Chris Lattnerf54f2212009-08-12 06:24:27 +0000141 // When targetting iPhone OS, interpret the minor version and
142 // revision as the iPhone OS version
143 char iPhoneOSStr[] = "10000";
144 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
145 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
146 iPhoneOSStr[0] = '0' + Min;
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000147 }
Chris Lattnerf54f2212009-08-12 06:24:27 +0000148
149 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
150 iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
151 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
152 iPhoneOSStr);
Eli Friedman872996c2008-08-20 02:34:37 +0000153}
Chris Lattner4b009652007-07-25 00:24:17 +0000154
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000155/// GetDarwinLanguageOptions - Set the default language options for darwin.
156static void GetDarwinLanguageOptions(LangOptions &Opts,
Daniel Dunbar608b3882009-08-24 09:10:05 +0000157 const llvm::Triple &Triple) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000158 Opts.NeXTRuntime = true;
Mike Stump25cf7602009-09-09 15:08:12 +0000159
Daniel Dunbar608b3882009-08-24 09:10:05 +0000160 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000161 return;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000162
Daniel Dunbar608b3882009-08-24 09:10:05 +0000163 unsigned MajorVersion = Triple.getDarwinMajorNumber();
Chris Lattnerf54f2212009-08-12 06:24:27 +0000164
Bill Wendlinge1d4f5d2009-06-28 07:36:13 +0000165 // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
Chris Lattnerf54f2212009-08-12 06:24:27 +0000166 if (MajorVersion > 9) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000167 Opts.Blocks = 1;
Bill Wendling39e99a42009-06-28 23:01:01 +0000168 Opts.setStackProtectorMode(LangOptions::SSPOn);
Bill Wendlinge1d4f5d2009-06-28 07:36:13 +0000169 }
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000170
Bill Wendlinge1d4f5d2009-06-28 07:36:13 +0000171 // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
172 // beyond.
Chris Lattnerf54f2212009-08-12 06:24:27 +0000173 if (MajorVersion >= 9 && Opts.ObjC1 &&
Daniel Dunbar608b3882009-08-24 09:10:05 +0000174 Triple.getArch() == llvm::Triple::x86_64)
Fariborz Jahanian72efecb2009-02-24 23:38:42 +0000175 Opts.ObjCNonFragileABI = 1;
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000176}
177
Chris Lattner43954312009-08-10 19:03:04 +0000178namespace {
Edwin Török36565e52009-06-30 17:10:35 +0000179template<typename Target>
180class DarwinTargetInfo : public OSTargetInfo<Target> {
181protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000182 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000183 std::vector<char> &Defines) const {
184 getDarwinDefines(Defines, Opts);
185 getDarwinOSXDefines(Defines, Triple);
186 }
Mike Stump25cf7602009-09-09 15:08:12 +0000187
Edwin Török36565e52009-06-30 17:10:35 +0000188 /// getDefaultLangOptions - Allow the target to specify default settings for
189 /// various language options. These may be overridden by command line
190 /// options.
191 virtual void getDefaultLangOptions(LangOptions &Opts) {
192 TargetInfo::getDefaultLangOptions(Opts);
Daniel Dunbar608b3882009-08-24 09:10:05 +0000193 GetDarwinLanguageOptions(Opts, TargetInfo::getTriple());
Edwin Török36565e52009-06-30 17:10:35 +0000194 }
195public:
196 DarwinTargetInfo(const std::string& triple) :
197 OSTargetInfo<Target>(triple) {
198 this->TLSSupported = false;
199 }
200
Edwin Török36565e52009-06-30 17:10:35 +0000201 virtual const char *getUnicodeStringSection() const {
202 return "__TEXT,__ustring";
203 }
Mike Stump25cf7602009-09-09 15:08:12 +0000204
Chris Lattner43954312009-08-10 19:03:04 +0000205 virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
206 // Let MCSectionMachO validate this.
207 llvm::StringRef Segment, Section;
208 unsigned TAA, StubSize;
209 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
210 TAA, StubSize);
211 }
Edwin Török36565e52009-06-30 17:10:35 +0000212};
213
Chris Lattner43954312009-08-10 19:03:04 +0000214
Edwin Török36565e52009-06-30 17:10:35 +0000215// DragonFlyBSD Target
216template<typename Target>
217class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
218protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000219 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000220 std::vector<char> &Defs) const {
221 // DragonFly defines; list based off of gcc output
222 Define(Defs, "__DragonFly__");
223 Define(Defs, "__DragonFly_cc_version", "100001");
224 Define(Defs, "__ELF__");
225 Define(Defs, "__KPRINTF_ATTRIBUTE__");
226 Define(Defs, "__tune_i386__");
227 DefineStd(Defs, "unix", Opts);
228 }
229public:
Mike Stump25cf7602009-09-09 15:08:12 +0000230 DragonFlyBSDTargetInfo(const std::string &triple)
Edwin Török36565e52009-06-30 17:10:35 +0000231 : OSTargetInfo<Target>(triple) {}
232};
233
234// FreeBSD Target
235template<typename Target>
236class FreeBSDTargetInfo : public OSTargetInfo<Target> {
237protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000238 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000239 std::vector<char> &Defs) const {
240 // FreeBSD defines; list based off of gcc output
241
Daniel Dunbar608b3882009-08-24 09:10:05 +0000242 // FIXME: Move version number handling to llvm::Triple.
243 const char *FreeBSD = strstr(Triple.getTriple().c_str(),
244 "-freebsd");
Edwin Török36565e52009-06-30 17:10:35 +0000245 FreeBSD += strlen("-freebsd");
246 char release[] = "X";
247 release[0] = FreeBSD[0];
248 char version[] = "X00001";
249 version[0] = FreeBSD[0];
250
251 Define(Defs, "__FreeBSD__", release);
252 Define(Defs, "__FreeBSD_cc_version", version);
253 Define(Defs, "__KPRINTF_ATTRIBUTE__");
254 DefineStd(Defs, "unix", Opts);
255 Define(Defs, "__ELF__", "1");
256 }
257public:
Mike Stump25cf7602009-09-09 15:08:12 +0000258 FreeBSDTargetInfo(const std::string &triple)
Duncan Sandscd2cb662009-07-08 13:55:08 +0000259 : OSTargetInfo<Target>(triple) {
260 this->UserLabelPrefix = "";
261 }
Edwin Török36565e52009-06-30 17:10:35 +0000262};
263
264// Linux target
265template<typename Target>
266class LinuxTargetInfo : public OSTargetInfo<Target> {
267protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000268 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000269 std::vector<char> &Defs) const {
270 // Linux defines; list based off of gcc output
271 DefineStd(Defs, "unix", Opts);
272 DefineStd(Defs, "linux", Opts);
273 Define(Defs, "__gnu_linux__");
274 Define(Defs, "__ELF__", "1");
Daniel Dunbar62a7cbc2009-09-03 04:54:28 +0000275 if (Opts.POSIXThreads)
276 Define(Defs, "_REENTRANT", "1");
Edwin Török36565e52009-06-30 17:10:35 +0000277 }
278public:
Mike Stump25cf7602009-09-09 15:08:12 +0000279 LinuxTargetInfo(const std::string& triple)
Edwin Török36565e52009-06-30 17:10:35 +0000280 : OSTargetInfo<Target>(triple) {
281 this->UserLabelPrefix = "";
282 }
283};
284
Chris Lattner25fff082009-07-13 20:29:08 +0000285// NetBSD Target
286template<typename Target>
287class NetBSDTargetInfo : public OSTargetInfo<Target> {
288protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000289 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Chris Lattner25fff082009-07-13 20:29:08 +0000290 std::vector<char> &Defs) const {
291 // NetBSD defines; list based off of gcc output
292 Define(Defs, "__NetBSD__", "1");
293 Define(Defs, "__unix__", "1");
294 Define(Defs, "__ELF__", "1");
Daniel Dunbar62a7cbc2009-09-03 04:54:28 +0000295 if (Opts.POSIXThreads)
296 Define(Defs, "_POSIX_THREADS", "1");
Chris Lattner25fff082009-07-13 20:29:08 +0000297 }
298public:
Mike Stump25cf7602009-09-09 15:08:12 +0000299 NetBSDTargetInfo(const std::string &triple)
Chris Lattner25fff082009-07-13 20:29:08 +0000300 : OSTargetInfo<Target>(triple) {
301 this->UserLabelPrefix = "";
302 }
303};
304
Edwin Török36565e52009-06-30 17:10:35 +0000305// OpenBSD Target
306template<typename Target>
307class OpenBSDTargetInfo : public OSTargetInfo<Target> {
308protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000309 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000310 std::vector<char> &Defs) const {
311 // OpenBSD defines; list based off of gcc output
312
313 Define(Defs, "__OpenBSD__", "1");
314 DefineStd(Defs, "unix", Opts);
315 Define(Defs, "__ELF__", "1");
Daniel Dunbar62a7cbc2009-09-03 04:54:28 +0000316 if (Opts.POSIXThreads)
317 Define(Defs, "_POSIX_THREADS", "1");
Edwin Török36565e52009-06-30 17:10:35 +0000318 }
319public:
Mike Stump25cf7602009-09-09 15:08:12 +0000320 OpenBSDTargetInfo(const std::string &triple)
Edwin Török36565e52009-06-30 17:10:35 +0000321 : OSTargetInfo<Target>(triple) {}
322};
323
Edward O'Callaghan0a7ef9a2009-10-18 13:33:59 +0000324// AuroraUX target
325template<typename Target>
326class AuroraUXTargetInfo : public OSTargetInfo<Target> {
327protected:
328 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
329 std::vector<char> &Defs) const {
330 DefineStd(Defs, "sun", Opts);
331 DefineStd(Defs, "unix", Opts);
332 Define(Defs, "__ELF__");
333 Define(Defs, "__svr4__");
334 Define(Defs, "__SVR4");
335 }
336public:
337 AuroraUXTargetInfo(const std::string& triple)
338 : OSTargetInfo<Target>(triple) {
339 this->UserLabelPrefix = "";
340 this->WCharType = this->SignedLong;
341 // FIXME: WIntType should be SignedLong
342 }
343};
344
Edwin Török36565e52009-06-30 17:10:35 +0000345// Solaris target
346template<typename Target>
347class SolarisTargetInfo : public OSTargetInfo<Target> {
348protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +0000349 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +0000350 std::vector<char> &Defs) const {
351 DefineStd(Defs, "sun", Opts);
352 DefineStd(Defs, "unix", Opts);
353 Define(Defs, "__ELF__");
354 Define(Defs, "__svr4__");
355 Define(Defs, "__SVR4");
356 }
357public:
Mike Stump25cf7602009-09-09 15:08:12 +0000358 SolarisTargetInfo(const std::string& triple)
Edwin Török36565e52009-06-30 17:10:35 +0000359 : OSTargetInfo<Target>(triple) {
360 this->UserLabelPrefix = "";
361 this->WCharType = this->SignedLong;
362 // FIXME: WIntType should be SignedLong
363 }
364};
Mike Stump25cf7602009-09-09 15:08:12 +0000365} // end anonymous namespace.
Edwin Török36565e52009-06-30 17:10:35 +0000366
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000367//===----------------------------------------------------------------------===//
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000368// Specific target implementations.
369//===----------------------------------------------------------------------===//
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000370
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000371namespace {
372// PPC abstract base class
373class PPCTargetInfo : public TargetInfo {
374 static const Builtin::Info BuiltinInfo[];
375 static const char * const GCCRegNames[];
376 static const TargetInfo::GCCRegAlias GCCRegAliases[];
377
378public:
Eli Friedmand9389be2009-06-05 07:05:05 +0000379 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
380
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000381 virtual void getTargetBuiltins(const Builtin::Info *&Records,
382 unsigned &NumRecords) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000383 Records = BuiltinInfo;
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000384 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000385 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000386
Chris Lattner79682402009-03-20 15:52:06 +0000387 virtual void getTargetDefines(const LangOptions &Opts,
388 std::vector<char> &Defines) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000389
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000390 virtual const char *getVAListDeclaration() const {
Chris Lattnera07708f2008-10-27 01:11:29 +0000391 return "typedef char* __builtin_va_list;";
392 // This is the right definition for ABI/V4: System V.4/eabi.
393 /*return "typedef struct __va_list_tag {"
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000394 " unsigned char gpr;"
395 " unsigned char fpr;"
396 " unsigned short reserved;"
397 " void* overflow_arg_area;"
398 " void* reg_save_area;"
Chris Lattnera07708f2008-10-27 01:11:29 +0000399 "} __builtin_va_list[1];";*/
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000400 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000401 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000402 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000403 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000404 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000405 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000406 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000407 switch (*Name) {
Anders Carlsson4ce42302007-11-27 04:11:28 +0000408 default: return false;
409 case 'O': // Zero
410 return true;
411 case 'b': // Base register
412 case 'f': // Floating point register
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000413 Info.setAllowsRegister();
Anders Carlsson4ce42302007-11-27 04:11:28 +0000414 return true;
415 }
416 }
Eli Friedmand9389be2009-06-05 07:05:05 +0000417 virtual void getDefaultLangOptions(LangOptions &Opts) {
418 TargetInfo::getDefaultLangOptions(Opts);
419 Opts.CharIsSigned = false;
420 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000421 virtual const char *getClobbers() const {
422 return "";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000423 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000424};
Anders Carlsson4ce42302007-11-27 04:11:28 +0000425
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000426const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000427#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
428#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner99ca9d62009-06-14 01:05:48 +0000429#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000430};
Anton Korobeynikove7772382009-05-03 13:42:53 +0000431
432
Chris Lattnerbef1d722009-03-02 22:27:17 +0000433/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
434/// #defines that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000435void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
436 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000437 // Target identification.
438 Define(Defs, "__ppc__");
439 Define(Defs, "_ARCH_PPC");
440 Define(Defs, "__POWERPC__");
441 if (PointerWidth == 64) {
442 Define(Defs, "_ARCH_PPC64");
443 Define(Defs, "_LP64");
444 Define(Defs, "__LP64__");
445 Define(Defs, "__ppc64__");
446 } else {
447 Define(Defs, "__ppc__");
448 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000449
Chris Lattnerbef1d722009-03-02 22:27:17 +0000450 // Target properties.
451 Define(Defs, "_BIG_ENDIAN");
452 Define(Defs, "__BIG_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000453
Chris Lattnerbef1d722009-03-02 22:27:17 +0000454 // Subtarget options.
455 Define(Defs, "__NATURAL_ALIGNMENT__");
456 Define(Defs, "__REGISTER_PREFIX__", "");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000457
Chris Lattnerbef1d722009-03-02 22:27:17 +0000458 // FIXME: Should be controlled by command line option.
459 Define(Defs, "__LONG_DOUBLE_128__");
460}
461
Chris Lattner9fd73612008-04-21 18:56:49 +0000462
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000463const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattner14d2bb72009-09-16 05:05:27 +0000464 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
465 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
466 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
467 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
468 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
469 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
470 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
471 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000472 "mq", "lr", "ctr", "ap",
Chris Lattner14d2bb72009-09-16 05:05:27 +0000473 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000474 "xer",
Chris Lattner14d2bb72009-09-16 05:05:27 +0000475 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
476 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
477 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
478 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000479 "vrsave", "vscr",
480 "spe_acc", "spefscr",
481 "sfp"
482};
Chris Lattner4b009652007-07-25 00:24:17 +0000483
Anton Korobeynikove7772382009-05-03 13:42:53 +0000484void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000485 unsigned &NumNames) const {
486 Names = GCCRegNames;
487 NumNames = llvm::array_lengthof(GCCRegNames);
488}
Chris Lattner4b009652007-07-25 00:24:17 +0000489
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000490const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
491 // While some of these aliases do map to different registers
492 // they still share the same register name.
Daniel Dunbar40b774e2009-09-17 07:03:19 +0000493 { { "0" }, "r0" },
494 { { "1"}, "r1" },
495 { { "2" }, "r2" },
496 { { "3" }, "r3" },
497 { { "4" }, "r4" },
498 { { "5" }, "r5" },
499 { { "6" }, "r6" },
500 { { "7" }, "r7" },
501 { { "8" }, "r8" },
502 { { "9" }, "r9" },
503 { { "10" }, "r10" },
504 { { "11" }, "r11" },
505 { { "12" }, "r12" },
506 { { "13" }, "r13" },
507 { { "14" }, "r14" },
508 { { "15" }, "r15" },
509 { { "16" }, "r16" },
510 { { "17" }, "r17" },
511 { { "18" }, "r18" },
512 { { "19" }, "r19" },
513 { { "20" }, "r20" },
514 { { "21" }, "r21" },
515 { { "22" }, "r22" },
516 { { "23" }, "r23" },
517 { { "24" }, "r24" },
518 { { "25" }, "r25" },
519 { { "26" }, "r26" },
520 { { "27" }, "r27" },
521 { { "28" }, "r28" },
522 { { "29" }, "r29" },
523 { { "30" }, "r30" },
524 { { "31" }, "r31" },
525 { { "fr0" }, "f0" },
526 { { "fr1" }, "f1" },
527 { { "fr2" }, "f2" },
528 { { "fr3" }, "f3" },
529 { { "fr4" }, "f4" },
530 { { "fr5" }, "f5" },
531 { { "fr6" }, "f6" },
532 { { "fr7" }, "f7" },
533 { { "fr8" }, "f8" },
534 { { "fr9" }, "f9" },
Mike Stump369c21c2009-09-17 21:15:00 +0000535 { { "fr10" }, "f10" },
Daniel Dunbar40b774e2009-09-17 07:03:19 +0000536 { { "fr11" }, "f11" },
537 { { "fr12" }, "f12" },
538 { { "fr13" }, "f13" },
539 { { "fr14" }, "f14" },
540 { { "fr15" }, "f15" },
541 { { "fr16" }, "f16" },
542 { { "fr17" }, "f17" },
543 { { "fr18" }, "f18" },
544 { { "fr19" }, "f19" },
545 { { "fr20" }, "f20" },
546 { { "fr21" }, "f21" },
547 { { "fr22" }, "f22" },
548 { { "fr23" }, "f23" },
549 { { "fr24" }, "f24" },
550 { { "fr25" }, "f25" },
551 { { "fr26" }, "f26" },
552 { { "fr27" }, "f27" },
553 { { "fr28" }, "f28" },
554 { { "fr29" }, "f29" },
555 { { "fr30" }, "f30" },
556 { { "fr31" }, "f31" },
557 { { "cc" }, "cr0" },
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000558};
559
Anton Korobeynikove7772382009-05-03 13:42:53 +0000560void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000561 unsigned &NumAliases) const {
562 Aliases = GCCRegAliases;
563 NumAliases = llvm::array_lengthof(GCCRegAliases);
564}
565} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +0000566
567namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000568class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000569public:
Eli Friedman2b161652008-08-21 00:13:15 +0000570 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
571 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner2e17d912009-11-07 18:59:41 +0000572 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Eli Friedman2b161652008-08-21 00:13:15 +0000573 }
Chris Lattner4b009652007-07-25 00:24:17 +0000574};
575} // end anonymous namespace.
576
577namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000578class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000579public:
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000580 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000581 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman38e31802009-07-01 03:36:11 +0000582 IntMaxType = SignedLong;
583 UIntMaxType = UnsignedLong;
584 Int64Type = SignedLong;
Eli Friedman2b161652008-08-21 00:13:15 +0000585 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner2e17d912009-11-07 18:59:41 +0000586 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnere5fde952008-05-09 06:17:04 +0000587 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000588};
589} // end anonymous namespace.
590
Chris Lattner4b009652007-07-25 00:24:17 +0000591namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000592// Namespace for x86 abstract base class
593const Builtin::Info BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000594#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
595#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner99ca9d62009-06-14 01:05:48 +0000596#include "clang/Basic/BuiltinsX86.def"
Eli Friedman872996c2008-08-20 02:34:37 +0000597};
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000598
Eli Friedman872996c2008-08-20 02:34:37 +0000599const char *GCCRegNames[] = {
600 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
601 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
602 "argp", "flags", "fspr", "dirflag", "frame",
603 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
604 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
605 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
606 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
607};
608
609const TargetInfo::GCCRegAlias GCCRegAliases[] = {
610 { { "al", "ah", "eax", "rax" }, "ax" },
611 { { "bl", "bh", "ebx", "rbx" }, "bx" },
612 { { "cl", "ch", "ecx", "rcx" }, "cx" },
613 { { "dl", "dh", "edx", "rdx" }, "dx" },
614 { { "esi", "rsi" }, "si" },
615 { { "edi", "rdi" }, "di" },
616 { { "esp", "rsp" }, "sp" },
617 { { "ebp", "rbp" }, "bp" },
618};
619
620// X86 target abstract base class; x86-32 and x86-64 are very close, so
621// most of the implementation can be shared.
622class X86TargetInfo : public TargetInfo {
Chris Lattner715fe4c2009-03-02 22:40:39 +0000623 enum X86SSEEnum {
624 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
625 } SSELevel;
Eli Friedman872996c2008-08-20 02:34:37 +0000626public:
Anton Korobeynikove7772382009-05-03 13:42:53 +0000627 X86TargetInfo(const std::string& triple)
Daniel Dunbar07181d72009-05-06 03:16:41 +0000628 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman872996c2008-08-20 02:34:37 +0000629 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner4b009652007-07-25 00:24:17 +0000630 }
631 virtual void getTargetBuiltins(const Builtin::Info *&Records,
632 unsigned &NumRecords) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000633 Records = BuiltinInfo;
634 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000635 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000636 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman872996c2008-08-20 02:34:37 +0000637 unsigned &NumNames) const {
638 Names = GCCRegNames;
639 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000640 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000641 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000642 unsigned &NumAliases) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000643 Aliases = GCCRegAliases;
644 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000645 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000646 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000647 TargetInfo::ConstraintInfo &info) const;
648 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlsson4ce42302007-11-27 04:11:28 +0000649 virtual const char *getClobbers() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000650 return "~{dirflag},~{fpsr},~{flags}";
651 }
Chris Lattner79682402009-03-20 15:52:06 +0000652 virtual void getTargetDefines(const LangOptions &Opts,
653 std::vector<char> &Defines) const;
Daniel Dunbar0838f962009-05-06 21:07:50 +0000654 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
655 const std::string &Name,
656 bool Enabled) const;
Mike Stump25cf7602009-09-09 15:08:12 +0000657 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar0838f962009-05-06 21:07:50 +0000658 llvm::StringMap<bool> &Features) const;
Daniel Dunbar8dd8f262009-11-11 09:38:56 +0000659 virtual void HandleTargetFeatures(const std::vector<std::string> &Features);
Chris Lattner4b009652007-07-25 00:24:17 +0000660};
Chris Lattner7d6220c2009-03-02 22:20:04 +0000661
Mike Stump25cf7602009-09-09 15:08:12 +0000662void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar0838f962009-05-06 21:07:50 +0000663 llvm::StringMap<bool> &Features) const {
Daniel Dunbar07181d72009-05-06 03:16:41 +0000664 // FIXME: This should not be here.
665 Features["3dnow"] = false;
666 Features["3dnowa"] = false;
667 Features["mmx"] = false;
668 Features["sse"] = false;
669 Features["sse2"] = false;
670 Features["sse3"] = false;
671 Features["ssse3"] = false;
672 Features["sse41"] = false;
673 Features["sse42"] = false;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000674
Daniel Dunbar07181d72009-05-06 03:16:41 +0000675 // LLVM does not currently recognize this.
676 // Features["sse4a"] = false;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000677
Daniel Dunbar07181d72009-05-06 03:16:41 +0000678 // FIXME: This *really* should not be here.
679
680 // X86_64 always has SSE2.
681 if (PointerWidth == 64)
682 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
683
Daniel Dunbarc2e55de2009-05-06 21:56:32 +0000684 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
685 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
686 ;
687 else if (CPU == "pentium-mmx" || CPU == "pentium2")
688 setFeatureEnabled(Features, "mmx", true);
689 else if (CPU == "pentium3")
690 setFeatureEnabled(Features, "sse", true);
691 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
692 setFeatureEnabled(Features, "sse2", true);
693 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
694 setFeatureEnabled(Features, "sse3", true);
695 else if (CPU == "core2")
696 setFeatureEnabled(Features, "ssse3", true);
697 else if (CPU == "penryn") {
698 setFeatureEnabled(Features, "sse4", true);
699 Features["sse42"] = false;
700 } else if (CPU == "atom")
701 setFeatureEnabled(Features, "sse3", true);
702 else if (CPU == "corei7")
703 setFeatureEnabled(Features, "sse4", true);
704 else if (CPU == "k6" || CPU == "winchip-c6")
705 setFeatureEnabled(Features, "mmx", true);
Mike Stump25cf7602009-09-09 15:08:12 +0000706 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarc2e55de2009-05-06 21:56:32 +0000707 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
708 setFeatureEnabled(Features, "mmx", true);
709 setFeatureEnabled(Features, "3dnow", true);
710 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
711 setFeatureEnabled(Features, "sse", true);
712 setFeatureEnabled(Features, "3dnowa", true);
713 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
714 CPU == "athlon-fx") {
Mike Stump25cf7602009-09-09 15:08:12 +0000715 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarc2e55de2009-05-06 21:56:32 +0000716 setFeatureEnabled(Features, "3dnowa", true);
717 } else if (CPU == "c3-2")
718 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar07181d72009-05-06 03:16:41 +0000719}
720
Daniel Dunbar0838f962009-05-06 21:07:50 +0000721bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump25cf7602009-09-09 15:08:12 +0000722 const std::string &Name,
Daniel Dunbar0838f962009-05-06 21:07:50 +0000723 bool Enabled) const {
724 // FIXME: This *really* should not be here.
725 if (!Features.count(Name) && Name != "sse4")
726 return false;
727
728 if (Enabled) {
729 if (Name == "mmx")
730 Features["mmx"] = true;
731 else if (Name == "sse")
732 Features["mmx"] = Features["sse"] = true;
733 else if (Name == "sse2")
734 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
735 else if (Name == "sse3")
Mike Stump25cf7602009-09-09 15:08:12 +0000736 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000737 Features["sse3"] = true;
738 else if (Name == "ssse3")
Mike Stump25cf7602009-09-09 15:08:12 +0000739 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000740 Features["ssse3"] = true;
741 else if (Name == "sse4")
Mike Stump25cf7602009-09-09 15:08:12 +0000742 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000743 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
744 else if (Name == "3dnow")
745 Features["3dnowa"] = true;
746 else if (Name == "3dnowa")
747 Features["3dnow"] = Features["3dnowa"] = true;
748 } else {
749 if (Name == "mmx")
Mike Stump25cf7602009-09-09 15:08:12 +0000750 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000751 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
752 else if (Name == "sse")
Mike Stump25cf7602009-09-09 15:08:12 +0000753 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000754 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
755 else if (Name == "sse2")
Mike Stump25cf7602009-09-09 15:08:12 +0000756 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000757 Features["sse41"] = Features["sse42"] = false;
758 else if (Name == "sse3")
Mike Stump25cf7602009-09-09 15:08:12 +0000759 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbar0838f962009-05-06 21:07:50 +0000760 Features["sse42"] = false;
761 else if (Name == "ssse3")
762 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
763 else if (Name == "sse4")
764 Features["sse41"] = Features["sse42"] = false;
765 else if (Name == "3dnow")
766 Features["3dnow"] = Features["3dnowa"] = false;
767 else if (Name == "3dnowa")
768 Features["3dnowa"] = false;
769 }
770
771 return true;
772}
773
Daniel Dunbar07181d72009-05-06 03:16:41 +0000774/// HandleTargetOptions - Perform initialization based on the user
775/// configured set of features.
Daniel Dunbar8dd8f262009-11-11 09:38:56 +0000776void
777X86TargetInfo::HandleTargetFeatures(const std::vector<std::string> &Features) {
778 // Remember the maximum enabled sselevel.
779 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
780 // Ignore disabled features.
781 if (Features[i][0] == '-')
782 continue;
783
784 assert(Features[i][0] == '+' && "Invalid target feature!");
785 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
786 .Case("sse42", SSE42)
787 .Case("sse41", SSE41)
788 .Case("ssse3", SSSE3)
789 .Case("sse2", SSE2)
790 .Case("sse", SSE1)
791 .Case("mmx", MMX)
792 .Default(NoMMXSSE);
793 SSELevel = std::max(SSELevel, Level);
794 }
Chris Lattner7d6220c2009-03-02 22:20:04 +0000795}
Chris Lattnerbef1d722009-03-02 22:27:17 +0000796
797/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
798/// that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000799void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
800 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000801 // Target identification.
802 if (PointerWidth == 64) {
803 Define(Defs, "_LP64");
804 Define(Defs, "__LP64__");
805 Define(Defs, "__amd64__");
806 Define(Defs, "__amd64");
807 Define(Defs, "__x86_64");
808 Define(Defs, "__x86_64__");
Chris Lattnerbef1d722009-03-02 22:27:17 +0000809 } else {
Chris Lattnerc345a802009-03-20 16:06:38 +0000810 DefineStd(Defs, "i386", Opts);
Chris Lattnerbef1d722009-03-02 22:27:17 +0000811 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000812
Chris Lattnerbef1d722009-03-02 22:27:17 +0000813 // Target properties.
814 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000815
Chris Lattnerbef1d722009-03-02 22:27:17 +0000816 // Subtarget options.
817 Define(Defs, "__nocona");
818 Define(Defs, "__nocona__");
819 Define(Defs, "__tune_nocona__");
Chris Lattnerbef1d722009-03-02 22:27:17 +0000820 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner715fe4c2009-03-02 22:40:39 +0000821
Chris Lattner25ac1c12009-04-19 17:32:33 +0000822 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
823 // functions in glibc header files that use FP Stack inline asm which the
824 // backend can't deal with (PR879).
825 Define(Defs, "__NO_MATH_INLINES");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000826
Chris Lattner715fe4c2009-03-02 22:40:39 +0000827 // Each case falls through to the previous one here.
828 switch (SSELevel) {
829 case SSE42:
830 Define(Defs, "__SSE4_2__");
831 case SSE41:
832 Define(Defs, "__SSE4_1__");
833 case SSSE3:
834 Define(Defs, "__SSSE3__");
835 case SSE3:
836 Define(Defs, "__SSE3__");
837 case SSE2:
838 Define(Defs, "__SSE2__");
839 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
840 case SSE1:
841 Define(Defs, "__SSE__");
842 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
843 case MMX:
844 Define(Defs, "__MMX__");
845 case NoMMXSSE:
846 break;
847 }
Chris Lattnerbef1d722009-03-02 22:27:17 +0000848}
Anton Korobeynikove7772382009-05-03 13:42:53 +0000849
850
Eli Friedman872996c2008-08-20 02:34:37 +0000851bool
Anders Carlsson36834a72009-02-28 17:11:49 +0000852X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000853 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000854 switch (*Name) {
Eli Friedman872996c2008-08-20 02:34:37 +0000855 default: return false;
856 case 'a': // eax.
857 case 'b': // ebx.
858 case 'c': // ecx.
859 case 'd': // edx.
860 case 'S': // esi.
861 case 'D': // edi.
862 case 'A': // edx:eax.
863 case 't': // top of floating point stack.
864 case 'u': // second from top of floating point stack.
865 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson2285e622008-10-06 00:41:45 +0000866 case 'y': // Any MMX register.
Anders Carlssond2459f92008-10-06 19:17:39 +0000867 case 'x': // Any SSE register.
Eli Friedman872996c2008-08-20 02:34:37 +0000868 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikove7772382009-05-03 13:42:53 +0000869 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssonff235da2009-01-24 18:03:09 +0000870 // x86_64 instructions.
Anton Korobeynikove7772382009-05-03 13:42:53 +0000871 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssonff235da2009-01-24 18:03:09 +0000872 // x86_64 instructions.
Eli Friedman872996c2008-08-20 02:34:37 +0000873 case 'N': // unsigned 8-bit integer constant for use with in and out
874 // instructions.
Eli Friedman7e17aed2009-06-08 20:45:44 +0000875 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000876 Info.setAllowsRegister();
Eli Friedman872996c2008-08-20 02:34:37 +0000877 return true;
878 }
879}
880
881std::string
882X86TargetInfo::convertConstraint(const char Constraint) const {
883 switch (Constraint) {
884 case 'a': return std::string("{ax}");
885 case 'b': return std::string("{bx}");
886 case 'c': return std::string("{cx}");
887 case 'd': return std::string("{dx}");
888 case 'S': return std::string("{si}");
889 case 'D': return std::string("{di}");
890 case 't': // top of floating point stack.
891 return std::string("{st}");
892 case 'u': // second from top of floating point stack.
893 return std::string("{st(1)}"); // second from top of floating point stack.
894 default:
895 return std::string(1, Constraint);
896 }
897}
Eli Friedman872996c2008-08-20 02:34:37 +0000898} // end anonymous namespace
Chris Lattner4b009652007-07-25 00:24:17 +0000899
900namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000901// X86-32 generic target
902class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000903public:
Eli Friedman872996c2008-08-20 02:34:37 +0000904 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
905 DoubleAlign = LongLongAlign = 32;
906 LongDoubleWidth = 96;
907 LongDoubleAlign = 32;
Eli Friedman2b161652008-08-21 00:13:15 +0000908 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
909 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner2e17d912009-11-07 18:59:41 +0000910 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman04ede302009-03-29 20:31:09 +0000911 SizeType = UnsignedInt;
912 PtrDiffType = SignedInt;
913 IntPtrType = SignedInt;
Anton Korobeynikov8fcffeb2009-04-03 23:38:25 +0000914 RegParmMax = 3;
Eli Friedman872996c2008-08-20 02:34:37 +0000915 }
916 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000917 return "typedef char* __builtin_va_list;";
Eli Friedman872996c2008-08-20 02:34:37 +0000918 }
Chris Lattneraa339182009-09-23 06:06:36 +0000919
920 int getEHDataRegisterNumber(unsigned RegNo) const {
921 if (RegNo == 0) return 0;
922 if (RegNo == 1) return 2;
923 return -1;
924 }
Eli Friedman872996c2008-08-20 02:34:37 +0000925};
926} // end anonymous namespace
927
928namespace {
Eli Friedman1c79f4b2009-07-05 18:47:56 +0000929class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
930public:
931 OpenBSDI386TargetInfo(const std::string& triple) :
932 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
933 SizeType = UnsignedLong;
934 IntPtrType = SignedLong;
Eli Friedman96ada022009-07-05 22:31:18 +0000935 PtrDiffType = SignedLong;
Eli Friedman1c79f4b2009-07-05 18:47:56 +0000936 }
937};
938} // end anonymous namespace
939
940namespace {
Edwin Török36565e52009-06-30 17:10:35 +0000941class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman872996c2008-08-20 02:34:37 +0000942public:
Edwin Török36565e52009-06-30 17:10:35 +0000943 DarwinI386TargetInfo(const std::string& triple) :
944 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman872996c2008-08-20 02:34:37 +0000945 LongDoubleWidth = 128;
946 LongDoubleAlign = 128;
Eli Friedman04ede302009-03-29 20:31:09 +0000947 SizeType = UnsignedLong;
948 IntPtrType = SignedLong;
Eli Friedman2b161652008-08-21 00:13:15 +0000949 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
950 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner2e17d912009-11-07 18:59:41 +0000951 "a0:0:64-f80:128:128-n8:16:32";
Edwin Török2d98f9f2009-06-30 17:00:25 +0000952 }
953
Eli Friedman872996c2008-08-20 02:34:37 +0000954};
Daniel Dunbar64c77a12009-06-29 20:52:51 +0000955} // end anonymous namespace
956
957namespace {
Eli Friedman23cb7912008-08-21 01:40:19 +0000958// x86-32 Windows target
959class WindowsX86_32TargetInfo : public X86_32TargetInfo {
960public:
961 WindowsX86_32TargetInfo(const std::string& triple)
962 : X86_32TargetInfo(triple) {
Eli Friedman8f575172009-04-19 21:38:35 +0000963 TLSSupported = false;
Chris Lattnera8a69e12009-06-24 17:12:15 +0000964 WCharType = UnsignedShort;
Eli Friedmanb28055e2009-06-08 21:16:17 +0000965 DoubleAlign = LongLongAlign = 64;
966 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
967 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner2e17d912009-11-07 18:59:41 +0000968 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman23cb7912008-08-21 01:40:19 +0000969 }
Chris Lattner79682402009-03-20 15:52:06 +0000970 virtual void getTargetDefines(const LangOptions &Opts,
971 std::vector<char> &Defines) const {
972 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman23cb7912008-08-21 01:40:19 +0000973 // This list is based off of the the list of things MingW defines
Eli Friedman23cb7912008-08-21 01:40:19 +0000974 Define(Defines, "_WIN32");
Chris Lattnerc345a802009-03-20 16:06:38 +0000975 DefineStd(Defines, "WIN32", Opts);
976 DefineStd(Defines, "WINNT", Opts);
Eli Friedman23cb7912008-08-21 01:40:19 +0000977 Define(Defines, "_X86_");
Eli Friedman23cb7912008-08-21 01:40:19 +0000978 }
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +0000979};
980} // end anonymous namespace
Eli Friedman6b6ca942009-06-08 06:11:14 +0000981
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +0000982namespace {
983
984/// GetWindowsVisualStudioLanguageOptions - Set the default language options for Windows.
985static void GetWindowsVisualStudioLanguageOptions(LangOptions &Opts) {
986 Opts.Microsoft = true;
987}
988
989// x86-32 Windows Visual Studio target
990class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
991public:
992 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
993 : WindowsX86_32TargetInfo(triple) {
994 }
995 virtual void getTargetDefines(const LangOptions &Opts,
996 std::vector<char> &Defines) const {
997 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
998 // The value of the following reflects processor type.
999 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1000 // We lost the original triple, so we use the default.
1001 Define(Defines, "_M_IX86", "600");
1002 }
Eli Friedman6b6ca942009-06-08 06:11:14 +00001003 virtual void getDefaultLangOptions(LangOptions &Opts) {
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001004 WindowsX86_32TargetInfo::getDefaultLangOptions(Opts);
1005 GetWindowsVisualStudioLanguageOptions(Opts);
1006 }
1007};
1008} // end anonymous namespace
1009
1010namespace {
1011// x86-32 MinGW target
1012class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1013public:
1014 MinGWX86_32TargetInfo(const std::string& triple)
1015 : WindowsX86_32TargetInfo(triple) {
1016 }
1017 virtual void getTargetDefines(const LangOptions &Opts,
1018 std::vector<char> &Defines) const {
1019 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
1020 Define(Defines, "__MSVCRT__");
1021 Define(Defines, "__MINGW32__");
Cédric Venet2c16e4e2009-09-27 10:09:11 +00001022 Define(Defines, "__declspec", "__declspec");
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001023 }
1024};
1025} // end anonymous namespace
1026
1027namespace {
1028// x86-32 Cygwin target
1029class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1030public:
1031 CygwinX86_32TargetInfo(const std::string& triple)
1032 : X86_32TargetInfo(triple) {
1033 TLSSupported = false;
1034 WCharType = UnsignedShort;
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001035 DoubleAlign = LongLongAlign = 64;
1036 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1037 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner2e17d912009-11-07 18:59:41 +00001038 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001039 }
1040 virtual void getTargetDefines(const LangOptions &Opts,
1041 std::vector<char> &Defines) const {
1042 X86_32TargetInfo::getTargetDefines(Opts, Defines);
1043 Define(Defines, "__CYGWIN__");
1044 Define(Defines, "__CYGWIN32__");
1045 DefineStd(Defines, "unix", Opts);
Eli Friedman6b6ca942009-06-08 06:11:14 +00001046 }
Eli Friedman23cb7912008-08-21 01:40:19 +00001047};
1048} // end anonymous namespace
1049
1050namespace {
Eli Friedman872996c2008-08-20 02:34:37 +00001051// x86-64 generic target
1052class X86_64TargetInfo : public X86TargetInfo {
1053public:
Chris Lattner79682402009-03-20 15:52:06 +00001054 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +00001055 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001056 LongDoubleWidth = 128;
1057 LongDoubleAlign = 128;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +00001058 IntMaxType = SignedLong;
1059 UIntMaxType = UnsignedLong;
Eli Friedman38e31802009-07-01 03:36:11 +00001060 Int64Type = SignedLong;
Anton Korobeynikov8fcffeb2009-04-03 23:38:25 +00001061 RegParmMax = 6;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +00001062
Eli Friedman2b161652008-08-21 00:13:15 +00001063 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1064 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner2e17d912009-11-07 18:59:41 +00001065 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Chris Lattner4b009652007-07-25 00:24:17 +00001066 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +00001067 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001068 return "typedef struct __va_list_tag {"
1069 " unsigned gp_offset;"
1070 " unsigned fp_offset;"
1071 " void* overflow_arg_area;"
1072 " void* reg_save_area;"
Eli Friedman3c79eee2009-07-03 00:45:06 +00001073 "} __va_list_tag;"
1074 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson7dd1c952007-11-24 23:38:12 +00001075 }
Chris Lattneraa339182009-09-23 06:06:36 +00001076
1077 int getEHDataRegisterNumber(unsigned RegNo) const {
1078 if (RegNo == 0) return 0;
1079 if (RegNo == 1) return 1;
1080 return -1;
1081 }
Eli Friedman872996c2008-08-20 02:34:37 +00001082};
1083} // end anonymous namespace
1084
1085namespace {
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001086// x86-64 Windows target
1087class WindowsX86_64TargetInfo : public X86_64TargetInfo {
1088public:
1089 WindowsX86_64TargetInfo(const std::string& triple)
1090 : X86_64TargetInfo(triple) {
1091 TLSSupported = false;
1092 WCharType = UnsignedShort;
Mike Stump4da7a162009-10-08 23:00:00 +00001093 LongWidth = LongAlign = 32;
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001094 DoubleAlign = LongLongAlign = 64;
1095 }
1096 virtual void getTargetDefines(const LangOptions &Opts,
1097 std::vector<char> &Defines) const {
1098 X86_64TargetInfo::getTargetDefines(Opts, Defines);
1099 Define(Defines, "_WIN64");
1100 DefineStd(Defines, "WIN64", Opts);
1101 }
1102};
1103} // end anonymous namespace
1104
1105namespace {
1106// x86-64 Windows Visual Studio target
1107class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1108public:
1109 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1110 : WindowsX86_64TargetInfo(triple) {
1111 }
1112 virtual void getTargetDefines(const LangOptions &Opts,
1113 std::vector<char> &Defines) const {
1114 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1115 Define(Defines, "_M_X64");
1116 }
1117 virtual const char *getVAListDeclaration() const {
1118 return "typedef char* va_list;";
1119 }
1120};
1121} // end anonymous namespace
1122
1123namespace {
1124// x86-64 MinGW target
1125class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1126public:
1127 MinGWX86_64TargetInfo(const std::string& triple)
1128 : WindowsX86_64TargetInfo(triple) {
1129 }
1130 virtual void getTargetDefines(const LangOptions &Opts,
1131 std::vector<char> &Defines) const {
1132 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1133 Define(Defines, "__MSVCRT__");
1134 Define(Defines, "__MINGW64__");
1135 Define(Defines, "__declspec");
1136 }
1137};
1138} // end anonymous namespace
1139
1140namespace {
Eli Friedman38e31802009-07-01 03:36:11 +00001141class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1142public:
Mike Stump25cf7602009-09-09 15:08:12 +00001143 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman38e31802009-07-01 03:36:11 +00001144 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1145 Int64Type = SignedLongLong;
1146 }
1147};
1148} // end anonymous namespace
1149
1150namespace {
Eli Friedman96ada022009-07-05 22:31:18 +00001151class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1152public:
Mike Stump25cf7602009-09-09 15:08:12 +00001153 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman96ada022009-07-05 22:31:18 +00001154 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1155 IntMaxType = SignedLongLong;
1156 UIntMaxType = UnsignedLongLong;
1157 Int64Type = SignedLongLong;
1158 }
1159};
1160} // end anonymous namespace
1161
1162namespace {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001163class ARMTargetInfo : public TargetInfo {
Mike Stumpf90a29f2009-04-08 02:07:04 +00001164 enum {
1165 Armv4t,
1166 Armv5,
1167 Armv6,
Mike Stump4e21ba42009-08-04 19:48:52 +00001168 Armv7a,
Mike Stumpf90a29f2009-04-08 02:07:04 +00001169 XScale
1170 } ArmArch;
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001171
Daniel Dunbar40b774e2009-09-17 07:03:19 +00001172 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1173 static const char * const GCCRegNames[];
1174
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001175 std::string ABI;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001176 bool IsThumb;
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001177
Chris Lattner9fd73612008-04-21 18:56:49 +00001178public:
Daniel Dunbarf0156562009-09-17 16:21:10 +00001179 ARMTargetInfo(const std::string &TripleStr)
1180 : TargetInfo(TripleStr), ABI("aapcs-linux"), IsThumb(false)
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001181 {
Daniel Dunbarf0156562009-09-17 16:21:10 +00001182 llvm::Triple Triple(TripleStr);
1183
Daniel Dunbarb9531632009-09-14 00:02:24 +00001184 SizeType = UnsignedInt;
1185 PtrDiffType = SignedInt;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001186
1187 // FIXME: This shouldn't be done this way, we should use features to
1188 // indicate the arch. See lib/Driver/Tools.cpp.
1189 llvm::StringRef Version(""), Arch = Triple.getArchName();
1190 if (Arch.startswith("arm"))
1191 Version = Arch.substr(3);
1192 else if (Arch.startswith("thumb"))
1193 Version = Arch.substr(5);
1194 if (Version == "v7")
Mike Stump4e21ba42009-08-04 19:48:52 +00001195 ArmArch = Armv7a;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001196 else if (Version.empty() || Version == "v6" || Version == "v6t2")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001197 ArmArch = Armv6;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001198 else if (Version == "v5")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001199 ArmArch = Armv5;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001200 else if (Version == "v4t")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001201 ArmArch = Armv4t;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001202 else if (Arch == "xscale" || Arch == "thumbv5e")
Mike Stumpf90a29f2009-04-08 02:07:04 +00001203 ArmArch = XScale;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001204 else
Chris Lattner433d9722009-04-23 04:22:04 +00001205 ArmArch = Armv6;
Daniel Dunbarf0156562009-09-17 16:21:10 +00001206
1207 if (Arch.startswith("thumb"))
1208 IsThumb = true;
Daniel Dunbar54f62dc2009-09-22 21:44:58 +00001209
1210 if (IsThumb) {
1211 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1212 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner2e17d912009-11-07 18:59:41 +00001213 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar54f62dc2009-09-22 21:44:58 +00001214 } else {
1215 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1216 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner2e17d912009-11-07 18:59:41 +00001217 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar54f62dc2009-09-22 21:44:58 +00001218 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001219 }
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001220 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbarb9531632009-09-14 00:02:24 +00001221 virtual bool setABI(const std::string &Name) {
Daniel Dunbar0d83d512009-09-14 00:35:03 +00001222 ABI = Name;
1223
Daniel Dunbarb9531632009-09-14 00:02:24 +00001224 // The defaults (above) are for AAPCS, check if we need to change them.
1225 //
1226 // FIXME: We need support for -meabi... we could just mangle it into the
1227 // name.
1228 if (Name == "apcs-gnu") {
1229 DoubleAlign = LongLongAlign = 32;
1230 SizeType = UnsignedLong;
1231
Daniel Dunbar54f62dc2009-09-22 21:44:58 +00001232 if (IsThumb) {
1233 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1234 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner2e17d912009-11-07 18:59:41 +00001235 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar54f62dc2009-09-22 21:44:58 +00001236 } else {
1237 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1238 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner2e17d912009-11-07 18:59:41 +00001239 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar54f62dc2009-09-22 21:44:58 +00001240 }
1241
Daniel Dunbarb9531632009-09-14 00:02:24 +00001242 // FIXME: Override "preferred align" for double and long long.
1243 } else if (Name == "aapcs") {
1244 // FIXME: Enumerated types are variable width in straight AAPCS.
1245 } else if (Name == "aapcs-linux") {
1246 ;
1247 } else
1248 return false;
1249
1250 return true;
1251 }
Chris Lattner79682402009-03-20 15:52:06 +00001252 virtual void getTargetDefines(const LangOptions &Opts,
1253 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +00001254 // Target identification.
1255 Define(Defs, "__arm");
1256 Define(Defs, "__arm__");
Anton Korobeynikove7772382009-05-03 13:42:53 +00001257
Chris Lattnerbef1d722009-03-02 22:27:17 +00001258 // Target properties.
1259 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +00001260
Mike Stumpf90a29f2009-04-08 02:07:04 +00001261 // Subtarget options.
Daniel Dunbarf0156562009-09-17 16:21:10 +00001262 //
1263 // FIXME: Neither THUMB_INTERWORK nor SOFTFP is not being set correctly
1264 // here.
Mike Stump4e21ba42009-08-04 19:48:52 +00001265 if (ArmArch == Armv7a) {
1266 Define(Defs, "__ARM_ARCH_7A__");
1267 Define(Defs, "__THUMB_INTERWORK__");
1268 } else if (ArmArch == Armv6) {
Mike Stumpf90a29f2009-04-08 02:07:04 +00001269 Define(Defs, "__ARM_ARCH_6K__");
1270 Define(Defs, "__THUMB_INTERWORK__");
1271 } else if (ArmArch == Armv5) {
1272 Define(Defs, "__ARM_ARCH_5TEJ__");
1273 Define(Defs, "__THUMB_INTERWORK__");
1274 Define(Defs, "__SOFTFP__");
1275 } else if (ArmArch == Armv4t) {
1276 Define(Defs, "__ARM_ARCH_4T__");
1277 Define(Defs, "__SOFTFP__");
1278 } else if (ArmArch == XScale) {
1279 Define(Defs, "__ARM_ARCH_5TE__");
1280 Define(Defs, "__XSCALE__");
1281 Define(Defs, "__SOFTFP__");
1282 }
Daniel Dunbarf0156562009-09-17 16:21:10 +00001283
Chris Lattnerbef1d722009-03-02 22:27:17 +00001284 Define(Defs, "__ARMEL__");
Daniel Dunbarf0156562009-09-17 16:21:10 +00001285
1286 if (IsThumb) {
1287 Define(Defs, "__THUMBEL__");
1288 Define(Defs, "__thumb__");
1289 if (ArmArch == Armv7a)
1290 Define(Defs, "__thumb2__");
1291 }
1292
1293 // Note, this is always on in gcc, even though it doesn't make sense.
Eli Friedman468ca6d2009-05-29 19:00:15 +00001294 Define(Defs, "__APCS_32__");
Daniel Dunbarf0156562009-09-17 16:21:10 +00001295 // FIXME: This should be conditional on VFP instruction support.
Eli Friedman468ca6d2009-05-29 19:00:15 +00001296 Define(Defs, "__VFP_FP__");
Daniel Dunbarf0156562009-09-17 16:21:10 +00001297
1298 Define(Defs, "__USING_SJLJ_EXCEPTIONS__");
Chris Lattner9fd73612008-04-21 18:56:49 +00001299 }
1300 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1301 unsigned &NumRecords) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001302 // FIXME: Implement.
1303 Records = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +00001304 NumRecords = 0;
1305 }
1306 virtual const char *getVAListDeclaration() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001307 return "typedef char* __builtin_va_list;";
Chris Lattner9fd73612008-04-21 18:56:49 +00001308 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001309 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar40b774e2009-09-17 07:03:19 +00001310 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +00001311 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar40b774e2009-09-17 07:03:19 +00001312 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +00001313 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +00001314 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001315 // FIXME: Check if this is complete
Anders Carlsson36834a72009-02-28 17:11:49 +00001316 switch (*Name) {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001317 default:
Nate Begeman222823a2008-04-22 05:03:19 +00001318 case 'l': // r0-r7
1319 case 'h': // r8-r15
1320 case 'w': // VFP Floating point register single precision
1321 case 'P': // VFP Floating point register double precision
Chris Lattnerc49cc1a2009-04-26 07:16:29 +00001322 Info.setAllowsRegister();
Nate Begeman222823a2008-04-22 05:03:19 +00001323 return true;
1324 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001325 return false;
1326 }
1327 virtual const char *getClobbers() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001328 // FIXME: Is this really right?
Chris Lattner9fd73612008-04-21 18:56:49 +00001329 return "";
1330 }
1331};
Daniel Dunbar40b774e2009-09-17 07:03:19 +00001332
1333const char * const ARMTargetInfo::GCCRegNames[] = {
1334 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1335 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1336};
1337
1338void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
1339 unsigned &NumNames) const {
1340 Names = GCCRegNames;
1341 NumNames = llvm::array_lengthof(GCCRegNames);
1342}
1343
1344const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1345
1346 { { "a1" }, "r0" },
1347 { { "a2" }, "r1" },
1348 { { "a3" }, "r2" },
1349 { { "a4" }, "r3" },
1350 { { "v1" }, "r4" },
1351 { { "v2" }, "r5" },
1352 { { "v3" }, "r6" },
1353 { { "v4" }, "r7" },
1354 { { "v5" }, "r8" },
1355 { { "v6", "rfp" }, "r9" },
1356 { { "sl" }, "r10" },
1357 { { "fp" }, "r11" },
1358 { { "ip" }, "r12" },
1359 { { "sp" }, "r13" },
1360 { { "lr" }, "r14" },
1361 { { "pc" }, "r15" },
1362};
1363
1364void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1365 unsigned &NumAliases) const {
1366 Aliases = GCCRegAliases;
1367 NumAliases = llvm::array_lengthof(GCCRegAliases);
1368}
Chris Lattner9fd73612008-04-21 18:56:49 +00001369} // end anonymous namespace.
1370
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001371
1372namespace {
Mike Stump25cf7602009-09-09 15:08:12 +00001373class DarwinARMTargetInfo :
Edwin Török36565e52009-06-30 17:10:35 +00001374 public DarwinTargetInfo<ARMTargetInfo> {
1375protected:
Daniel Dunbar608b3882009-08-24 09:10:05 +00001376 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Edwin Török36565e52009-06-30 17:10:35 +00001377 std::vector<char> &Defines) const {
1378 getDarwinDefines(Defines, Opts);
1379 getDarwinIPhoneOSDefines(Defines, Triple);
Eli Friedman8f575172009-04-19 21:38:35 +00001380 }
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001381
Edwin Török36565e52009-06-30 17:10:35 +00001382public:
Mike Stump25cf7602009-09-09 15:08:12 +00001383 DarwinARMTargetInfo(const std::string& triple)
Edwin Török36565e52009-06-30 17:10:35 +00001384 : DarwinTargetInfo<ARMTargetInfo>(triple) {}
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001385};
1386} // end anonymous namespace.
1387
Chris Lattner4b009652007-07-25 00:24:17 +00001388namespace {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001389class SparcV8TargetInfo : public TargetInfo {
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001390 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1391 static const char * const GCCRegNames[];
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001392public:
Eli Friedmanff158dd2008-08-20 07:28:14 +00001393 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1394 // FIXME: Support Sparc quad-precision long double?
Eli Friedman2b161652008-08-21 00:13:15 +00001395 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner2e17d912009-11-07 18:59:41 +00001396 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedmanff158dd2008-08-20 07:28:14 +00001397 }
Chris Lattner79682402009-03-20 15:52:06 +00001398 virtual void getTargetDefines(const LangOptions &Opts,
1399 std::vector<char> &Defines) const {
Eli Friedmana456b7f2009-05-22 01:12:57 +00001400 DefineStd(Defines, "sparc", Opts);
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001401 Define(Defines, "__sparcv8");
Eli Friedmana456b7f2009-05-22 01:12:57 +00001402 Define(Defines, "__REGISTER_PREFIX__", "");
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001403 }
1404 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1405 unsigned &NumRecords) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001406 // FIXME: Implement!
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001407 }
1408 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001409 return "typedef void* __builtin_va_list;";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001410 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001411 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001412 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +00001413 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001414 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +00001415 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001416 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001417 // FIXME: Implement!
1418 return false;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001419 }
1420 virtual const char *getClobbers() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001421 // FIXME: Implement!
1422 return "";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001423 }
1424};
1425
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001426const char * const SparcV8TargetInfo::GCCRegNames[] = {
1427 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1428 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1429 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1430 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1431};
1432
Anton Korobeynikove7772382009-05-03 13:42:53 +00001433void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001434 unsigned &NumNames) const {
1435 Names = GCCRegNames;
1436 NumNames = llvm::array_lengthof(GCCRegNames);
1437}
1438
1439const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikove7772382009-05-03 13:42:53 +00001440 { { "g0" }, "r0" },
1441 { { "g1" }, "r1" },
1442 { { "g2" }, "r2" },
1443 { { "g3" }, "r3" },
1444 { { "g4" }, "r4" },
1445 { { "g5" }, "r5" },
1446 { { "g6" }, "r6" },
1447 { { "g7" }, "r7" },
1448 { { "o0" }, "r8" },
1449 { { "o1" }, "r9" },
1450 { { "o2" }, "r10" },
1451 { { "o3" }, "r11" },
1452 { { "o4" }, "r12" },
1453 { { "o5" }, "r13" },
1454 { { "o6", "sp" }, "r14" },
1455 { { "o7" }, "r15" },
1456 { { "l0" }, "r16" },
1457 { { "l1" }, "r17" },
1458 { { "l2" }, "r18" },
1459 { { "l3" }, "r19" },
1460 { { "l4" }, "r20" },
1461 { { "l5" }, "r21" },
1462 { { "l6" }, "r22" },
1463 { { "l7" }, "r23" },
1464 { { "i0" }, "r24" },
1465 { { "i1" }, "r25" },
1466 { { "i2" }, "r26" },
1467 { { "i3" }, "r27" },
1468 { { "i4" }, "r28" },
1469 { { "i5" }, "r29" },
1470 { { "i6", "fp" }, "r30" },
1471 { { "i7" }, "r31" },
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001472};
1473
Anton Korobeynikove7772382009-05-03 13:42:53 +00001474void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001475 unsigned &NumAliases) const {
1476 Aliases = GCCRegAliases;
1477 NumAliases = llvm::array_lengthof(GCCRegAliases);
1478}
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001479} // end anonymous namespace.
1480
Eli Friedmanff158dd2008-08-20 07:28:14 +00001481namespace {
Edward O'Callaghan0a7ef9a2009-10-18 13:33:59 +00001482class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
1483public:
1484 AuroraUXSparcV8TargetInfo(const std::string& triple) :
1485 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
1486 SizeType = UnsignedInt;
1487 PtrDiffType = SignedInt;
1488 }
1489};
Edwin Török36565e52009-06-30 17:10:35 +00001490class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001491public:
1492 SolarisSparcV8TargetInfo(const std::string& triple) :
Edwin Török36565e52009-06-30 17:10:35 +00001493 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedman7cca0982008-11-02 02:43:55 +00001494 SizeType = UnsignedInt;
1495 PtrDiffType = SignedInt;
Eli Friedmanff158dd2008-08-20 07:28:14 +00001496 }
1497};
1498} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +00001499
Chris Lattner85970f32008-05-08 05:58:21 +00001500namespace {
1501 class PIC16TargetInfo : public TargetInfo{
1502 public:
1503 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedman8f575172009-04-19 21:38:35 +00001504 TLSSupported = false;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001505 IntWidth = 16;
1506 LongWidth = LongLongWidth = 32;
1507 PointerWidth = 16;
1508 IntAlign = 8;
1509 LongAlign = LongLongAlign = 8;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001510 PointerAlign = 8;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001511 SizeType = UnsignedInt;
1512 IntMaxType = SignedLong;
1513 UIntMaxType = UnsignedLong;
Chris Lattnerd9ef7242009-02-13 22:28:55 +00001514 IntPtrType = SignedShort;
Eli Friedman7cca0982008-11-02 02:43:55 +00001515 PtrDiffType = SignedInt;
Sanjiv Guptaae8f1e82009-06-02 04:43:46 +00001516 FloatWidth = 32;
1517 FloatAlign = 32;
1518 DoubleWidth = 32;
1519 DoubleAlign = 32;
1520 LongDoubleWidth = 32;
1521 LongDoubleAlign = 32;
1522 FloatFormat = &llvm::APFloat::IEEEsingle;
1523 DoubleFormat = &llvm::APFloat::IEEEsingle;
1524 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner2e17d912009-11-07 18:59:41 +00001525 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8";
Sanjiv Guptaae8f1e82009-06-02 04:43:46 +00001526
Chris Lattner85970f32008-05-08 05:58:21 +00001527 }
Chris Lattner727b3c42008-05-09 06:08:39 +00001528 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1529 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner79682402009-03-20 15:52:06 +00001530 virtual void getTargetDefines(const LangOptions &Opts,
1531 std::vector<char> &Defines) const {
Chris Lattner85970f32008-05-08 05:58:21 +00001532 Define(Defines, "__pic16");
Sanjiv Guptad75fd0b2009-07-07 04:42:23 +00001533 Define(Defines, "rom", "__attribute__((address_space(1)))");
1534 Define(Defines, "ram", "__attribute__((address_space(0)))");
Mike Stump25cf7602009-09-09 15:08:12 +00001535 Define(Defines, "_section(SectName)",
Sanjiv Gupta9e2b9e02009-08-20 17:48:52 +00001536 "__attribute__((section(SectName)))");
Sanjiv Gupta09e95f02009-10-24 18:08:20 +00001537 Define(Defines, "near",
1538 "__attribute__((section(\"Address=NEAR\")))");
Sanjiv Gupta9e2b9e02009-08-20 17:48:52 +00001539 Define(Defines, "_address(Addr)",
1540 "__attribute__((section(\"Address=\"#Addr)))");
Sanjiv Guptad75fd0b2009-07-07 04:42:23 +00001541 Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
Sanjiv Gupta9e2b9e02009-08-20 17:48:52 +00001542 Define(Defines, "_interrupt",
1543 "__attribute__((section(\"interrupt=0x4\"))) \
1544 __attribute__((used))");
Chris Lattner85970f32008-05-08 05:58:21 +00001545 }
1546 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1547 unsigned &NumRecords) const {}
Mike Stump25cf7602009-09-09 15:08:12 +00001548 virtual const char *getVAListDeclaration() const {
Daniel Dunbar2e967de2009-08-24 09:54:37 +00001549 return "";
1550 }
1551 virtual const char *getClobbers() const {
1552 return "";
1553 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001554 virtual void getGCCRegNames(const char * const *&Names,
1555 unsigned &NumNames) const {}
1556 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner85970f32008-05-08 05:58:21 +00001557 TargetInfo::ConstraintInfo &info) const {
1558 return true;
1559 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001560 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner85970f32008-05-08 05:58:21 +00001561 unsigned &NumAliases) const {}
1562 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1563 };
1564}
1565
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001566namespace {
1567 class MSP430TargetInfo : public TargetInfo {
1568 static const char * const GCCRegNames[];
1569 public:
1570 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1571 TLSSupported = false;
1572 IntWidth = 16;
1573 LongWidth = LongLongWidth = 32;
1574 PointerWidth = 16;
1575 IntAlign = 8;
1576 LongAlign = LongLongAlign = 8;
1577 PointerAlign = 8;
1578 SizeType = UnsignedInt;
1579 IntMaxType = SignedLong;
1580 UIntMaxType = UnsignedLong;
1581 IntPtrType = SignedShort;
1582 PtrDiffType = SignedInt;
Chris Lattner2e17d912009-11-07 18:59:41 +00001583 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-n8:16";
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001584 }
1585 virtual void getTargetDefines(const LangOptions &Opts,
1586 std::vector<char> &Defines) const {
1587 Define(Defines, "MSP430");
1588 Define(Defines, "__MSP430__");
1589 // FIXME: defines for different 'flavours' of MCU
1590 }
1591 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1592 unsigned &NumRecords) const {
1593 // FIXME: Implement.
1594 Records = 0;
1595 NumRecords = 0;
1596 }
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001597 virtual void getGCCRegNames(const char * const *&Names,
1598 unsigned &NumNames) const;
1599 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1600 unsigned &NumAliases) const {
1601 // No aliases.
1602 Aliases = 0;
1603 NumAliases = 0;
1604 }
1605 virtual bool validateAsmConstraint(const char *&Name,
1606 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov174219b2009-10-15 23:17:13 +00001607 // No target constraints for now.
1608 return false;
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001609 }
1610 virtual const char *getClobbers() const {
1611 // FIXME: Is this really right?
1612 return "";
1613 }
1614 virtual const char *getVAListDeclaration() const {
1615 // FIXME: implement
Anton Korobeynikovf5955592009-05-08 18:24:57 +00001616 return "typedef char* __builtin_va_list;";
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001617 }
1618 };
1619
1620 const char * const MSP430TargetInfo::GCCRegNames[] = {
1621 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1622 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1623 };
1624
1625 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1626 unsigned &NumNames) const {
1627 Names = GCCRegNames;
1628 NumNames = llvm::array_lengthof(GCCRegNames);
1629 }
1630}
1631
1632
Anton Korobeynikov57f236f2009-07-16 20:09:57 +00001633namespace {
1634 class SystemZTargetInfo : public TargetInfo {
1635 static const char * const GCCRegNames[];
1636 public:
1637 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
1638 TLSSupported = false;
1639 IntWidth = IntAlign = 32;
1640 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
1641 PointerWidth = PointerAlign = 64;
Chris Lattner2e17d912009-11-07 18:59:41 +00001642 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
1643 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikov57f236f2009-07-16 20:09:57 +00001644 }
1645 virtual void getTargetDefines(const LangOptions &Opts,
1646 std::vector<char> &Defines) const {
1647 Define(Defines, "__s390__");
1648 Define(Defines, "__s390x__");
1649 }
1650 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1651 unsigned &NumRecords) const {
1652 // FIXME: Implement.
1653 Records = 0;
1654 NumRecords = 0;
1655 }
Anton Korobeynikov57f236f2009-07-16 20:09:57 +00001656
1657 virtual void getDefaultLangOptions(LangOptions &Opts) {
1658 TargetInfo::getDefaultLangOptions(Opts);
1659 Opts.CharIsSigned = false;
1660 }
1661
1662 virtual void getGCCRegNames(const char * const *&Names,
1663 unsigned &NumNames) const;
1664 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1665 unsigned &NumAliases) const {
1666 // No aliases.
1667 Aliases = 0;
1668 NumAliases = 0;
1669 }
1670 virtual bool validateAsmConstraint(const char *&Name,
1671 TargetInfo::ConstraintInfo &info) const {
1672 // FIXME: implement
1673 return true;
1674 }
1675 virtual const char *getClobbers() const {
1676 // FIXME: Is this really right?
1677 return "";
1678 }
1679 virtual const char *getVAListDeclaration() const {
1680 // FIXME: implement
1681 return "typedef char* __builtin_va_list;";
1682 }
1683 };
1684
1685 const char * const SystemZTargetInfo::GCCRegNames[] = {
1686 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1687 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1688 };
1689
1690 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
1691 unsigned &NumNames) const {
1692 Names = GCCRegNames;
1693 NumNames = llvm::array_lengthof(GCCRegNames);
1694 }
1695}
1696
Jakob Stoklund Olesen61774372009-08-17 20:08:44 +00001697namespace {
1698 class BlackfinTargetInfo : public TargetInfo {
1699 static const char * const GCCRegNames[];
1700 public:
1701 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
1702 TLSSupported = false;
1703 DoubleAlign = 32;
1704 LongLongAlign = 32;
1705 LongDoubleAlign = 32;
Chris Lattner2e17d912009-11-07 18:59:41 +00001706 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen61774372009-08-17 20:08:44 +00001707 }
1708
1709 virtual void getTargetDefines(const LangOptions &Opts,
1710 std::vector<char> &Defines) const {
1711 DefineStd(Defines, "bfin", Opts);
1712 DefineStd(Defines, "BFIN", Opts);
1713 Define(Defines, "__ADSPBLACKFIN__");
1714 // FIXME: This one is really dependent on -mcpu
1715 Define(Defines, "__ADSPLPBLACKFIN__");
1716 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
1717 }
1718
1719 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1720 unsigned &NumRecords) const {
1721 // FIXME: Implement.
1722 Records = 0;
1723 NumRecords = 0;
1724 }
1725
Jakob Stoklund Olesen61774372009-08-17 20:08:44 +00001726 virtual void getGCCRegNames(const char * const *&Names,
1727 unsigned &NumNames) const;
1728
1729 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1730 unsigned &NumAliases) const {
1731 // No aliases.
1732 Aliases = 0;
1733 NumAliases = 0;
1734 }
1735
1736 virtual bool validateAsmConstraint(const char *&Name,
1737 TargetInfo::ConstraintInfo &Info) const {
1738 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
1739 Info.setAllowsRegister();
1740 return true;
1741 }
1742 return false;
1743 }
1744
1745 virtual const char *getClobbers() const {
1746 return "";
1747 }
1748
1749 virtual const char *getVAListDeclaration() const {
1750 return "typedef char* __builtin_va_list;";
1751 }
1752 };
1753
1754 const char * const BlackfinTargetInfo::GCCRegNames[] = {
1755 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1756 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
1757 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
1758 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
1759 "a0", "a1", "cc",
1760 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
1761 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
1762 };
1763
1764 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
1765 unsigned &NumNames) const {
1766 Names = GCCRegNames;
1767 NumNames = llvm::array_lengthof(GCCRegNames);
1768 }
1769}
1770
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001771namespace {
1772
Mike Stump25cf7602009-09-09 15:08:12 +00001773 // LLVM and Clang cannot be used directly to output native binaries for
1774 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001775 // type and alignment information.
Mike Stump25cf7602009-09-09 15:08:12 +00001776 //
1777 // TCE uses the llvm bitcode as input and uses it for generating customized
1778 // target processor and program binary. TCE co-design environment is
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001779 // publicly available in http://tce.cs.tut.fi
1780
1781 class TCETargetInfo : public TargetInfo{
1782 public:
1783 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
1784 TLSSupported = false;
1785 IntWidth = 32;
1786 LongWidth = LongLongWidth = 32;
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001787 PointerWidth = 32;
1788 IntAlign = 32;
1789 LongAlign = LongLongAlign = 32;
1790 PointerAlign = 32;
1791 SizeType = UnsignedInt;
1792 IntMaxType = SignedLong;
1793 UIntMaxType = UnsignedLong;
1794 IntPtrType = SignedInt;
1795 PtrDiffType = SignedInt;
1796 FloatWidth = 32;
1797 FloatAlign = 32;
1798 DoubleWidth = 32;
1799 DoubleAlign = 32;
1800 LongDoubleWidth = 32;
1801 LongDoubleAlign = 32;
1802 FloatFormat = &llvm::APFloat::IEEEsingle;
1803 DoubleFormat = &llvm::APFloat::IEEEsingle;
1804 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1805 DescriptionString = "E-p:32:32:32-a0:32:32"
1806 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64"
Chris Lattner2e17d912009-11-07 18:59:41 +00001807 "-f32:32:32-f64:32:64-n32";
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001808 }
1809
1810 virtual void getTargetDefines(const LangOptions &Opts,
1811 std::vector<char> &Defines) const {
1812 DefineStd(Defines, "tce", Opts);
1813 Define(Defines, "__TCE__");
1814 Define(Defines, "__TCE_V1__");
1815 }
1816 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1817 unsigned &NumRecords) const {}
Daniel Dunbar2e967de2009-08-24 09:54:37 +00001818 virtual const char *getClobbers() const {
1819 return "";
1820 }
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001821 virtual const char *getVAListDeclaration() const {
1822 return "typedef void* __builtin_va_list;";
1823 }
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001824 virtual void getGCCRegNames(const char * const *&Names,
1825 unsigned &NumNames) const {}
1826 virtual bool validateAsmConstraint(const char *&Name,
1827 TargetInfo::ConstraintInfo &info) const {
1828 return true;
1829 }
1830 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1831 unsigned &NumAliases) const {}
1832 };
1833}
1834
Chris Lattner4b009652007-07-25 00:24:17 +00001835//===----------------------------------------------------------------------===//
1836// Driver code
1837//===----------------------------------------------------------------------===//
1838
Chris Lattnerfc457002008-03-05 01:18:20 +00001839/// CreateTargetInfo - Return the target info object for the specified target
1840/// triple.
1841TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001842 llvm::Triple Triple(T);
1843 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001844
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001845 switch (Triple.getArch()) {
1846 default:
1847 return NULL;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001848
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001849 case llvm::Triple::arm:
Daniel Dunbar3f361b52009-09-11 01:14:50 +00001850 case llvm::Triple::thumb:
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001851 switch (os) {
1852 case llvm::Triple::Darwin:
Eli Friedman2b161652008-08-21 00:13:15 +00001853 return new DarwinARMTargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001854 case llvm::Triple::FreeBSD:
Edwin Török36565e52009-06-30 17:10:35 +00001855 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001856 default:
1857 return new ARMTargetInfo(T);
1858 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001859
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001860 case llvm::Triple::bfin:
Jakob Stoklund Olesen61774372009-08-17 20:08:44 +00001861 return new BlackfinTargetInfo(T);
1862
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001863 case llvm::Triple::msp430:
1864 return new MSP430TargetInfo(T);
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001865
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001866 case llvm::Triple::pic16:
1867 return new PIC16TargetInfo(T);
1868
1869 case llvm::Triple::ppc:
1870 if (os == llvm::Triple::Darwin)
1871 return new DarwinTargetInfo<PPCTargetInfo>(T);
1872 return new PPC32TargetInfo(T);
1873
1874 case llvm::Triple::ppc64:
1875 if (os == llvm::Triple::Darwin)
1876 return new DarwinTargetInfo<PPC64TargetInfo>(T);
1877 return new PPC64TargetInfo(T);
1878
1879 case llvm::Triple::sparc:
Edward O'Callaghan0a7ef9a2009-10-18 13:33:59 +00001880 if (os == llvm::Triple::AuroraUX)
1881 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001882 if (os == llvm::Triple::Solaris)
1883 return new SolarisSparcV8TargetInfo(T);
1884 return new SparcV8TargetInfo(T);
1885
1886 case llvm::Triple::systemz:
1887 return new SystemZTargetInfo(T);
1888
Eli Friedmanf0ff32f2009-08-19 20:47:07 +00001889 case llvm::Triple::tce:
1890 return new TCETargetInfo(T);
1891
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001892 case llvm::Triple::x86:
1893 switch (os) {
Edward O'Callaghan0a7ef9a2009-10-18 13:33:59 +00001894 case llvm::Triple::AuroraUX:
1895 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001896 case llvm::Triple::Darwin:
1897 return new DarwinI386TargetInfo(T);
1898 case llvm::Triple::Linux:
1899 return new LinuxTargetInfo<X86_32TargetInfo>(T);
1900 case llvm::Triple::DragonFly:
1901 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
1902 case llvm::Triple::NetBSD:
1903 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
1904 case llvm::Triple::OpenBSD:
1905 return new OpenBSDI386TargetInfo(T);
1906 case llvm::Triple::FreeBSD:
1907 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
1908 case llvm::Triple::Solaris:
1909 return new SolarisTargetInfo<X86_32TargetInfo>(T);
1910 case llvm::Triple::Cygwin:
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001911 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001912 case llvm::Triple::MinGW32:
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001913 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001914 case llvm::Triple::Win32:
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001915 return new VisualStudioWindowsX86_32TargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001916 default:
1917 return new X86_32TargetInfo(T);
1918 }
1919
1920 case llvm::Triple::x86_64:
1921 switch (os) {
Edward O'Callaghan0a7ef9a2009-10-18 13:33:59 +00001922 case llvm::Triple::AuroraUX:
1923 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001924 case llvm::Triple::Darwin:
1925 return new DarwinX86_64TargetInfo(T);
1926 case llvm::Triple::Linux:
1927 return new LinuxTargetInfo<X86_64TargetInfo>(T);
1928 case llvm::Triple::NetBSD:
1929 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
1930 case llvm::Triple::OpenBSD:
1931 return new OpenBSDX86_64TargetInfo(T);
1932 case llvm::Triple::FreeBSD:
1933 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
1934 case llvm::Triple::Solaris:
1935 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar8d8e9d62009-09-23 07:31:35 +00001936 case llvm::Triple::MinGW64:
1937 return new MinGWX86_64TargetInfo(T);
1938 case llvm::Triple::Win32: // This is what Triple.h supports now.
1939 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar8ba3de02009-08-18 05:47:58 +00001940 default:
1941 return new X86_64TargetInfo(T);
1942 }
1943 }
Chris Lattner4b009652007-07-25 00:24:17 +00001944}