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