blob: ae6d5df673c08a0c16a3f94ccd8ce8671f061069 [file] [log] [blame]
Chris Lattner5ba61f02006-10-14 07:39:34 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner5ba61f02006-10-14 07:39:34 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenek6f6ff372007-12-12 18:05:32 +000011// target triple.
Chris Lattner5ba61f02006-10-14 07:39:34 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner5ba61f02006-10-14 07:39:34 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000016#include "clang/Basic/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
Chris Lattnerc7c6dd42008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Chandler Carruth26b29a02010-01-20 06:13:02 +000019#include "clang/Basic/MacroBuilder.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000020#include "clang/Basic/TargetBuiltins.h"
21#include "clang/Basic/TargetOptions.h"
Eli Friedman7cef49e2008-05-20 14:27:34 +000022#include "llvm/ADT/APFloat.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000023#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000024#include "llvm/ADT/STLExtras.h"
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000025#include "llvm/ADT/StringRef.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000026#include "llvm/ADT/StringSwitch.h"
Chris Lattner859c37a2009-08-12 06:24:27 +000027#include "llvm/ADT/Triple.h"
Chris Lattner30ba6742009-08-10 19:03:04 +000028#include "llvm/MC/MCSectionMachO.h"
Benjamin Kramerdc2f0062010-01-09 18:20:57 +000029#include <algorithm>
Chris Lattner5ba61f02006-10-14 07:39:34 +000030using namespace clang;
31
Chris Lattner5ba61f02006-10-14 07:39:34 +000032//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000033// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000034//===----------------------------------------------------------------------===//
35
Chris Lattner1e1c0b92009-03-20 16:06:38 +000036/// DefineStd - Define a macro name and standard variants. For example if
37/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
38/// when in GNU mode.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000039static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
Chris Lattner1e1c0b92009-03-20 16:06:38 +000040 const LangOptions &Opts) {
41 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000042
Chris Lattner1e1c0b92009-03-20 16:06:38 +000043 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
44 // in the user's namespace.
45 if (Opts.GNUMode)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000046 Builder.defineMacro(MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000047
Chris Lattner1e1c0b92009-03-20 16:06:38 +000048 // Define __unix.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000049 Builder.defineMacro("__" + MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000050
Chris Lattner1e1c0b92009-03-20 16:06:38 +000051 // Define __unix__.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000052 Builder.defineMacro("__" + MacroName + "__");
Chris Lattner1e1c0b92009-03-20 16:06:38 +000053}
54
Chris Lattner09d98f52008-10-05 21:50:58 +000055//===----------------------------------------------------------------------===//
56// Defines specific to certain operating systems.
57//===----------------------------------------------------------------------===//
Chris Lattner30ba6742009-08-10 19:03:04 +000058
Torok Edwinb2b37c62009-06-30 17:10:35 +000059namespace {
Douglas Gregorc05d2a12009-07-01 15:12:53 +000060template<typename TgtInfo>
61class OSTargetInfo : public TgtInfo {
Torok Edwinb2b37c62009-06-30 17:10:35 +000062protected:
Daniel Dunbar40165182009-08-24 09:10:05 +000063 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000064 MacroBuilder &Builder) const=0;
Torok Edwinb2b37c62009-06-30 17:10:35 +000065public:
Douglas Gregorc05d2a12009-07-01 15:12:53 +000066 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwinb2b37c62009-06-30 17:10:35 +000067 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000068 MacroBuilder &Builder) const {
69 TgtInfo::getTargetDefines(Opts, Builder);
70 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
Torok Edwin4e054162009-06-30 17:00:25 +000071 }
Torok Edwinb2b37c62009-06-30 17:10:35 +000072
73};
Chris Lattner859c37a2009-08-12 06:24:27 +000074} // end anonymous namespace
Torok Edwin4e054162009-06-30 17:00:25 +000075
Chris Lattner30ba6742009-08-10 19:03:04 +000076
Daniel Dunbard86666f2010-01-26 01:44:04 +000077static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
78 const llvm::Triple &Triple) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000079 Builder.defineMacro("__APPLE_CC__", "5621");
80 Builder.defineMacro("__APPLE__");
81 Builder.defineMacro("__MACH__");
82 Builder.defineMacro("OBJC_NEW_PROPERTIES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000083
Chris Lattner2a5c0a32009-04-07 16:50:40 +000084 // __weak is always defined, for use in blocks and with objc pointers.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000085 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000086
Chris Lattner2a5c0a32009-04-07 16:50:40 +000087 // Darwin defines __strong even in C mode (just to nothing).
88 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000089 Builder.defineMacro("__strong", "");
Chris Lattner2a5c0a32009-04-07 16:50:40 +000090 else
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000091 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
Eli Friedmanfd4b1552009-06-04 23:00:29 +000092
93 if (Opts.Static)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000094 Builder.defineMacro("__STATIC__");
Eli Friedmanfd4b1552009-06-04 23:00:29 +000095 else
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000096 Builder.defineMacro("__DYNAMIC__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +000097
98 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000099 Builder.defineMacro("_REENTRANT");
Daniel Dunbar497ff132009-04-10 19:52:24 +0000100
Daniel Dunbard86666f2010-01-26 01:44:04 +0000101 // Get the OS version number from the triple.
Daniel Dunbar497ff132009-04-10 19:52:24 +0000102 unsigned Maj, Min, Rev;
Mike Stump11289f42009-09-09 15:08:12 +0000103
Daniel Dunbard86666f2010-01-26 01:44:04 +0000104 // If no version was given, default to to 10.4.0, for simplifying tests.
105 if (Triple.getOSName() == "darwin") {
106 Min = Rev = 0;
107 Maj = 8;
108 } else
109 Triple.getDarwinNumber(Maj, Min, Rev);
110
111 // Set the appropriate OS version define.
112 if (Triple.getEnvironmentName() == "iphoneos") {
113 assert(Maj < 10 && Min < 99 && Rev < 99 && "Invalid version!");
114 char Str[6];
115 Str[0] = '0' + Maj;
116 Str[1] = '0' + (Min / 10);
117 Str[2] = '0' + (Min % 10);
118 Str[3] = '0' + (Rev / 10);
119 Str[4] = '0' + (Rev % 10);
120 Str[5] = '\0';
121 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
122 } else {
123 // For historical reasons that make little sense, the version passed here is
124 // the "darwin" version, which drops the 10 and offsets by 4.
125 Rev = Min;
126 Min = Maj - 4;
127 Maj = 10;
128
129 assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
130 assert(Maj < 99 && Min < 10 && Rev < 10 && "Invalid version!");
131 char Str[5];
132 Str[0] = '0' + (Maj / 10);
133 Str[1] = '0' + (Maj % 10);
134 Str[2] = '0' + Min;
135 Str[3] = '0' + Rev;
136 Str[4] = '\0';
137 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
Daniel Dunbar497ff132009-04-10 19:52:24 +0000138 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000139}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000140
Chris Lattner30ba6742009-08-10 19:03:04 +0000141namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000142template<typename Target>
143class DarwinTargetInfo : public OSTargetInfo<Target> {
144protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000145 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000146 MacroBuilder &Builder) const {
Daniel Dunbard86666f2010-01-26 01:44:04 +0000147 getDarwinDefines(Builder, Opts, Triple);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000148 }
Mike Stump11289f42009-09-09 15:08:12 +0000149
Torok Edwinb2b37c62009-06-30 17:10:35 +0000150public:
151 DarwinTargetInfo(const std::string& triple) :
152 OSTargetInfo<Target>(triple) {
153 this->TLSSupported = false;
154 }
155
Anders Carlsson0b0a1222010-01-30 18:33:31 +0000156 virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
Chris Lattner30ba6742009-08-10 19:03:04 +0000157 // Let MCSectionMachO validate this.
158 llvm::StringRef Segment, Section;
159 unsigned TAA, StubSize;
160 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
161 TAA, StubSize);
162 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000163};
164
Chris Lattner30ba6742009-08-10 19:03:04 +0000165
Torok Edwinb2b37c62009-06-30 17:10:35 +0000166// DragonFlyBSD Target
167template<typename Target>
168class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
169protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000170 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000171 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000172 // DragonFly defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000173 Builder.defineMacro("__DragonFly__");
174 Builder.defineMacro("__DragonFly_cc_version", "100001");
175 Builder.defineMacro("__ELF__");
176 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
177 Builder.defineMacro("__tune_i386__");
178 DefineStd(Builder, "unix", Opts);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000179 }
180public:
Mike Stump11289f42009-09-09 15:08:12 +0000181 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000182 : OSTargetInfo<Target>(triple) {}
183};
184
185// FreeBSD Target
186template<typename Target>
187class FreeBSDTargetInfo : public OSTargetInfo<Target> {
188protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000189 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000190 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000191 // FreeBSD defines; list based off of gcc output
192
Daniel Dunbar40165182009-08-24 09:10:05 +0000193 // FIXME: Move version number handling to llvm::Triple.
Benjamin Kramer31a68e72010-01-30 19:55:01 +0000194 llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000195
Benjamin Kramer31a68e72010-01-30 19:55:01 +0000196 Builder.defineMacro("__FreeBSD__", Release);
197 Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000198 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
199 DefineStd(Builder, "unix", Opts);
200 Builder.defineMacro("__ELF__");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000201 }
202public:
Mike Stump11289f42009-09-09 15:08:12 +0000203 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands9cb27e92009-07-08 13:55:08 +0000204 : OSTargetInfo<Target>(triple) {
205 this->UserLabelPrefix = "";
206 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000207};
208
209// Linux target
210template<typename Target>
211class LinuxTargetInfo : public OSTargetInfo<Target> {
212protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000213 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000214 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000215 // Linux defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000216 DefineStd(Builder, "unix", Opts);
217 DefineStd(Builder, "linux", Opts);
218 Builder.defineMacro("__gnu_linux__");
219 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000220 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000221 Builder.defineMacro("_REENTRANT");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000222 }
223public:
Mike Stump11289f42009-09-09 15:08:12 +0000224 LinuxTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000225 : OSTargetInfo<Target>(triple) {
226 this->UserLabelPrefix = "";
227 }
228};
229
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000230// NetBSD Target
231template<typename Target>
232class NetBSDTargetInfo : public OSTargetInfo<Target> {
233protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000234 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000235 MacroBuilder &Builder) const {
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000236 // NetBSD defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000237 Builder.defineMacro("__NetBSD__");
238 Builder.defineMacro("__unix__");
239 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000240 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000241 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000242 }
243public:
Mike Stump11289f42009-09-09 15:08:12 +0000244 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000245 : OSTargetInfo<Target>(triple) {
246 this->UserLabelPrefix = "";
247 }
248};
249
Torok Edwinb2b37c62009-06-30 17:10:35 +0000250// OpenBSD Target
251template<typename Target>
252class OpenBSDTargetInfo : public OSTargetInfo<Target> {
253protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000254 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000255 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000256 // OpenBSD defines; list based off of gcc output
257
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000258 Builder.defineMacro("__OpenBSD__");
259 DefineStd(Builder, "unix", Opts);
260 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000261 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000262 Builder.defineMacro("_POSIX_THREADS");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000263 }
264public:
Mike Stump11289f42009-09-09 15:08:12 +0000265 OpenBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000266 : OSTargetInfo<Target>(triple) {}
267};
268
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000269// PSP Target
270template<typename Target>
271class PSPTargetInfo : public OSTargetInfo<Target> {
272protected:
273 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000274 MacroBuilder &Builder) const {
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000275 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000276 Builder.defineMacro("PSP");
277 Builder.defineMacro("_PSP");
278 Builder.defineMacro("__psp__");
279 Builder.defineMacro("__ELF__");
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000280 }
281public:
282 PSPTargetInfo(const std::string& triple)
283 : OSTargetInfo<Target>(triple) {
284 this->UserLabelPrefix = "";
285 }
286};
287
John Thompsone467e192009-11-19 17:18:50 +0000288// PS3 PPU Target
289template<typename Target>
290class PS3PPUTargetInfo : public OSTargetInfo<Target> {
291protected:
292 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000293 MacroBuilder &Builder) const {
John Thompsone467e192009-11-19 17:18:50 +0000294 // PS3 PPU defines.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000295 Builder.defineMacro("__PPU__");
296 Builder.defineMacro("__CELLOS_LV2__");
297 Builder.defineMacro("__ELF__");
298 Builder.defineMacro("__LP32__");
John Thompsone467e192009-11-19 17:18:50 +0000299 }
300public:
301 PS3PPUTargetInfo(const std::string& triple)
302 : OSTargetInfo<Target>(triple) {
303 this->UserLabelPrefix = "";
John Thompson6f8dba72009-12-18 14:21:08 +0000304 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
305 this->SizeType = TargetInfo::UnsignedInt;
John Thompsone467e192009-11-19 17:18:50 +0000306 }
307};
308
309// FIXME: Need a real SPU target.
310// PS3 SPU Target
311template<typename Target>
312class PS3SPUTargetInfo : public OSTargetInfo<Target> {
313protected:
314 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000315 MacroBuilder &Builder) const {
John Thompsone467e192009-11-19 17:18:50 +0000316 // PS3 PPU defines.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000317 Builder.defineMacro("__SPU__");
318 Builder.defineMacro("__ELF__");
John Thompsone467e192009-11-19 17:18:50 +0000319 }
320public:
321 PS3SPUTargetInfo(const std::string& triple)
322 : OSTargetInfo<Target>(triple) {
323 this->UserLabelPrefix = "";
324 }
325};
326
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000327// AuroraUX target
328template<typename Target>
329class AuroraUXTargetInfo : public OSTargetInfo<Target> {
330protected:
331 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000332 MacroBuilder &Builder) const {
333 DefineStd(Builder, "sun", Opts);
334 DefineStd(Builder, "unix", Opts);
335 Builder.defineMacro("__ELF__");
336 Builder.defineMacro("__svr4__");
337 Builder.defineMacro("__SVR4");
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000338 }
339public:
340 AuroraUXTargetInfo(const std::string& triple)
341 : OSTargetInfo<Target>(triple) {
342 this->UserLabelPrefix = "";
343 this->WCharType = this->SignedLong;
344 // FIXME: WIntType should be SignedLong
345 }
346};
347
Torok Edwinb2b37c62009-06-30 17:10:35 +0000348// Solaris target
349template<typename Target>
350class SolarisTargetInfo : public OSTargetInfo<Target> {
351protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000352 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000353 MacroBuilder &Builder) const {
354 DefineStd(Builder, "sun", Opts);
355 DefineStd(Builder, "unix", Opts);
356 Builder.defineMacro("__ELF__");
357 Builder.defineMacro("__svr4__");
358 Builder.defineMacro("__SVR4");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000359 }
360public:
Mike Stump11289f42009-09-09 15:08:12 +0000361 SolarisTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000362 : OSTargetInfo<Target>(triple) {
363 this->UserLabelPrefix = "";
364 this->WCharType = this->SignedLong;
365 // FIXME: WIntType should be SignedLong
366 }
367};
Mike Stump11289f42009-09-09 15:08:12 +0000368} // end anonymous namespace.
Torok Edwinb2b37c62009-06-30 17:10:35 +0000369
Chris Lattner09d98f52008-10-05 21:50:58 +0000370//===----------------------------------------------------------------------===//
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000371// Specific target implementations.
372//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000373
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000374namespace {
375// PPC abstract base class
376class PPCTargetInfo : public TargetInfo {
377 static const Builtin::Info BuiltinInfo[];
378 static const char * const GCCRegNames[];
379 static const TargetInfo::GCCRegAlias GCCRegAliases[];
380
381public:
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000382 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
383
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000384 virtual void getTargetBuiltins(const Builtin::Info *&Records,
385 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000386 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000387 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000388 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000389
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000390 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000391 MacroBuilder &Builder) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000392
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000393 virtual const char *getVAListDeclaration() const {
Chris Lattner69f9bc22008-10-27 01:11:29 +0000394 return "typedef char* __builtin_va_list;";
395 // This is the right definition for ABI/V4: System V.4/eabi.
396 /*return "typedef struct __va_list_tag {"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000397 " unsigned char gpr;"
398 " unsigned char fpr;"
399 " unsigned short reserved;"
400 " void* overflow_arg_area;"
401 " void* reg_save_area;"
Chris Lattner69f9bc22008-10-27 01:11:29 +0000402 "} __builtin_va_list[1];";*/
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000403 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000404 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000405 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000406 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000407 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000408 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000409 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000410 switch (*Name) {
Anders Carlssonf511f642007-11-27 04:11:28 +0000411 default: return false;
412 case 'O': // Zero
413 return true;
414 case 'b': // Base register
415 case 'f': // Floating point register
Chris Lattnerd9725f72009-04-26 07:16:29 +0000416 Info.setAllowsRegister();
Anders Carlssonf511f642007-11-27 04:11:28 +0000417 return true;
418 }
419 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000420 virtual const char *getClobbers() const {
421 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000422 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000423};
Anders Carlssonf511f642007-11-27 04:11:28 +0000424
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000425const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000426#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
427#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000428#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000429};
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000430
431
Chris Lattnerecd49032009-03-02 22:27:17 +0000432/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
433/// #defines that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000434void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000435 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000436 // Target identification.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000437 Builder.defineMacro("__ppc__");
438 Builder.defineMacro("_ARCH_PPC");
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000439 Builder.defineMacro("__powerpc__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000440 Builder.defineMacro("__POWERPC__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000441 if (PointerWidth == 64) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000442 Builder.defineMacro("_ARCH_PPC64");
443 Builder.defineMacro("_LP64");
444 Builder.defineMacro("__LP64__");
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000445 Builder.defineMacro("__powerpc64__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000446 Builder.defineMacro("__ppc64__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000447 } else {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000448 Builder.defineMacro("__ppc__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000449 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000450
Chris Lattnerecd49032009-03-02 22:27:17 +0000451 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000452 Builder.defineMacro("_BIG_ENDIAN");
453 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000454
Chris Lattnerecd49032009-03-02 22:27:17 +0000455 // Subtarget options.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000456 Builder.defineMacro("__NATURAL_ALIGNMENT__");
457 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000458
Chris Lattnerecd49032009-03-02 22:27:17 +0000459 // FIXME: Should be controlled by command line option.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000460 Builder.defineMacro("__LONG_DOUBLE_128__");
John Thompsone467e192009-11-19 17:18:50 +0000461
462 if (Opts.AltiVec) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000463 Builder.defineMacro("__VEC__", "10206");
464 Builder.defineMacro("__ALTIVEC__");
John Thompsone467e192009-11-19 17:18:50 +0000465 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000466}
467
Chris Lattner17df24e2008-04-21 18:56:49 +0000468
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000469const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000470 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
471 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
472 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
473 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
474 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
475 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
476 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
477 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000478 "mq", "lr", "ctr", "ap",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000479 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000480 "xer",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000481 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
482 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
483 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
484 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000485 "vrsave", "vscr",
486 "spe_acc", "spefscr",
487 "sfp"
488};
Chris Lattner10a5b382007-01-29 05:24:35 +0000489
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000490void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000491 unsigned &NumNames) const {
492 Names = GCCRegNames;
493 NumNames = llvm::array_lengthof(GCCRegNames);
494}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000495
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000496const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
497 // While some of these aliases do map to different registers
498 // they still share the same register name.
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000499 { { "0" }, "r0" },
500 { { "1"}, "r1" },
501 { { "2" }, "r2" },
502 { { "3" }, "r3" },
503 { { "4" }, "r4" },
504 { { "5" }, "r5" },
505 { { "6" }, "r6" },
506 { { "7" }, "r7" },
507 { { "8" }, "r8" },
508 { { "9" }, "r9" },
509 { { "10" }, "r10" },
510 { { "11" }, "r11" },
511 { { "12" }, "r12" },
512 { { "13" }, "r13" },
513 { { "14" }, "r14" },
514 { { "15" }, "r15" },
515 { { "16" }, "r16" },
516 { { "17" }, "r17" },
517 { { "18" }, "r18" },
518 { { "19" }, "r19" },
519 { { "20" }, "r20" },
520 { { "21" }, "r21" },
521 { { "22" }, "r22" },
522 { { "23" }, "r23" },
523 { { "24" }, "r24" },
524 { { "25" }, "r25" },
525 { { "26" }, "r26" },
526 { { "27" }, "r27" },
527 { { "28" }, "r28" },
528 { { "29" }, "r29" },
529 { { "30" }, "r30" },
530 { { "31" }, "r31" },
531 { { "fr0" }, "f0" },
532 { { "fr1" }, "f1" },
533 { { "fr2" }, "f2" },
534 { { "fr3" }, "f3" },
535 { { "fr4" }, "f4" },
536 { { "fr5" }, "f5" },
537 { { "fr6" }, "f6" },
538 { { "fr7" }, "f7" },
539 { { "fr8" }, "f8" },
540 { { "fr9" }, "f9" },
Mike Stumpfaacf012009-09-17 21:15:00 +0000541 { { "fr10" }, "f10" },
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000542 { { "fr11" }, "f11" },
543 { { "fr12" }, "f12" },
544 { { "fr13" }, "f13" },
545 { { "fr14" }, "f14" },
546 { { "fr15" }, "f15" },
547 { { "fr16" }, "f16" },
548 { { "fr17" }, "f17" },
549 { { "fr18" }, "f18" },
550 { { "fr19" }, "f19" },
551 { { "fr20" }, "f20" },
552 { { "fr21" }, "f21" },
553 { { "fr22" }, "f22" },
554 { { "fr23" }, "f23" },
555 { { "fr24" }, "f24" },
556 { { "fr25" }, "f25" },
557 { { "fr26" }, "f26" },
558 { { "fr27" }, "f27" },
559 { { "fr28" }, "f28" },
560 { { "fr29" }, "f29" },
561 { { "fr30" }, "f30" },
562 { { "fr31" }, "f31" },
563 { { "cc" }, "cr0" },
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000564};
565
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000566void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000567 unsigned &NumAliases) const {
568 Aliases = GCCRegAliases;
569 NumAliases = llvm::array_lengthof(GCCRegAliases);
570}
571} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000572
Chris Lattner5ba61f02006-10-14 07:39:34 +0000573namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000574class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000575public:
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000576 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedman873f65a2008-08-21 00:13:15 +0000577 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000578 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000579
580 if (getTriple().getOS() == llvm::Triple::FreeBSD)
581 this->SizeType = TargetInfo::UnsignedInt;
Eli Friedman873f65a2008-08-21 00:13:15 +0000582 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000583};
584} // end anonymous namespace.
585
586namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000587class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000588public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000589 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000590 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2857ccb2009-07-01 03:36:11 +0000591 IntMaxType = SignedLong;
592 UIntMaxType = UnsignedLong;
593 Int64Type = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000594 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000595 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000596 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000597};
598} // end anonymous namespace.
599
Chris Lattner5ba61f02006-10-14 07:39:34 +0000600namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000601// Namespace for x86 abstract base class
602const Builtin::Info BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000603#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
604#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000605#include "clang/Basic/BuiltinsX86.def"
Eli Friedman3fd920a2008-08-20 02:34:37 +0000606};
Eli Friedmanb5366062008-05-20 14:21:01 +0000607
Nuno Lopescfca1f02009-12-23 17:49:57 +0000608static const char* const GCCRegNames[] = {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000609 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
610 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
611 "argp", "flags", "fspr", "dirflag", "frame",
612 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
613 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
614 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
615 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
616};
617
618const TargetInfo::GCCRegAlias GCCRegAliases[] = {
619 { { "al", "ah", "eax", "rax" }, "ax" },
620 { { "bl", "bh", "ebx", "rbx" }, "bx" },
621 { { "cl", "ch", "ecx", "rcx" }, "cx" },
622 { { "dl", "dh", "edx", "rdx" }, "dx" },
623 { { "esi", "rsi" }, "si" },
624 { { "edi", "rdi" }, "di" },
625 { { "esp", "rsp" }, "sp" },
626 { { "ebp", "rbp" }, "bp" },
627};
628
629// X86 target abstract base class; x86-32 and x86-64 are very close, so
630// most of the implementation can be shared.
631class X86TargetInfo : public TargetInfo {
Chris Lattner96e43572009-03-02 22:40:39 +0000632 enum X86SSEEnum {
633 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
634 } SSELevel;
Anders Carlssone437c682010-01-27 03:47:49 +0000635 enum AMD3DNowEnum {
636 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
637 } AMD3DNowLevel;
638
Eli Friedman3fd920a2008-08-20 02:34:37 +0000639public:
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000640 X86TargetInfo(const std::string& triple)
Anders Carlssone437c682010-01-27 03:47:49 +0000641 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000642 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +0000643 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000644 virtual void getTargetBuiltins(const Builtin::Info *&Records,
645 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000646 Records = BuiltinInfo;
647 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000648 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000649 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000650 unsigned &NumNames) const {
651 Names = GCCRegNames;
652 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000653 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000654 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000655 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000656 Aliases = GCCRegAliases;
657 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +0000658 }
Anders Carlsson58436352009-02-28 17:11:49 +0000659 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000660 TargetInfo::ConstraintInfo &info) const;
661 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +0000662 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000663 return "~{dirflag},~{fpsr},~{flags}";
664 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000665 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000666 MacroBuilder &Builder) const;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000667 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
668 const std::string &Name,
669 bool Enabled) const;
Mike Stump11289f42009-09-09 15:08:12 +0000670 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000671 llvm::StringMap<bool> &Features) const;
Daniel Dunbar7b245ed2009-12-19 03:30:57 +0000672 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Chris Lattner5ba61f02006-10-14 07:39:34 +0000673};
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000674
Mike Stump11289f42009-09-09 15:08:12 +0000675void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000676 llvm::StringMap<bool> &Features) const {
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000677 // FIXME: This should not be here.
678 Features["3dnow"] = false;
679 Features["3dnowa"] = false;
680 Features["mmx"] = false;
681 Features["sse"] = false;
682 Features["sse2"] = false;
683 Features["sse3"] = false;
684 Features["ssse3"] = false;
685 Features["sse41"] = false;
686 Features["sse42"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000687
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000688 // LLVM does not currently recognize this.
689 // Features["sse4a"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000690
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000691 // FIXME: This *really* should not be here.
692
693 // X86_64 always has SSE2.
694 if (PointerWidth == 64)
695 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
696
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000697 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
698 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
699 ;
700 else if (CPU == "pentium-mmx" || CPU == "pentium2")
701 setFeatureEnabled(Features, "mmx", true);
702 else if (CPU == "pentium3")
703 setFeatureEnabled(Features, "sse", true);
704 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
705 setFeatureEnabled(Features, "sse2", true);
706 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
707 setFeatureEnabled(Features, "sse3", true);
708 else if (CPU == "core2")
709 setFeatureEnabled(Features, "ssse3", true);
710 else if (CPU == "penryn") {
711 setFeatureEnabled(Features, "sse4", true);
712 Features["sse42"] = false;
713 } else if (CPU == "atom")
714 setFeatureEnabled(Features, "sse3", true);
715 else if (CPU == "corei7")
716 setFeatureEnabled(Features, "sse4", true);
717 else if (CPU == "k6" || CPU == "winchip-c6")
718 setFeatureEnabled(Features, "mmx", true);
Mike Stump11289f42009-09-09 15:08:12 +0000719 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000720 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
721 setFeatureEnabled(Features, "mmx", true);
722 setFeatureEnabled(Features, "3dnow", true);
723 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
724 setFeatureEnabled(Features, "sse", true);
725 setFeatureEnabled(Features, "3dnowa", true);
726 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
727 CPU == "athlon-fx") {
Mike Stump11289f42009-09-09 15:08:12 +0000728 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000729 setFeatureEnabled(Features, "3dnowa", true);
730 } else if (CPU == "c3-2")
731 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000732}
733
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000734bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump11289f42009-09-09 15:08:12 +0000735 const std::string &Name,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000736 bool Enabled) const {
Eric Christopher399ffa52010-03-04 02:26:37 +0000737 // FIXME: This *really* should not be here. We need some way of translating
738 // options into llvm subtarget features.
739 if (!Features.count(Name) &&
740 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000741 return false;
742
743 if (Enabled) {
744 if (Name == "mmx")
745 Features["mmx"] = true;
746 else if (Name == "sse")
747 Features["mmx"] = Features["sse"] = true;
748 else if (Name == "sse2")
749 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
750 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000751 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000752 Features["sse3"] = true;
753 else if (Name == "ssse3")
Mike Stump11289f42009-09-09 15:08:12 +0000754 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000755 Features["ssse3"] = true;
Eric Christopher399ffa52010-03-04 02:26:37 +0000756 else if (Name == "sse4" || Name == "sse4.2")
Mike Stump11289f42009-09-09 15:08:12 +0000757 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000758 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopher399ffa52010-03-04 02:26:37 +0000759 else if (Name == "sse4.1")
760 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
761 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000762 else if (Name == "3dnow")
763 Features["3dnowa"] = true;
764 else if (Name == "3dnowa")
765 Features["3dnow"] = Features["3dnowa"] = true;
766 } else {
767 if (Name == "mmx")
Mike Stump11289f42009-09-09 15:08:12 +0000768 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000769 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
770 else if (Name == "sse")
Mike Stump11289f42009-09-09 15:08:12 +0000771 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000772 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
773 else if (Name == "sse2")
Mike Stump11289f42009-09-09 15:08:12 +0000774 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000775 Features["sse41"] = Features["sse42"] = false;
776 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000777 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000778 Features["sse42"] = false;
779 else if (Name == "ssse3")
780 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
781 else if (Name == "sse4")
782 Features["sse41"] = Features["sse42"] = false;
Eric Christophercfeceff2010-03-04 02:31:44 +0000783 else if (Name == "sse4.2")
784 Features["sse42"] = false;
785 else if (Name == "sse4.1")
786 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000787 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 Dunbar4dbaaa62009-05-06 03:16:41 +0000796/// HandleTargetOptions - Perform initialization based on the user
797/// configured set of features.
Daniel Dunbar7b245ed2009-12-19 03:30:57 +0000798void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar979586e2009-11-11 09:38:56 +0000799 // Remember the maximum enabled sselevel.
800 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
801 // Ignore disabled features.
802 if (Features[i][0] == '-')
803 continue;
804
805 assert(Features[i][0] == '+' && "Invalid target feature!");
806 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
807 .Case("sse42", SSE42)
808 .Case("sse41", SSE41)
809 .Case("ssse3", SSSE3)
810 .Case("sse2", SSE2)
811 .Case("sse", SSE1)
812 .Case("mmx", MMX)
813 .Default(NoMMXSSE);
814 SSELevel = std::max(SSELevel, Level);
Anders Carlssone437c682010-01-27 03:47:49 +0000815
816 AMD3DNowEnum ThreeDNowLevel =
817 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
818 .Case("3dnowa", AMD3DNowAthlon)
819 .Case("3dnow", AMD3DNow)
820 .Default(NoAMD3DNow);
821
822 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar979586e2009-11-11 09:38:56 +0000823 }
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000824}
Chris Lattnerecd49032009-03-02 22:27:17 +0000825
826/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
827/// that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000828void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000829 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000830 // Target identification.
831 if (PointerWidth == 64) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000832 Builder.defineMacro("_LP64");
833 Builder.defineMacro("__LP64__");
834 Builder.defineMacro("__amd64__");
835 Builder.defineMacro("__amd64");
836 Builder.defineMacro("__x86_64");
837 Builder.defineMacro("__x86_64__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000838 } else {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000839 DefineStd(Builder, "i386", Opts);
Chris Lattnerecd49032009-03-02 22:27:17 +0000840 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000841
Chris Lattnerecd49032009-03-02 22:27:17 +0000842 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000843 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000844
Chris Lattnerecd49032009-03-02 22:27:17 +0000845 // Subtarget options.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000846 Builder.defineMacro("__nocona");
847 Builder.defineMacro("__nocona__");
848 Builder.defineMacro("__tune_nocona__");
849 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner96e43572009-03-02 22:40:39 +0000850
Chris Lattner6df41af2009-04-19 17:32:33 +0000851 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
852 // functions in glibc header files that use FP Stack inline asm which the
853 // backend can't deal with (PR879).
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000854 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000855
Chris Lattner96e43572009-03-02 22:40:39 +0000856 // Each case falls through to the previous one here.
857 switch (SSELevel) {
858 case SSE42:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000859 Builder.defineMacro("__SSE4_2__");
Chris Lattner96e43572009-03-02 22:40:39 +0000860 case SSE41:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000861 Builder.defineMacro("__SSE4_1__");
Chris Lattner96e43572009-03-02 22:40:39 +0000862 case SSSE3:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000863 Builder.defineMacro("__SSSE3__");
Chris Lattner96e43572009-03-02 22:40:39 +0000864 case SSE3:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000865 Builder.defineMacro("__SSE3__");
Chris Lattner96e43572009-03-02 22:40:39 +0000866 case SSE2:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000867 Builder.defineMacro("__SSE2__");
868 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner96e43572009-03-02 22:40:39 +0000869 case SSE1:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000870 Builder.defineMacro("__SSE__");
871 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner96e43572009-03-02 22:40:39 +0000872 case MMX:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000873 Builder.defineMacro("__MMX__");
Chris Lattner96e43572009-03-02 22:40:39 +0000874 case NoMMXSSE:
875 break;
876 }
Anders Carlssone437c682010-01-27 03:47:49 +0000877
878 // Each case falls through to the previous one here.
879 switch (AMD3DNowLevel) {
880 case AMD3DNowAthlon:
881 Builder.defineMacro("__3dNOW_A__");
882 case AMD3DNow:
883 Builder.defineMacro("__3dNOW__");
884 case NoAMD3DNow:
885 break;
886 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000887}
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000888
889
Eli Friedman3fd920a2008-08-20 02:34:37 +0000890bool
Anders Carlsson58436352009-02-28 17:11:49 +0000891X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000892 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000893 switch (*Name) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000894 default: return false;
895 case 'a': // eax.
896 case 'b': // ebx.
897 case 'c': // ecx.
898 case 'd': // edx.
899 case 'S': // esi.
900 case 'D': // edi.
901 case 'A': // edx:eax.
902 case 't': // top of floating point stack.
903 case 'u': // second from top of floating point stack.
904 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +0000905 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +0000906 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000907 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000908 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000909 // x86_64 instructions.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000910 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000911 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000912 case 'N': // unsigned 8-bit integer constant for use with in and out
913 // instructions.
Eli Friedmancf432d32009-06-08 20:45:44 +0000914 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
Chris Lattnerd9725f72009-04-26 07:16:29 +0000915 Info.setAllowsRegister();
Eli Friedman3fd920a2008-08-20 02:34:37 +0000916 return true;
917 }
918}
919
920std::string
921X86TargetInfo::convertConstraint(const char Constraint) const {
922 switch (Constraint) {
923 case 'a': return std::string("{ax}");
924 case 'b': return std::string("{bx}");
925 case 'c': return std::string("{cx}");
926 case 'd': return std::string("{dx}");
927 case 'S': return std::string("{si}");
928 case 'D': return std::string("{di}");
929 case 't': // top of floating point stack.
930 return std::string("{st}");
931 case 'u': // second from top of floating point stack.
932 return std::string("{st(1)}"); // second from top of floating point stack.
933 default:
934 return std::string(1, Constraint);
935 }
936}
Eli Friedman3fd920a2008-08-20 02:34:37 +0000937} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +0000938
939namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000940// X86-32 generic target
941class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000942public:
Eli Friedman3fd920a2008-08-20 02:34:37 +0000943 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
944 DoubleAlign = LongLongAlign = 32;
945 LongDoubleWidth = 96;
946 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +0000947 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
948 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000949 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman32ca82a2009-03-29 20:31:09 +0000950 SizeType = UnsignedInt;
951 PtrDiffType = SignedInt;
952 IntPtrType = SignedInt;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +0000953 RegParmMax = 3;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000954 }
955 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000956 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000957 }
Chris Lattnerd545ad12009-09-23 06:06:36 +0000958
959 int getEHDataRegisterNumber(unsigned RegNo) const {
960 if (RegNo == 0) return 0;
961 if (RegNo == 1) return 2;
962 return -1;
963 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000964};
965} // end anonymous namespace
966
967namespace {
Eli Friedmane3aa4542009-07-05 18:47:56 +0000968class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
969public:
970 OpenBSDI386TargetInfo(const std::string& triple) :
971 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
972 SizeType = UnsignedLong;
973 IntPtrType = SignedLong;
Eli Friedman245f2292009-07-05 22:31:18 +0000974 PtrDiffType = SignedLong;
Eli Friedmane3aa4542009-07-05 18:47:56 +0000975 }
976};
977} // end anonymous namespace
978
979namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000980class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000981public:
Torok Edwinb2b37c62009-06-30 17:10:35 +0000982 DarwinI386TargetInfo(const std::string& triple) :
983 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000984 LongDoubleWidth = 128;
985 LongDoubleAlign = 128;
Eli Friedman32ca82a2009-03-29 20:31:09 +0000986 SizeType = UnsignedLong;
987 IntPtrType = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000988 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
989 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000990 "a0:0:64-f80:128:128-n8:16:32";
Torok Edwin4e054162009-06-30 17:00:25 +0000991 }
992
Eli Friedman3fd920a2008-08-20 02:34:37 +0000993};
Daniel Dunbar10de9e62009-06-29 20:52:51 +0000994} // end anonymous namespace
995
996namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000997// x86-32 Windows target
998class WindowsX86_32TargetInfo : public X86_32TargetInfo {
999public:
1000 WindowsX86_32TargetInfo(const std::string& triple)
1001 : X86_32TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +00001002 TLSSupported = false;
Chris Lattner46be2e12009-06-24 17:12:15 +00001003 WCharType = UnsignedShort;
Eli Friedmanebb9e4d2009-06-08 21:16:17 +00001004 DoubleAlign = LongLongAlign = 64;
1005 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Anton Korobeynikovd7e4a092009-12-19 02:05:07 +00001006 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1007 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001008 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001009 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001010 MacroBuilder &Builder) const {
1011 X86_32TargetInfo::getTargetDefines(Opts, Builder);
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001012 // This list is based off of the the list of things MingW defines
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001013 Builder.defineMacro("_WIN32");
1014 DefineStd(Builder, "WIN32", Opts);
1015 DefineStd(Builder, "WINNT", Opts);
1016 Builder.defineMacro("_X86_");
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001017 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001018};
1019} // end anonymous namespace
Eli Friedmanaa27a872009-06-08 06:11:14 +00001020
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001021namespace {
1022
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001023// x86-32 Windows Visual Studio target
1024class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1025public:
1026 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1027 : WindowsX86_32TargetInfo(triple) {
1028 }
1029 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001030 MacroBuilder &Builder) const {
1031 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001032 // The value of the following reflects processor type.
1033 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1034 // We lost the original triple, so we use the default.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001035 Builder.defineMacro("_M_IX86", "600");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001036 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001037};
1038} // end anonymous namespace
1039
1040namespace {
1041// x86-32 MinGW target
1042class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1043public:
1044 MinGWX86_32TargetInfo(const std::string& triple)
1045 : WindowsX86_32TargetInfo(triple) {
1046 }
1047 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001048 MacroBuilder &Builder) const {
1049 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1050 Builder.defineMacro("__MSVCRT__");
1051 Builder.defineMacro("__MINGW32__");
1052 Builder.defineMacro("__declspec", "__declspec");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001053 }
1054};
1055} // end anonymous namespace
1056
1057namespace {
1058// x86-32 Cygwin target
1059class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1060public:
1061 CygwinX86_32TargetInfo(const std::string& triple)
1062 : X86_32TargetInfo(triple) {
1063 TLSSupported = false;
1064 WCharType = UnsignedShort;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001065 DoubleAlign = LongLongAlign = 64;
1066 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1067 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001068 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001069 }
1070 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001071 MacroBuilder &Builder) const {
1072 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1073 Builder.defineMacro("__CYGWIN__");
1074 Builder.defineMacro("__CYGWIN32__");
1075 DefineStd(Builder, "unix", Opts);
Eli Friedmanaa27a872009-06-08 06:11:14 +00001076 }
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001077};
1078} // end anonymous namespace
1079
1080namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001081// x86-64 generic target
1082class X86_64TargetInfo : public X86TargetInfo {
1083public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001084 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +00001085 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +00001086 LongDoubleWidth = 128;
1087 LongDoubleAlign = 128;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001088 IntMaxType = SignedLong;
1089 UIntMaxType = UnsignedLong;
Eli Friedman2857ccb2009-07-01 03:36:11 +00001090 Int64Type = SignedLong;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001091 RegParmMax = 6;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001092
Eli Friedman873f65a2008-08-21 00:13:15 +00001093 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1094 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001095 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Chris Lattner10a5b382007-01-29 05:24:35 +00001096 }
Anders Carlssona7408e72007-10-13 00:45:48 +00001097 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001098 return "typedef struct __va_list_tag {"
1099 " unsigned gp_offset;"
1100 " unsigned fp_offset;"
1101 " void* overflow_arg_area;"
1102 " void* reg_save_area;"
Eli Friedmanfb36b022009-07-03 00:45:06 +00001103 "} __va_list_tag;"
1104 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001105 }
Chris Lattnerd545ad12009-09-23 06:06:36 +00001106
1107 int getEHDataRegisterNumber(unsigned RegNo) const {
1108 if (RegNo == 0) return 0;
1109 if (RegNo == 1) return 1;
1110 return -1;
1111 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001112};
1113} // end anonymous namespace
1114
1115namespace {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001116// x86-64 Windows target
1117class WindowsX86_64TargetInfo : public X86_64TargetInfo {
1118public:
1119 WindowsX86_64TargetInfo(const std::string& triple)
1120 : X86_64TargetInfo(triple) {
1121 TLSSupported = false;
1122 WCharType = UnsignedShort;
Mike Stumpaf9afe92009-10-08 23:00:00 +00001123 LongWidth = LongAlign = 32;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001124 DoubleAlign = LongLongAlign = 64;
1125 }
1126 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001127 MacroBuilder &Builder) const {
1128 X86_64TargetInfo::getTargetDefines(Opts, Builder);
1129 Builder.defineMacro("_WIN64");
1130 DefineStd(Builder, "WIN64", Opts);
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001131 }
1132};
1133} // end anonymous namespace
1134
1135namespace {
1136// x86-64 Windows Visual Studio target
1137class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1138public:
1139 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1140 : WindowsX86_64TargetInfo(triple) {
1141 }
1142 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001143 MacroBuilder &Builder) const {
1144 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1145 Builder.defineMacro("_M_X64");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001146 }
1147 virtual const char *getVAListDeclaration() const {
1148 return "typedef char* va_list;";
1149 }
1150};
1151} // end anonymous namespace
1152
1153namespace {
1154// x86-64 MinGW target
1155class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1156public:
1157 MinGWX86_64TargetInfo(const std::string& triple)
1158 : WindowsX86_64TargetInfo(triple) {
1159 }
1160 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001161 MacroBuilder &Builder) const {
1162 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1163 Builder.defineMacro("__MSVCRT__");
1164 Builder.defineMacro("__MINGW64__");
1165 Builder.defineMacro("__declspec");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001166 }
1167};
1168} // end anonymous namespace
1169
1170namespace {
Eli Friedman2857ccb2009-07-01 03:36:11 +00001171class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1172public:
Mike Stump11289f42009-09-09 15:08:12 +00001173 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman2857ccb2009-07-01 03:36:11 +00001174 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1175 Int64Type = SignedLongLong;
1176 }
1177};
1178} // end anonymous namespace
1179
1180namespace {
Eli Friedman245f2292009-07-05 22:31:18 +00001181class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1182public:
Mike Stump11289f42009-09-09 15:08:12 +00001183 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman245f2292009-07-05 22:31:18 +00001184 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1185 IntMaxType = SignedLongLong;
1186 UIntMaxType = UnsignedLongLong;
1187 Int64Type = SignedLongLong;
1188 }
1189};
1190} // end anonymous namespace
1191
1192namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001193class ARMTargetInfo : public TargetInfo {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001194 // Possible FPU choices.
1195 enum FPUMode {
1196 NoFPU,
1197 VFP2FPU,
1198 VFP3FPU,
1199 NeonFPU
1200 };
1201
1202 static bool FPUModeIsVFP(FPUMode Mode) {
1203 return Mode >= VFP2FPU && Mode <= NeonFPU;
1204 }
1205
1206 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1207 static const char * const GCCRegNames[];
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001208
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001209 std::string ABI, CPU;
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001210
1211 unsigned FPU : 3;
1212
Daniel Dunbar893d4752009-12-19 04:15:38 +00001213 unsigned IsThumb : 1;
1214
1215 // Initialized via features.
1216 unsigned SoftFloat : 1;
1217 unsigned SoftFloatABI : 1;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001218
Chris Lattner5cc15e02010-03-03 19:03:45 +00001219 static const Builtin::Info BuiltinInfo[];
1220
Chris Lattner17df24e2008-04-21 18:56:49 +00001221public:
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001222 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001223 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001224 {
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001225 SizeType = UnsignedInt;
1226 PtrDiffType = SignedInt;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001227
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001228 // FIXME: Should we just treat this as a feature?
Daniel Dunbarc454ecf2009-12-18 19:57:13 +00001229 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbar03184792009-09-22 21:44:58 +00001230 if (IsThumb) {
1231 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1232 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001233 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001234 } else {
1235 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1236 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001237 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001238 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001239 }
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001240 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001241 virtual bool setABI(const std::string &Name) {
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001242 ABI = Name;
1243
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001244 // The defaults (above) are for AAPCS, check if we need to change them.
1245 //
1246 // FIXME: We need support for -meabi... we could just mangle it into the
1247 // name.
1248 if (Name == "apcs-gnu") {
Daniel Dunbar377dc2f2010-01-27 20:23:08 +00001249 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001250 SizeType = UnsignedLong;
1251
Daniel Dunbar03184792009-09-22 21:44:58 +00001252 if (IsThumb) {
1253 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1254 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001255 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001256 } else {
1257 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1258 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001259 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001260 }
1261
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001262 // FIXME: Override "preferred align" for double and long long.
1263 } else if (Name == "aapcs") {
1264 // FIXME: Enumerated types are variable width in straight AAPCS.
1265 } else if (Name == "aapcs-linux") {
1266 ;
1267 } else
1268 return false;
1269
1270 return true;
1271 }
Daniel Dunbar893d4752009-12-19 04:15:38 +00001272
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001273 void getDefaultFeatures(const std::string &CPU,
1274 llvm::StringMap<bool> &Features) const {
1275 // FIXME: This should not be here.
1276 Features["vfp2"] = false;
1277 Features["vfp3"] = false;
1278 Features["neon"] = false;
1279
1280 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1281 Features["vfp2"] = true;
1282 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1283 Features["neon"] = true;
1284 }
1285
Daniel Dunbar893d4752009-12-19 04:15:38 +00001286 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1287 const std::string &Name,
1288 bool Enabled) const {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001289 if (Name == "soft-float" || Name == "soft-float-abi") {
1290 Features[Name] = Enabled;
1291 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1292 // These effectively are a single option, reset them when any is enabled.
1293 if (Enabled)
1294 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1295 Features[Name] = Enabled;
1296 } else
Daniel Dunbar893d4752009-12-19 04:15:38 +00001297 return false;
1298
Daniel Dunbar893d4752009-12-19 04:15:38 +00001299 return true;
1300 }
1301
1302 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001303 FPU = NoFPU;
Daniel Dunbar893d4752009-12-19 04:15:38 +00001304 SoftFloat = SoftFloatABI = false;
1305 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1306 if (Features[i] == "+soft-float")
1307 SoftFloat = true;
1308 else if (Features[i] == "+soft-float-abi")
1309 SoftFloatABI = true;
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001310 else if (Features[i] == "+vfp2")
1311 FPU = VFP2FPU;
1312 else if (Features[i] == "+vfp3")
1313 FPU = VFP3FPU;
1314 else if (Features[i] == "+neon")
1315 FPU = NeonFPU;
Daniel Dunbar893d4752009-12-19 04:15:38 +00001316 }
1317
1318 // Remove front-end specific options which the backend handles differently.
1319 std::vector<std::string>::iterator it;
1320 it = std::find(Features.begin(), Features.end(), "+soft-float");
1321 if (it != Features.end())
1322 Features.erase(it);
1323 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1324 if (it != Features.end())
1325 Features.erase(it);
1326 }
1327
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001328 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1329 return llvm::StringSwitch<const char*>(Name)
1330 .Cases("arm8", "arm810", "4")
1331 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1332 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1333 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1334 .Case("ep9312", "4T")
1335 .Cases("arm10tdmi", "arm1020t", "5T")
1336 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1337 .Case("arm926ej-s", "5TEJ")
1338 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1339 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001340 .Case("arm1136j-s", "6J")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001341 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001342 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001343 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1344 .Cases("cortex-a8", "cortex-a9", "7A")
1345 .Default(0);
1346 }
1347 virtual bool setCPU(const std::string &Name) {
1348 if (!getCPUDefineSuffix(Name))
1349 return false;
1350
1351 CPU = Name;
1352 return true;
1353 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001354 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001355 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001356 // Target identification.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001357 Builder.defineMacro("__arm");
1358 Builder.defineMacro("__arm__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001359
Chris Lattnerecd49032009-03-02 22:27:17 +00001360 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001361 Builder.defineMacro("__ARMEL__");
1362 Builder.defineMacro("__LITTLE_ENDIAN__");
1363 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001364
1365 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001366 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001367
Mike Stump9d54bd72009-04-08 02:07:04 +00001368 // Subtarget options.
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001369
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001370 // FIXME: It's more complicated than this and we don't really support
1371 // interworking.
1372 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001373 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001374
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001375 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001376 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001377
Daniel Dunbar893d4752009-12-19 04:15:38 +00001378 if (SoftFloat)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001379 Builder.defineMacro("__SOFTFP__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001380
1381 if (CPU == "xscale")
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001382 Builder.defineMacro("__XSCALE__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001383
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001384 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001385 if (IsThumb) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001386 Builder.defineMacro("__THUMBEL__");
1387 Builder.defineMacro("__thumb__");
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001388 if (IsThumb2)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001389 Builder.defineMacro("__thumb2__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001390 }
1391
1392 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001393 Builder.defineMacro("__APCS_32__");
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001394
1395 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001396 Builder.defineMacro("__VFP_FP__");
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001397
1398 // This only gets set when Neon instructions are actually available, unlike
1399 // the VFP define, hence the soft float and arch check. This is subtly
1400 // different from gcc, we follow the intent which was that it should be set
1401 // when Neon instructions are actually available.
1402 if (FPU == NeonFPU && !SoftFloat && IsThumb2)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001403 Builder.defineMacro("__ARM_NEON__");
Chris Lattner17df24e2008-04-21 18:56:49 +00001404 }
1405 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1406 unsigned &NumRecords) const {
Chris Lattner5cc15e02010-03-03 19:03:45 +00001407 Records = BuiltinInfo;
1408 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner17df24e2008-04-21 18:56:49 +00001409 }
1410 virtual const char *getVAListDeclaration() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001411 return "typedef char* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +00001412 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001413 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001414 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001415 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001416 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001417 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00001418 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001419 // FIXME: Check if this is complete
Anders Carlsson58436352009-02-28 17:11:49 +00001420 switch (*Name) {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001421 default:
Nate Begeman2908fa02008-04-22 05:03:19 +00001422 case 'l': // r0-r7
1423 case 'h': // r8-r15
1424 case 'w': // VFP Floating point register single precision
1425 case 'P': // VFP Floating point register double precision
Chris Lattnerd9725f72009-04-26 07:16:29 +00001426 Info.setAllowsRegister();
Nate Begeman2908fa02008-04-22 05:03:19 +00001427 return true;
1428 }
Chris Lattner17df24e2008-04-21 18:56:49 +00001429 return false;
1430 }
1431 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001432 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +00001433 return "";
1434 }
1435};
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001436
1437const char * const ARMTargetInfo::GCCRegNames[] = {
1438 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1439 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1440};
1441
1442void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
1443 unsigned &NumNames) const {
1444 Names = GCCRegNames;
1445 NumNames = llvm::array_lengthof(GCCRegNames);
1446}
1447
1448const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1449
1450 { { "a1" }, "r0" },
1451 { { "a2" }, "r1" },
1452 { { "a3" }, "r2" },
1453 { { "a4" }, "r3" },
1454 { { "v1" }, "r4" },
1455 { { "v2" }, "r5" },
1456 { { "v3" }, "r6" },
1457 { { "v4" }, "r7" },
1458 { { "v5" }, "r8" },
1459 { { "v6", "rfp" }, "r9" },
1460 { { "sl" }, "r10" },
1461 { { "fp" }, "r11" },
1462 { { "ip" }, "r12" },
1463 { { "sp" }, "r13" },
1464 { { "lr" }, "r14" },
1465 { { "pc" }, "r15" },
1466};
1467
1468void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1469 unsigned &NumAliases) const {
1470 Aliases = GCCRegAliases;
1471 NumAliases = llvm::array_lengthof(GCCRegAliases);
1472}
Chris Lattner5cc15e02010-03-03 19:03:45 +00001473
1474const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
1475#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
1476#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
1477#include "clang/Basic/BuiltinsARM.def"
1478};
Chris Lattner17df24e2008-04-21 18:56:49 +00001479} // end anonymous namespace.
1480
Eli Friedmanf05b7722008-08-20 07:44:10 +00001481
1482namespace {
Mike Stump11289f42009-09-09 15:08:12 +00001483class DarwinARMTargetInfo :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001484 public DarwinTargetInfo<ARMTargetInfo> {
1485protected:
Daniel Dunbar40165182009-08-24 09:10:05 +00001486 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001487 MacroBuilder &Builder) const {
Daniel Dunbard86666f2010-01-26 01:44:04 +00001488 getDarwinDefines(Builder, Opts, Triple);
Eli Friedmand88c8a12009-04-19 21:38:35 +00001489 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00001490
Torok Edwinb2b37c62009-06-30 17:10:35 +00001491public:
Mike Stump11289f42009-09-09 15:08:12 +00001492 DarwinARMTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +00001493 : DarwinTargetInfo<ARMTargetInfo>(triple) {}
Eli Friedmanf05b7722008-08-20 07:44:10 +00001494};
1495} // end anonymous namespace.
1496
Chris Lattner5ba61f02006-10-14 07:39:34 +00001497namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001498class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +00001499 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1500 static const char * const GCCRegNames[];
Gabor Greif49991682008-02-21 16:29:08 +00001501public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001502 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1503 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +00001504 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001505 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001506 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001507 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001508 MacroBuilder &Builder) const {
1509 DefineStd(Builder, "sparc", Opts);
1510 Builder.defineMacro("__sparcv8");
1511 Builder.defineMacro("__REGISTER_PREFIX__", "");
Gabor Greif49991682008-02-21 16:29:08 +00001512 }
1513 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1514 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001515 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +00001516 }
1517 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001518 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +00001519 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001520 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001521 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001522 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001523 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001524 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif49991682008-02-21 16:29:08 +00001525 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001526 // FIXME: Implement!
1527 return false;
Gabor Greif49991682008-02-21 16:29:08 +00001528 }
1529 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001530 // FIXME: Implement!
1531 return "";
Gabor Greif49991682008-02-21 16:29:08 +00001532 }
1533};
1534
Chris Lattner9b415d62009-01-27 01:58:38 +00001535const char * const SparcV8TargetInfo::GCCRegNames[] = {
1536 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1537 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1538 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1539 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1540};
1541
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001542void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001543 unsigned &NumNames) const {
1544 Names = GCCRegNames;
1545 NumNames = llvm::array_lengthof(GCCRegNames);
1546}
1547
1548const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001549 { { "g0" }, "r0" },
1550 { { "g1" }, "r1" },
1551 { { "g2" }, "r2" },
1552 { { "g3" }, "r3" },
1553 { { "g4" }, "r4" },
1554 { { "g5" }, "r5" },
1555 { { "g6" }, "r6" },
1556 { { "g7" }, "r7" },
1557 { { "o0" }, "r8" },
1558 { { "o1" }, "r9" },
1559 { { "o2" }, "r10" },
1560 { { "o3" }, "r11" },
1561 { { "o4" }, "r12" },
1562 { { "o5" }, "r13" },
1563 { { "o6", "sp" }, "r14" },
1564 { { "o7" }, "r15" },
1565 { { "l0" }, "r16" },
1566 { { "l1" }, "r17" },
1567 { { "l2" }, "r18" },
1568 { { "l3" }, "r19" },
1569 { { "l4" }, "r20" },
1570 { { "l5" }, "r21" },
1571 { { "l6" }, "r22" },
1572 { { "l7" }, "r23" },
1573 { { "i0" }, "r24" },
1574 { { "i1" }, "r25" },
1575 { { "i2" }, "r26" },
1576 { { "i3" }, "r27" },
1577 { { "i4" }, "r28" },
1578 { { "i5" }, "r29" },
1579 { { "i6", "fp" }, "r30" },
1580 { { "i7" }, "r31" },
Chris Lattner9b415d62009-01-27 01:58:38 +00001581};
1582
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001583void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001584 unsigned &NumAliases) const {
1585 Aliases = GCCRegAliases;
1586 NumAliases = llvm::array_lengthof(GCCRegAliases);
1587}
Gabor Greif49991682008-02-21 16:29:08 +00001588} // end anonymous namespace.
1589
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001590namespace {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00001591class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
1592public:
1593 AuroraUXSparcV8TargetInfo(const std::string& triple) :
1594 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
1595 SizeType = UnsignedInt;
1596 PtrDiffType = SignedInt;
1597 }
1598};
Torok Edwinb2b37c62009-06-30 17:10:35 +00001599class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001600public:
1601 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001602 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmand50881c2008-11-02 02:43:55 +00001603 SizeType = UnsignedInt;
1604 PtrDiffType = SignedInt;
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001605 }
1606};
1607} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +00001608
Chris Lattnerb781dc792008-05-08 05:58:21 +00001609namespace {
1610 class PIC16TargetInfo : public TargetInfo{
1611 public:
1612 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +00001613 TLSSupported = false;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001614 IntWidth = 16;
1615 LongWidth = LongLongWidth = 32;
1616 PointerWidth = 16;
1617 IntAlign = 8;
1618 LongAlign = LongLongAlign = 8;
Eli Friedmanb5366062008-05-20 14:21:01 +00001619 PointerAlign = 8;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001620 SizeType = UnsignedInt;
1621 IntMaxType = SignedLong;
1622 UIntMaxType = UnsignedLong;
Chris Lattner7e4c81c2009-02-13 22:28:55 +00001623 IntPtrType = SignedShort;
Eli Friedmand50881c2008-11-02 02:43:55 +00001624 PtrDiffType = SignedInt;
Edward O'Callaghan847f2a12009-11-21 00:49:54 +00001625 SigAtomicType = SignedLong;
Sanjiv Gupta7c720072009-06-02 04:43:46 +00001626 FloatWidth = 32;
1627 FloatAlign = 32;
1628 DoubleWidth = 32;
1629 DoubleAlign = 32;
1630 LongDoubleWidth = 32;
1631 LongDoubleAlign = 32;
1632 FloatFormat = &llvm::APFloat::IEEEsingle;
1633 DoubleFormat = &llvm::APFloat::IEEEsingle;
1634 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001635 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8";
Sanjiv Gupta7c720072009-06-02 04:43:46 +00001636
Chris Lattnerb781dc792008-05-08 05:58:21 +00001637 }
Chris Lattner5e2ef0c2008-05-09 06:08:39 +00001638 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1639 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001640 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001641 MacroBuilder &Builder) const {
1642 Builder.defineMacro("__pic16");
Sanjiv Guptaecd26002010-02-16 03:37:11 +00001643 Builder.defineMacro("__PIC16");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001644 Builder.defineMacro("rom", "__attribute__((address_space(1)))");
1645 Builder.defineMacro("ram", "__attribute__((address_space(0)))");
Sanjiv Guptaecd26002010-02-16 03:37:11 +00001646 Builder.defineMacro("__section(SectName)",
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001647 "__attribute__((section(SectName)))");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001648 Builder.defineMacro("near",
Sanjiv Gupta84f0f772009-10-24 18:08:20 +00001649 "__attribute__((section(\"Address=NEAR\")))");
Sanjiv Guptaecd26002010-02-16 03:37:11 +00001650 Builder.defineMacro("__address(Addr)",
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001651 "__attribute__((section(\"Address=\"#Addr)))");
Sanjiv Guptaecd26002010-02-16 03:37:11 +00001652 Builder.defineMacro("__config(conf)", "asm(\"CONFIG \"#conf)");
1653 Builder.defineMacro("__idlocs(value)", "asm(\"__IDLOCS \"#value)");
1654 Builder.defineMacro("interrupt",
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001655 "__attribute__((section(\"interrupt=0x4\"))) \
1656 __attribute__((used))");
Chris Lattnerb781dc792008-05-08 05:58:21 +00001657 }
1658 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1659 unsigned &NumRecords) const {}
Mike Stump11289f42009-09-09 15:08:12 +00001660 virtual const char *getVAListDeclaration() const {
Sanjiv Guptaecd26002010-02-16 03:37:11 +00001661 return "typedef char* __builtin_va_list;";
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001662 }
1663 virtual const char *getClobbers() const {
1664 return "";
1665 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001666 virtual void getGCCRegNames(const char * const *&Names,
1667 unsigned &NumNames) const {}
1668 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001669 TargetInfo::ConstraintInfo &info) const {
1670 return true;
1671 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001672 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001673 unsigned &NumAliases) const {}
1674 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1675 };
1676}
1677
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001678namespace {
1679 class MSP430TargetInfo : public TargetInfo {
1680 static const char * const GCCRegNames[];
1681 public:
1682 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1683 TLSSupported = false;
Anton Korobeynikovcbc4e982010-01-30 12:55:11 +00001684 IntWidth = 16; IntAlign = 16;
1685 LongWidth = 32; LongLongWidth = 64;
1686 LongAlign = LongLongAlign = 16;
1687 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001688 SizeType = UnsignedInt;
1689 IntMaxType = SignedLong;
1690 UIntMaxType = UnsignedLong;
1691 IntPtrType = SignedShort;
1692 PtrDiffType = SignedInt;
Edward O'Callaghan847f2a12009-11-21 00:49:54 +00001693 SigAtomicType = SignedLong;
Anton Korobeynikovd94329a2009-12-19 01:32:37 +00001694 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001695 }
1696 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001697 MacroBuilder &Builder) const {
1698 Builder.defineMacro("MSP430");
1699 Builder.defineMacro("__MSP430__");
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001700 // FIXME: defines for different 'flavours' of MCU
1701 }
1702 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1703 unsigned &NumRecords) const {
1704 // FIXME: Implement.
1705 Records = 0;
1706 NumRecords = 0;
1707 }
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001708 virtual void getGCCRegNames(const char * const *&Names,
1709 unsigned &NumNames) const;
1710 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1711 unsigned &NumAliases) const {
1712 // No aliases.
1713 Aliases = 0;
1714 NumAliases = 0;
1715 }
1716 virtual bool validateAsmConstraint(const char *&Name,
1717 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov051913b2009-10-15 23:17:13 +00001718 // No target constraints for now.
1719 return false;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001720 }
1721 virtual const char *getClobbers() const {
1722 // FIXME: Is this really right?
1723 return "";
1724 }
1725 virtual const char *getVAListDeclaration() const {
1726 // FIXME: implement
Anton Korobeynikov2f910822009-05-08 18:24:57 +00001727 return "typedef char* __builtin_va_list;";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001728 }
1729 };
1730
1731 const char * const MSP430TargetInfo::GCCRegNames[] = {
1732 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1733 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1734 };
1735
1736 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1737 unsigned &NumNames) const {
1738 Names = GCCRegNames;
1739 NumNames = llvm::array_lengthof(GCCRegNames);
1740 }
1741}
1742
1743
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001744namespace {
1745 class SystemZTargetInfo : public TargetInfo {
1746 static const char * const GCCRegNames[];
1747 public:
1748 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
1749 TLSSupported = false;
1750 IntWidth = IntAlign = 32;
1751 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
1752 PointerWidth = PointerAlign = 64;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001753 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
1754 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001755 }
1756 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001757 MacroBuilder &Builder) const {
1758 Builder.defineMacro("__s390__");
1759 Builder.defineMacro("__s390x__");
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001760 }
1761 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1762 unsigned &NumRecords) const {
1763 // FIXME: Implement.
1764 Records = 0;
1765 NumRecords = 0;
1766 }
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001767
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001768 virtual void getGCCRegNames(const char * const *&Names,
1769 unsigned &NumNames) const;
1770 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1771 unsigned &NumAliases) const {
1772 // No aliases.
1773 Aliases = 0;
1774 NumAliases = 0;
1775 }
1776 virtual bool validateAsmConstraint(const char *&Name,
1777 TargetInfo::ConstraintInfo &info) const {
1778 // FIXME: implement
1779 return true;
1780 }
1781 virtual const char *getClobbers() const {
1782 // FIXME: Is this really right?
1783 return "";
1784 }
1785 virtual const char *getVAListDeclaration() const {
1786 // FIXME: implement
1787 return "typedef char* __builtin_va_list;";
1788 }
1789 };
1790
1791 const char * const SystemZTargetInfo::GCCRegNames[] = {
1792 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1793 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1794 };
1795
1796 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
1797 unsigned &NumNames) const {
1798 Names = GCCRegNames;
1799 NumNames = llvm::array_lengthof(GCCRegNames);
1800 }
1801}
1802
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001803namespace {
1804 class BlackfinTargetInfo : public TargetInfo {
1805 static const char * const GCCRegNames[];
1806 public:
1807 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
1808 TLSSupported = false;
1809 DoubleAlign = 32;
1810 LongLongAlign = 32;
1811 LongDoubleAlign = 32;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001812 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001813 }
1814
1815 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001816 MacroBuilder &Builder) const {
1817 DefineStd(Builder, "bfin", Opts);
1818 DefineStd(Builder, "BFIN", Opts);
1819 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001820 // FIXME: This one is really dependent on -mcpu
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001821 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001822 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
1823 }
1824
1825 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1826 unsigned &NumRecords) const {
1827 // FIXME: Implement.
1828 Records = 0;
1829 NumRecords = 0;
1830 }
1831
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001832 virtual void getGCCRegNames(const char * const *&Names,
1833 unsigned &NumNames) const;
1834
1835 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1836 unsigned &NumAliases) const {
1837 // No aliases.
1838 Aliases = 0;
1839 NumAliases = 0;
1840 }
1841
1842 virtual bool validateAsmConstraint(const char *&Name,
1843 TargetInfo::ConstraintInfo &Info) const {
1844 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
1845 Info.setAllowsRegister();
1846 return true;
1847 }
1848 return false;
1849 }
1850
1851 virtual const char *getClobbers() const {
1852 return "";
1853 }
1854
1855 virtual const char *getVAListDeclaration() const {
1856 return "typedef char* __builtin_va_list;";
1857 }
1858 };
1859
1860 const char * const BlackfinTargetInfo::GCCRegNames[] = {
1861 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1862 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
1863 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
1864 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
1865 "a0", "a1", "cc",
1866 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
1867 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
1868 };
1869
1870 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
1871 unsigned &NumNames) const {
1872 Names = GCCRegNames;
1873 NumNames = llvm::array_lengthof(GCCRegNames);
1874 }
1875}
1876
Eli Friedmana9c3d712009-08-19 20:47:07 +00001877namespace {
1878
Mike Stump11289f42009-09-09 15:08:12 +00001879 // LLVM and Clang cannot be used directly to output native binaries for
1880 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmana9c3d712009-08-19 20:47:07 +00001881 // type and alignment information.
Mike Stump11289f42009-09-09 15:08:12 +00001882 //
1883 // TCE uses the llvm bitcode as input and uses it for generating customized
1884 // target processor and program binary. TCE co-design environment is
Eli Friedmana9c3d712009-08-19 20:47:07 +00001885 // publicly available in http://tce.cs.tut.fi
1886
1887 class TCETargetInfo : public TargetInfo{
1888 public:
1889 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
1890 TLSSupported = false;
1891 IntWidth = 32;
1892 LongWidth = LongLongWidth = 32;
Eli Friedmana9c3d712009-08-19 20:47:07 +00001893 PointerWidth = 32;
1894 IntAlign = 32;
1895 LongAlign = LongLongAlign = 32;
1896 PointerAlign = 32;
1897 SizeType = UnsignedInt;
1898 IntMaxType = SignedLong;
1899 UIntMaxType = UnsignedLong;
1900 IntPtrType = SignedInt;
1901 PtrDiffType = SignedInt;
1902 FloatWidth = 32;
1903 FloatAlign = 32;
1904 DoubleWidth = 32;
1905 DoubleAlign = 32;
1906 LongDoubleWidth = 32;
1907 LongDoubleAlign = 32;
1908 FloatFormat = &llvm::APFloat::IEEEsingle;
1909 DoubleFormat = &llvm::APFloat::IEEEsingle;
1910 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner09797542010-03-04 21:07:38 +00001911 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
1912 "i16:16:32-i32:32:32-i64:32:32-"
1913 "f32:32:32-f64:64:64-v64:64:64-"
1914 "v128:128:128-a0:0:64-n32";
Eli Friedmana9c3d712009-08-19 20:47:07 +00001915 }
1916
1917 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001918 MacroBuilder &Builder) const {
1919 DefineStd(Builder, "tce", Opts);
1920 Builder.defineMacro("__TCE__");
1921 Builder.defineMacro("__TCE_V1__");
Eli Friedmana9c3d712009-08-19 20:47:07 +00001922 }
1923 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1924 unsigned &NumRecords) const {}
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001925 virtual const char *getClobbers() const {
1926 return "";
1927 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001928 virtual const char *getVAListDeclaration() const {
1929 return "typedef void* __builtin_va_list;";
1930 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001931 virtual void getGCCRegNames(const char * const *&Names,
1932 unsigned &NumNames) const {}
1933 virtual bool validateAsmConstraint(const char *&Name,
1934 TargetInfo::ConstraintInfo &info) const {
1935 return true;
1936 }
1937 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1938 unsigned &NumAliases) const {}
1939 };
1940}
1941
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00001942namespace {
1943class MipsTargetInfo : public TargetInfo {
Eric Christopher0b26a612010-03-02 02:41:08 +00001944 std::string ABI, CPU;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00001945 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1946 static const char * const GCCRegNames[];
1947public:
Eric Christopher0b26a612010-03-02 02:41:08 +00001948 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00001949 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
1950 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
1951 }
Eric Christopher0b26a612010-03-02 02:41:08 +00001952 virtual const char *getABI() const { return ABI.c_str(); }
1953 virtual bool setABI(const std::string &Name) {
1954
1955 if ((Name == "o32") || (Name == "eabi")) {
1956 ABI = Name;
1957 return true;
1958 } else
1959 return false;
1960 }
1961 virtual bool setCPU(const std::string &Name) {
1962 CPU = Name;
1963 return true;
1964 }
1965 void getDefaultFeatures(const std::string &CPU,
1966 llvm::StringMap<bool> &Features) const {
1967 Features[ABI] = true;
1968 Features[CPU] = true;
1969 }
1970 virtual void getArchDefines(const LangOptions &Opts,
1971 MacroBuilder &Builder) const {
1972 if (ABI == "o32")
1973 Builder.defineMacro("__mips_o32");
1974 else if (ABI == "eabi")
1975 Builder.defineMacro("__mips_eabi");
1976 }
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00001977 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001978 MacroBuilder &Builder) const {
1979 DefineStd(Builder, "mips", Opts);
1980 Builder.defineMacro("_mips");
1981 DefineStd(Builder, "MIPSEB", Opts);
1982 Builder.defineMacro("_MIPSEB");
1983 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christopher0b26a612010-03-02 02:41:08 +00001984 getArchDefines(Opts, Builder);
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00001985 }
1986 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1987 unsigned &NumRecords) const {
1988 // FIXME: Implement!
1989 }
1990 virtual const char *getVAListDeclaration() const {
1991 return "typedef void* __builtin_va_list;";
1992 }
1993 virtual void getGCCRegNames(const char * const *&Names,
1994 unsigned &NumNames) const;
1995 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1996 unsigned &NumAliases) const;
1997 virtual bool validateAsmConstraint(const char *&Name,
1998 TargetInfo::ConstraintInfo &Info) const {
1999 switch (*Name) {
2000 default:
2001 case 'r': // CPU registers.
2002 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2003 case 'y': // Equivalent to "r", backwards compatibility only.
2004 case 'f': // floating-point registers.
2005 Info.setAllowsRegister();
2006 return true;
2007 }
2008 return false;
2009 }
2010
2011 virtual const char *getClobbers() const {
2012 // FIXME: Implement!
2013 return "";
2014 }
2015};
2016
2017const char * const MipsTargetInfo::GCCRegNames[] = {
2018 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
2019 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2020 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2021 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2022 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2023 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2024 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2025 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2026 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2027 "$fcc5","$fcc6","$fcc7"
2028};
2029
2030void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2031 unsigned &NumNames) const {
2032 Names = GCCRegNames;
2033 NumNames = llvm::array_lengthof(GCCRegNames);
2034}
2035
2036const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2037 { { "at" }, "$1" },
2038 { { "v0" }, "$2" },
2039 { { "v1" }, "$3" },
2040 { { "a0" }, "$4" },
2041 { { "a1" }, "$5" },
2042 { { "a2" }, "$6" },
2043 { { "a3" }, "$7" },
2044 { { "t0" }, "$8" },
2045 { { "t1" }, "$9" },
2046 { { "t2" }, "$10" },
2047 { { "t3" }, "$11" },
2048 { { "t4" }, "$12" },
2049 { { "t5" }, "$13" },
2050 { { "t6" }, "$14" },
2051 { { "t7" }, "$15" },
2052 { { "s0" }, "$16" },
2053 { { "s1" }, "$17" },
2054 { { "s2" }, "$18" },
2055 { { "s3" }, "$19" },
2056 { { "s4" }, "$20" },
2057 { { "s5" }, "$21" },
2058 { { "s6" }, "$22" },
2059 { { "s7" }, "$23" },
2060 { { "t8" }, "$24" },
2061 { { "t9" }, "$25" },
2062 { { "k0" }, "$26" },
2063 { { "k1" }, "$27" },
2064 { { "gp" }, "$28" },
2065 { { "sp" }, "$29" },
2066 { { "fp" }, "$30" },
2067 { { "ra" }, "$31" }
2068};
2069
2070void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2071 unsigned &NumAliases) const {
2072 Aliases = GCCRegAliases;
2073 NumAliases = llvm::array_lengthof(GCCRegAliases);
2074}
2075} // end anonymous namespace.
2076
2077namespace {
2078class MipselTargetInfo : public MipsTargetInfo {
2079public:
2080 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2081 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2082 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2083 }
2084
2085 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002086 MacroBuilder &Builder) const;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002087};
2088
2089void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002090 MacroBuilder &Builder) const {
2091 DefineStd(Builder, "mips", Opts);
2092 Builder.defineMacro("_mips");
2093 DefineStd(Builder, "MIPSEL", Opts);
2094 Builder.defineMacro("_MIPSEL");
2095 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christopher0b26a612010-03-02 02:41:08 +00002096 getArchDefines(Opts, Builder);
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002097}
2098} // end anonymous namespace.
2099
Chris Lattner5ba61f02006-10-14 07:39:34 +00002100//===----------------------------------------------------------------------===//
2101// Driver code
2102//===----------------------------------------------------------------------===//
2103
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002104static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar52322032009-08-18 05:47:58 +00002105 llvm::Triple Triple(T);
2106 llvm::Triple::OSType os = Triple.getOS();
Eli Friedmanb5366062008-05-20 14:21:01 +00002107
Daniel Dunbar52322032009-08-18 05:47:58 +00002108 switch (Triple.getArch()) {
2109 default:
2110 return NULL;
Eli Friedmanb5366062008-05-20 14:21:01 +00002111
Daniel Dunbar52322032009-08-18 05:47:58 +00002112 case llvm::Triple::arm:
Daniel Dunbar33a004e2009-09-11 01:14:50 +00002113 case llvm::Triple::thumb:
Daniel Dunbar52322032009-08-18 05:47:58 +00002114 switch (os) {
2115 case llvm::Triple::Darwin:
Eli Friedman873f65a2008-08-21 00:13:15 +00002116 return new DarwinARMTargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002117 case llvm::Triple::FreeBSD:
Torok Edwinb2b37c62009-06-30 17:10:35 +00002118 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002119 default:
2120 return new ARMTargetInfo(T);
2121 }
Eli Friedmanb5366062008-05-20 14:21:01 +00002122
Daniel Dunbar52322032009-08-18 05:47:58 +00002123 case llvm::Triple::bfin:
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002124 return new BlackfinTargetInfo(T);
2125
Daniel Dunbar52322032009-08-18 05:47:58 +00002126 case llvm::Triple::msp430:
2127 return new MSP430TargetInfo(T);
Eli Friedmanb5366062008-05-20 14:21:01 +00002128
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002129 case llvm::Triple::mips:
2130 if (os == llvm::Triple::Psp)
2131 return new PSPTargetInfo<MipsTargetInfo>(T);
2132 if (os == llvm::Triple::Linux)
2133 return new LinuxTargetInfo<MipsTargetInfo>(T);
2134 return new MipsTargetInfo(T);
2135
2136 case llvm::Triple::mipsel:
2137 if (os == llvm::Triple::Psp)
2138 return new PSPTargetInfo<MipselTargetInfo>(T);
2139 if (os == llvm::Triple::Linux)
2140 return new LinuxTargetInfo<MipselTargetInfo>(T);
2141 return new MipselTargetInfo(T);
2142
Daniel Dunbar52322032009-08-18 05:47:58 +00002143 case llvm::Triple::pic16:
2144 return new PIC16TargetInfo(T);
2145
2146 case llvm::Triple::ppc:
2147 if (os == llvm::Triple::Darwin)
2148 return new DarwinTargetInfo<PPCTargetInfo>(T);
Chris Lattnerdb5c16b2010-02-16 18:14:57 +00002149 else if (os == llvm::Triple::FreeBSD)
2150 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002151 return new PPC32TargetInfo(T);
2152
2153 case llvm::Triple::ppc64:
2154 if (os == llvm::Triple::Darwin)
2155 return new DarwinTargetInfo<PPC64TargetInfo>(T);
John Thompsone467e192009-11-19 17:18:50 +00002156 else if (os == llvm::Triple::Lv2)
2157 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnerdb5c16b2010-02-16 18:14:57 +00002158 else if (os == llvm::Triple::FreeBSD)
2159 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002160 return new PPC64TargetInfo(T);
2161
2162 case llvm::Triple::sparc:
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002163 if (os == llvm::Triple::AuroraUX)
2164 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002165 if (os == llvm::Triple::Solaris)
2166 return new SolarisSparcV8TargetInfo(T);
2167 return new SparcV8TargetInfo(T);
2168
John Thompsone467e192009-11-19 17:18:50 +00002169 // FIXME: Need a real SPU target.
2170 case llvm::Triple::cellspu:
2171 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2172
Daniel Dunbar52322032009-08-18 05:47:58 +00002173 case llvm::Triple::systemz:
2174 return new SystemZTargetInfo(T);
2175
Eli Friedmana9c3d712009-08-19 20:47:07 +00002176 case llvm::Triple::tce:
2177 return new TCETargetInfo(T);
2178
Daniel Dunbar52322032009-08-18 05:47:58 +00002179 case llvm::Triple::x86:
2180 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002181 case llvm::Triple::AuroraUX:
2182 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002183 case llvm::Triple::Darwin:
2184 return new DarwinI386TargetInfo(T);
2185 case llvm::Triple::Linux:
2186 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2187 case llvm::Triple::DragonFly:
2188 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2189 case llvm::Triple::NetBSD:
2190 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2191 case llvm::Triple::OpenBSD:
2192 return new OpenBSDI386TargetInfo(T);
2193 case llvm::Triple::FreeBSD:
2194 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
2195 case llvm::Triple::Solaris:
2196 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2197 case llvm::Triple::Cygwin:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002198 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002199 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002200 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002201 case llvm::Triple::Win32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002202 return new VisualStudioWindowsX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002203 default:
2204 return new X86_32TargetInfo(T);
2205 }
2206
2207 case llvm::Triple::x86_64:
2208 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002209 case llvm::Triple::AuroraUX:
2210 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002211 case llvm::Triple::Darwin:
2212 return new DarwinX86_64TargetInfo(T);
2213 case llvm::Triple::Linux:
2214 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner002ba6b2010-01-09 05:41:14 +00002215 case llvm::Triple::DragonFly:
2216 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002217 case llvm::Triple::NetBSD:
2218 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2219 case llvm::Triple::OpenBSD:
2220 return new OpenBSDX86_64TargetInfo(T);
2221 case llvm::Triple::FreeBSD:
2222 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2223 case llvm::Triple::Solaris:
2224 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002225 case llvm::Triple::MinGW64:
2226 return new MinGWX86_64TargetInfo(T);
2227 case llvm::Triple::Win32: // This is what Triple.h supports now.
2228 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002229 default:
2230 return new X86_64TargetInfo(T);
2231 }
2232 }
Chris Lattner5ba61f02006-10-14 07:39:34 +00002233}
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002234
2235/// CreateTargetInfo - Return the target info object for the specified target
2236/// triple.
2237TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002238 TargetOptions &Opts) {
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002239 llvm::Triple Triple(Opts.Triple);
2240
2241 // Construct the target
2242 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2243 if (!Target) {
2244 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2245 return 0;
2246 }
2247
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002248 // Set the target CPU if specified.
2249 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2250 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2251 return 0;
2252 }
2253
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002254 // Set the target ABI if specified.
2255 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2256 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2257 return 0;
2258 }
2259
2260 // Compute the default target features, we need the target to handle this
2261 // because features may have dependencies on one another.
2262 llvm::StringMap<bool> Features;
2263 Target->getDefaultFeatures(Opts.CPU, Features);
2264
2265 // Apply the user specified deltas.
2266 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2267 ie = Opts.Features.end(); it != ie; ++it) {
2268 const char *Name = it->c_str();
2269
2270 // Apply the feature via the target.
2271 if ((Name[0] != '-' && Name[0] != '+') ||
2272 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2273 Diags.Report(diag::err_target_invalid_feature) << Name;
2274 return 0;
2275 }
2276 }
2277
2278 // Add the features to the compile options.
2279 //
2280 // FIXME: If we are completely confident that we have the right set, we only
2281 // need to pass the minuses.
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002282 Opts.Features.clear();
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002283 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2284 ie = Features.end(); it != ie; ++it)
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002285 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2286 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002287
2288 return Target.take();
2289}