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