blob: aa5147f76f01006f4ecfe5adc0a117d6b7ae02e3 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikova7c47172009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenekbbced582007-12-12 18:05:32 +000011// target triple.
Reid Spencer5f016e22007-07-11 17:01:13 +000012//
13//===----------------------------------------------------------------------===//
14
Reid Spencer5f016e22007-07-11 17:01:13 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000016#include "clang/Basic/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
Chris Lattner8fc4dfb2008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Chandler Carruth103b71c2010-01-20 06:13:02 +000019#include "clang/Basic/MacroBuilder.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000020#include "clang/Basic/TargetBuiltins.h"
21#include "clang/Basic/TargetOptions.h"
Eli Friedman25531262008-05-20 14:27:34 +000022#include "llvm/ADT/APFloat.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000023#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar29a790b2009-11-11 09:38:56 +000024#include "llvm/ADT/STLExtras.h"
Daniel Dunbar77659342009-08-19 20:04:03 +000025#include "llvm/ADT/StringRef.h"
Daniel Dunbar29a790b2009-11-11 09:38:56 +000026#include "llvm/ADT/StringSwitch.h"
Chris Lattner4c28b1c2009-08-12 06:24:27 +000027#include "llvm/ADT/Triple.h"
Chris Lattner797c3c42009-08-10 19:03:04 +000028#include "llvm/MC/MCSectionMachO.h"
Dale Johannesen1e592cb2010-10-29 23:24:33 +000029#include "llvm/Type.h"
Benjamin Kramer48725082010-01-09 18:20:57 +000030#include <algorithm>
Reid Spencer5f016e22007-07-11 17:01:13 +000031using namespace clang;
32
Reid Spencer5f016e22007-07-11 17:01:13 +000033//===----------------------------------------------------------------------===//
34// Common code shared among targets.
35//===----------------------------------------------------------------------===//
36
Chris Lattnerca45cff2009-03-20 16:06:38 +000037/// DefineStd - Define a macro name and standard variants. For example if
38/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
39/// when in GNU mode.
Benjamin Kramera9992772010-01-09 17:55:51 +000040static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
Chris Lattnerca45cff2009-03-20 16:06:38 +000041 const LangOptions &Opts) {
42 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000043
Chris Lattnerca45cff2009-03-20 16:06:38 +000044 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
45 // in the user's namespace.
46 if (Opts.GNUMode)
Benjamin Kramera9992772010-01-09 17:55:51 +000047 Builder.defineMacro(MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000048
Chris Lattnerca45cff2009-03-20 16:06:38 +000049 // Define __unix.
Benjamin Kramera9992772010-01-09 17:55:51 +000050 Builder.defineMacro("__" + MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000051
Chris Lattnerca45cff2009-03-20 16:06:38 +000052 // Define __unix__.
Benjamin Kramera9992772010-01-09 17:55:51 +000053 Builder.defineMacro("__" + MacroName + "__");
Chris Lattnerca45cff2009-03-20 16:06:38 +000054}
55
Chris Lattnerd29b6302008-10-05 21:50:58 +000056//===----------------------------------------------------------------------===//
57// Defines specific to certain operating systems.
58//===----------------------------------------------------------------------===//
Chris Lattner797c3c42009-08-10 19:03:04 +000059
Torok Edwin5f6c1942009-06-30 17:10:35 +000060namespace {
Douglas Gregora3844922009-07-01 15:12:53 +000061template<typename TgtInfo>
62class OSTargetInfo : public TgtInfo {
Torok Edwin5f6c1942009-06-30 17:10:35 +000063protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +000064 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +000065 MacroBuilder &Builder) const=0;
Torok Edwin5f6c1942009-06-30 17:10:35 +000066public:
Douglas Gregora3844922009-07-01 15:12:53 +000067 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwin5f6c1942009-06-30 17:10:35 +000068 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +000069 MacroBuilder &Builder) const {
70 TgtInfo::getTargetDefines(Opts, Builder);
71 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
Torok Edwinb0a5b242009-06-30 17:00:25 +000072 }
Torok Edwin5f6c1942009-06-30 17:10:35 +000073
74};
Chris Lattner4c28b1c2009-08-12 06:24:27 +000075} // end anonymous namespace
Torok Edwinb0a5b242009-06-30 17:00:25 +000076
Chris Lattner797c3c42009-08-10 19:03:04 +000077
Daniel Dunbar21ae3192010-01-26 01:44:04 +000078static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
79 const llvm::Triple &Triple) {
Benjamin Kramera9992772010-01-09 17:55:51 +000080 Builder.defineMacro("__APPLE_CC__", "5621");
81 Builder.defineMacro("__APPLE__");
82 Builder.defineMacro("__MACH__");
83 Builder.defineMacro("OBJC_NEW_PROPERTIES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000084
Chris Lattner10d24272009-04-07 16:50:40 +000085 // __weak is always defined, for use in blocks and with objc pointers.
Benjamin Kramera9992772010-01-09 17:55:51 +000086 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000087
Chris Lattner10d24272009-04-07 16:50:40 +000088 // Darwin defines __strong even in C mode (just to nothing).
89 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Benjamin Kramera9992772010-01-09 17:55:51 +000090 Builder.defineMacro("__strong", "");
Chris Lattner10d24272009-04-07 16:50:40 +000091 else
Benjamin Kramera9992772010-01-09 17:55:51 +000092 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
Eli Friedman2de4fee2009-06-04 23:00:29 +000093
94 if (Opts.Static)
Benjamin Kramera9992772010-01-09 17:55:51 +000095 Builder.defineMacro("__STATIC__");
Eli Friedman2de4fee2009-06-04 23:00:29 +000096 else
Benjamin Kramera9992772010-01-09 17:55:51 +000097 Builder.defineMacro("__DYNAMIC__");
Daniel Dunbar5345c392009-09-03 04:54:28 +000098
99 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000100 Builder.defineMacro("_REENTRANT");
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000101
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000102 // Get the OS version number from the triple.
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000103 unsigned Maj, Min, Rev;
Mike Stump1eb44332009-09-09 15:08:12 +0000104
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000105 // If no version was given, default to to 10.4.0, for simplifying tests.
106 if (Triple.getOSName() == "darwin") {
107 Min = Rev = 0;
108 Maj = 8;
109 } else
110 Triple.getDarwinNumber(Maj, Min, Rev);
111
112 // Set the appropriate OS version define.
113 if (Triple.getEnvironmentName() == "iphoneos") {
114 assert(Maj < 10 && Min < 99 && Rev < 99 && "Invalid version!");
115 char Str[6];
116 Str[0] = '0' + Maj;
117 Str[1] = '0' + (Min / 10);
118 Str[2] = '0' + (Min % 10);
119 Str[3] = '0' + (Rev / 10);
120 Str[4] = '0' + (Rev % 10);
121 Str[5] = '\0';
122 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
123 } else {
124 // For historical reasons that make little sense, the version passed here is
125 // the "darwin" version, which drops the 10 and offsets by 4.
126 Rev = Min;
127 Min = Maj - 4;
128 Maj = 10;
129
130 assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
131 assert(Maj < 99 && Min < 10 && Rev < 10 && "Invalid version!");
132 char Str[5];
133 Str[0] = '0' + (Maj / 10);
134 Str[1] = '0' + (Maj % 10);
135 Str[2] = '0' + Min;
136 Str[3] = '0' + Rev;
137 Str[4] = '\0';
138 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000139 }
Eli Friedman618234a2008-08-20 02:34:37 +0000140}
Reid Spencer5f016e22007-07-11 17:01:13 +0000141
Chris Lattner797c3c42009-08-10 19:03:04 +0000142namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000143template<typename Target>
144class DarwinTargetInfo : public OSTargetInfo<Target> {
145protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000146 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000147 MacroBuilder &Builder) const {
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000148 getDarwinDefines(Builder, Opts, Triple);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000149 }
Mike Stump1eb44332009-09-09 15:08:12 +0000150
Torok Edwin5f6c1942009-06-30 17:10:35 +0000151public:
152 DarwinTargetInfo(const std::string& triple) :
153 OSTargetInfo<Target>(triple) {
Eric Christopherdd53ec92010-06-25 19:04:52 +0000154 this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;
Torok Edwin5f6c1942009-06-30 17:10:35 +0000155 }
156
Anders Carlssonf959fb52010-01-30 18:33:31 +0000157 virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
Chris Lattner797c3c42009-08-10 19:03:04 +0000158 // Let MCSectionMachO validate this.
159 llvm::StringRef Segment, Section;
160 unsigned TAA, StubSize;
161 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
162 TAA, StubSize);
163 }
Michael J. Spencer20249a12010-10-21 03:16:25 +0000164
Anders Carlsson18af3682010-06-08 22:47:50 +0000165 virtual const char *getStaticInitSectionSpecifier() const {
166 // FIXME: We should return 0 when building kexts.
167 return "__TEXT,__StaticInit,regular,pure_instructions";
168 }
Michael J. Spencer20249a12010-10-21 03:16:25 +0000169
Torok Edwin5f6c1942009-06-30 17:10:35 +0000170};
171
Chris Lattner797c3c42009-08-10 19:03:04 +0000172
Torok Edwin5f6c1942009-06-30 17:10:35 +0000173// DragonFlyBSD Target
174template<typename Target>
175class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
176protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000177 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000178 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000179 // DragonFly defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000180 Builder.defineMacro("__DragonFly__");
181 Builder.defineMacro("__DragonFly_cc_version", "100001");
182 Builder.defineMacro("__ELF__");
183 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
184 Builder.defineMacro("__tune_i386__");
185 DefineStd(Builder, "unix", Opts);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000186 }
187public:
Mike Stump1eb44332009-09-09 15:08:12 +0000188 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000189 : OSTargetInfo<Target>(triple) {}
190};
191
192// FreeBSD Target
193template<typename Target>
194class FreeBSDTargetInfo : public OSTargetInfo<Target> {
195protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000196 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000197 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000198 // FreeBSD defines; list based off of gcc output
199
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000200 // FIXME: Move version number handling to llvm::Triple.
Benjamin Kramer3bb65302010-01-30 19:55:01 +0000201 llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000202
Benjamin Kramer3bb65302010-01-30 19:55:01 +0000203 Builder.defineMacro("__FreeBSD__", Release);
204 Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
Benjamin Kramera9992772010-01-09 17:55:51 +0000205 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
206 DefineStd(Builder, "unix", Opts);
207 Builder.defineMacro("__ELF__");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000208 }
209public:
Mike Stump1eb44332009-09-09 15:08:12 +0000210 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands1e90faf2009-07-08 13:55:08 +0000211 : OSTargetInfo<Target>(triple) {
212 this->UserLabelPrefix = "";
213 }
Torok Edwin5f6c1942009-06-30 17:10:35 +0000214};
215
Chris Lattner38e317d2010-07-07 16:01:42 +0000216// Minix Target
217template<typename Target>
218class MinixTargetInfo : public OSTargetInfo<Target> {
219protected:
220 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
221 MacroBuilder &Builder) const {
222 // Minix defines
223
224 Builder.defineMacro("__minix", "3");
225 Builder.defineMacro("_EM_WSIZE", "4");
226 Builder.defineMacro("_EM_PSIZE", "4");
227 Builder.defineMacro("_EM_SSIZE", "2");
228 Builder.defineMacro("_EM_LSIZE", "4");
229 Builder.defineMacro("_EM_FSIZE", "4");
230 Builder.defineMacro("_EM_DSIZE", "8");
231 DefineStd(Builder, "unix", Opts);
232 }
233public:
234 MinixTargetInfo(const std::string &triple)
235 : OSTargetInfo<Target>(triple) {
236 this->UserLabelPrefix = "";
237 }
238};
239
Torok Edwin5f6c1942009-06-30 17:10:35 +0000240// Linux target
241template<typename Target>
242class LinuxTargetInfo : public OSTargetInfo<Target> {
243protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000244 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000245 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000246 // Linux defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000247 DefineStd(Builder, "unix", Opts);
248 DefineStd(Builder, "linux", Opts);
249 Builder.defineMacro("__gnu_linux__");
250 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000251 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000252 Builder.defineMacro("_REENTRANT");
Douglas Gregor2b003fd2010-04-21 05:52:38 +0000253 if (Opts.CPlusPlus)
254 Builder.defineMacro("_GNU_SOURCE");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000255 }
256public:
Mike Stump1eb44332009-09-09 15:08:12 +0000257 LinuxTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000258 : OSTargetInfo<Target>(triple) {
259 this->UserLabelPrefix = "";
260 }
261};
262
Chris Lattnerb62bb282009-07-13 20:29:08 +0000263// NetBSD Target
264template<typename Target>
265class NetBSDTargetInfo : public OSTargetInfo<Target> {
266protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000267 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000268 MacroBuilder &Builder) const {
Chris Lattnerb62bb282009-07-13 20:29:08 +0000269 // NetBSD defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000270 Builder.defineMacro("__NetBSD__");
271 Builder.defineMacro("__unix__");
272 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000273 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000274 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerb62bb282009-07-13 20:29:08 +0000275 }
276public:
Mike Stump1eb44332009-09-09 15:08:12 +0000277 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerb62bb282009-07-13 20:29:08 +0000278 : OSTargetInfo<Target>(triple) {
279 this->UserLabelPrefix = "";
280 }
281};
282
Torok Edwin5f6c1942009-06-30 17:10:35 +0000283// OpenBSD Target
284template<typename Target>
285class OpenBSDTargetInfo : public OSTargetInfo<Target> {
286protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000287 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000288 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000289 // OpenBSD defines; list based off of gcc output
290
Benjamin Kramera9992772010-01-09 17:55:51 +0000291 Builder.defineMacro("__OpenBSD__");
292 DefineStd(Builder, "unix", Opts);
293 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000294 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000295 Builder.defineMacro("_POSIX_THREADS");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000296 }
297public:
Mike Stump1eb44332009-09-09 15:08:12 +0000298 OpenBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000299 : OSTargetInfo<Target>(triple) {}
300};
301
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000302// PSP Target
303template<typename Target>
304class PSPTargetInfo : public OSTargetInfo<Target> {
305protected:
306 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000307 MacroBuilder &Builder) const {
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000308 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramera9992772010-01-09 17:55:51 +0000309 Builder.defineMacro("PSP");
310 Builder.defineMacro("_PSP");
311 Builder.defineMacro("__psp__");
312 Builder.defineMacro("__ELF__");
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000313 }
314public:
315 PSPTargetInfo(const std::string& triple)
316 : OSTargetInfo<Target>(triple) {
317 this->UserLabelPrefix = "";
318 }
319};
320
John Thompson3f6918a2009-11-19 17:18:50 +0000321// PS3 PPU Target
322template<typename Target>
323class PS3PPUTargetInfo : public OSTargetInfo<Target> {
324protected:
325 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000326 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000327 // PS3 PPU defines.
John Thompsonfb457972010-03-25 16:18:32 +0000328 Builder.defineMacro("__PPC__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000329 Builder.defineMacro("__PPU__");
330 Builder.defineMacro("__CELLOS_LV2__");
331 Builder.defineMacro("__ELF__");
332 Builder.defineMacro("__LP32__");
John Thompson8e6065a2010-06-24 22:44:13 +0000333 Builder.defineMacro("_ARCH_PPC64");
334 Builder.defineMacro("__powerpc64__");
John Thompson3f6918a2009-11-19 17:18:50 +0000335 }
336public:
337 PS3PPUTargetInfo(const std::string& triple)
338 : OSTargetInfo<Target>(triple) {
339 this->UserLabelPrefix = "";
John Thompsonec387af2009-12-18 14:21:08 +0000340 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
John Thompson8e6065a2010-06-24 22:44:13 +0000341 this->IntMaxType = TargetInfo::SignedLongLong;
342 this->UIntMaxType = TargetInfo::UnsignedLongLong;
343 this->Int64Type = TargetInfo::SignedLongLong;
John Thompsonec387af2009-12-18 14:21:08 +0000344 this->SizeType = TargetInfo::UnsignedInt;
John Thompson8e6065a2010-06-24 22:44:13 +0000345 this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
346 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
John Thompson3f6918a2009-11-19 17:18:50 +0000347 }
348};
349
350// FIXME: Need a real SPU target.
351// PS3 SPU Target
352template<typename Target>
353class PS3SPUTargetInfo : public OSTargetInfo<Target> {
354protected:
355 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000356 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000357 // PS3 PPU defines.
Benjamin Kramera9992772010-01-09 17:55:51 +0000358 Builder.defineMacro("__SPU__");
359 Builder.defineMacro("__ELF__");
John Thompson3f6918a2009-11-19 17:18:50 +0000360 }
361public:
362 PS3SPUTargetInfo(const std::string& triple)
363 : OSTargetInfo<Target>(triple) {
364 this->UserLabelPrefix = "";
365 }
366};
367
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000368// AuroraUX target
369template<typename Target>
370class AuroraUXTargetInfo : public OSTargetInfo<Target> {
371protected:
372 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000373 MacroBuilder &Builder) const {
374 DefineStd(Builder, "sun", Opts);
375 DefineStd(Builder, "unix", Opts);
376 Builder.defineMacro("__ELF__");
377 Builder.defineMacro("__svr4__");
378 Builder.defineMacro("__SVR4");
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000379 }
380public:
381 AuroraUXTargetInfo(const std::string& triple)
382 : OSTargetInfo<Target>(triple) {
383 this->UserLabelPrefix = "";
384 this->WCharType = this->SignedLong;
385 // FIXME: WIntType should be SignedLong
386 }
387};
388
Torok Edwin5f6c1942009-06-30 17:10:35 +0000389// Solaris target
390template<typename Target>
391class SolarisTargetInfo : public OSTargetInfo<Target> {
392protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000393 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000394 MacroBuilder &Builder) const {
395 DefineStd(Builder, "sun", Opts);
396 DefineStd(Builder, "unix", Opts);
397 Builder.defineMacro("__ELF__");
398 Builder.defineMacro("__svr4__");
399 Builder.defineMacro("__SVR4");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000400 }
401public:
Mike Stump1eb44332009-09-09 15:08:12 +0000402 SolarisTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000403 : OSTargetInfo<Target>(triple) {
404 this->UserLabelPrefix = "";
405 this->WCharType = this->SignedLong;
406 // FIXME: WIntType should be SignedLong
407 }
408};
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000409
410// Windows target
411template<typename Target>
412class WindowsTargetInfo : public OSTargetInfo<Target> {
413protected:
414 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
415 MacroBuilder &Builder) const {
Michael J. Spencera764e832010-10-21 08:22:51 +0000416 Builder.defineMacro("_WIN32");
417 }
418 void getVisualStudioDefines(const LangOptions &Opts,
419 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000420 if (Opts.CPlusPlus) {
421 if (Opts.RTTI)
422 Builder.defineMacro("_CPPRTTI");
423
424 if (Opts.Exceptions)
425 Builder.defineMacro("_CPPUNWIND");
426 }
427
428 if (!Opts.CharIsSigned)
429 Builder.defineMacro("_CHAR_UNSIGNED");
430
431 // FIXME: POSIXThreads isn't exactly the option this should be defined for,
432 // but it works for now.
433 if (Opts.POSIXThreads)
434 Builder.defineMacro("_MT");
Michael J. Spencera764e832010-10-21 08:22:51 +0000435
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000436 if (Opts.MSCVersion != 0)
437 Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
438
439 if (Opts.Microsoft) {
440 Builder.defineMacro("_MSC_EXTENSIONS");
441
442 if (Opts.CPlusPlus0x) {
443 Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
444 Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
445 Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
446 }
447 }
448
449 Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000450 }
451
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000452public:
453 WindowsTargetInfo(const std::string &triple)
454 : OSTargetInfo<Target>(triple) {}
455};
456
Mike Stump1eb44332009-09-09 15:08:12 +0000457} // end anonymous namespace.
Torok Edwin5f6c1942009-06-30 17:10:35 +0000458
Chris Lattnerd29b6302008-10-05 21:50:58 +0000459//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000460// Specific target implementations.
461//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000462
Eli Friedmane4277982008-08-20 23:11:40 +0000463namespace {
464// PPC abstract base class
465class PPCTargetInfo : public TargetInfo {
466 static const Builtin::Info BuiltinInfo[];
467 static const char * const GCCRegNames[];
468 static const TargetInfo::GCCRegAlias GCCRegAliases[];
469
470public:
Eli Friedman15b91762009-06-05 07:05:05 +0000471 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
472
Eli Friedmane4277982008-08-20 23:11:40 +0000473 virtual void getTargetBuiltins(const Builtin::Info *&Records,
474 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000475 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000476 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000477 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000478
Chris Lattner33328642009-03-20 15:52:06 +0000479 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000480 MacroBuilder &Builder) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000481
Eli Friedmane4277982008-08-20 23:11:40 +0000482 virtual const char *getVAListDeclaration() const {
Chris Lattnerd5998502008-10-27 01:11:29 +0000483 return "typedef char* __builtin_va_list;";
484 // This is the right definition for ABI/V4: System V.4/eabi.
485 /*return "typedef struct __va_list_tag {"
Eli Friedmane4277982008-08-20 23:11:40 +0000486 " unsigned char gpr;"
487 " unsigned char fpr;"
488 " unsigned short reserved;"
489 " void* overflow_arg_area;"
490 " void* reg_save_area;"
Chris Lattnerd5998502008-10-27 01:11:29 +0000491 "} __builtin_va_list[1];";*/
Anders Carlsson3346ae62007-11-24 23:38:12 +0000492 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000493 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000494 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000495 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000496 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000497 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000498 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000499 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000500 default: return false;
501 case 'O': // Zero
John Thompson8e6065a2010-06-24 22:44:13 +0000502 break;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000503 case 'b': // Base register
504 case 'f': // Floating point register
Chris Lattner44def072009-04-26 07:16:29 +0000505 Info.setAllowsRegister();
John Thompson8e6065a2010-06-24 22:44:13 +0000506 break;
507 // FIXME: The following are added to allow parsing.
508 // I just took a guess at what the actions should be.
509 // Also, is more specific checking needed? I.e. specific registers?
Michael J. Spencer20249a12010-10-21 03:16:25 +0000510 case 'd': // Floating point register (containing 64-bit value)
John Thompson8e6065a2010-06-24 22:44:13 +0000511 case 'v': // Altivec vector register
512 Info.setAllowsRegister();
513 break;
514 case 'w':
515 switch (Name[1]) {
Michael J. Spencer20249a12010-10-21 03:16:25 +0000516 case 'd':// VSX vector register to hold vector double data
517 case 'f':// VSX vector register to hold vector float data
518 case 's':// VSX vector register to hold scalar float data
519 case 'a':// Any VSX register
John Thompson8e6065a2010-06-24 22:44:13 +0000520 break;
521 default:
522 return false;
523 }
524 Info.setAllowsRegister();
525 Name++; // Skip over 'w'.
526 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000527 case 'h': // `MQ', `CTR', or `LINK' register
528 case 'q': // `MQ' register
529 case 'c': // `CTR' register
530 case 'l': // `LINK' register
531 case 'x': // `CR' register (condition register) number 0
532 case 'y': // `CR' register (condition register)
533 case 'z': // `XER[CA]' carry bit (part of the XER register)
John Thompson8e6065a2010-06-24 22:44:13 +0000534 Info.setAllowsRegister();
535 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000536 case 'I': // Signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000537 case 'J': // Unsigned 16-bit constant shifted left 16 bits
Michael J. Spencer20249a12010-10-21 03:16:25 +0000538 // (use `L' instead for SImode constants)
539 case 'K': // Unsigned 16-bit constant
540 case 'L': // Signed 16-bit constant shifted left 16 bits
541 case 'M': // Constant larger than 31
542 case 'N': // Exact power of 2
543 case 'P': // Constant whose negation is a signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000544 case 'G': // Floating point constant that can be loaded into a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000545 // register with one instruction per word
John Thompson8e6065a2010-06-24 22:44:13 +0000546 case 'H': // Integer/Floating point constant that can be loaded
Michael J. Spencer20249a12010-10-21 03:16:25 +0000547 // into a register using three instructions
John Thompson8e6065a2010-06-24 22:44:13 +0000548 break;
549 case 'm': // Memory operand. Note that on PowerPC targets, m can
550 // include addresses that update the base register. It
551 // is therefore only safe to use `m' in an asm statement
552 // if that asm statement accesses the operand exactly once.
553 // The asm statement must also use `%U<opno>' as a
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000554 // placeholder for the "update" flag in the corresponding
Michael J. Spencer20249a12010-10-21 03:16:25 +0000555 // load or store instruction. For example:
John Thompson8e6065a2010-06-24 22:44:13 +0000556 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
Michael J. Spencer20249a12010-10-21 03:16:25 +0000557 // is correct but:
John Thompson8e6065a2010-06-24 22:44:13 +0000558 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
559 // is not. Use es rather than m if you don't want the base
Michael J. Spencer20249a12010-10-21 03:16:25 +0000560 // register to be updated.
561 case 'e':
John Thompson56b6eca2010-06-25 00:02:05 +0000562 if (Name[1] != 's')
563 return false;
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000564 // es: A "stable" memory operand; that is, one which does not
John Thompson8e6065a2010-06-24 22:44:13 +0000565 // include any automodification of the base register. Unlike
566 // `m', this constraint can be used in asm statements that
567 // might access the operand several times, or that might not
John Thompson56b6eca2010-06-25 00:02:05 +0000568 // access it at all.
John Thompson8e6065a2010-06-24 22:44:13 +0000569 Info.setAllowsMemory();
John Thompson56b6eca2010-06-25 00:02:05 +0000570 Name++; // Skip over 'e'.
John Thompson8e6065a2010-06-24 22:44:13 +0000571 break;
572 case 'Q': // Memory operand that is an offset from a register (it is
Michael J. Spencer20249a12010-10-21 03:16:25 +0000573 // usually better to use `m' or `es' in asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000574 case 'Z': // Memory operand that is an indexed or indirect from a
575 // register (it is usually better to use `m' or `es' in
Michael J. Spencer20249a12010-10-21 03:16:25 +0000576 // asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000577 Info.setAllowsMemory();
578 Info.setAllowsRegister();
579 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000580 case 'R': // AIX TOC entry
John Thompson8e6065a2010-06-24 22:44:13 +0000581 case 'a': // Address operand that is an indexed or indirect from a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000582 // register (`p' is preferable for asm statements)
583 case 'S': // Constant suitable as a 64-bit mask operand
584 case 'T': // Constant suitable as a 32-bit mask operand
585 case 'U': // System V Release 4 small data area reference
John Thompson8e6065a2010-06-24 22:44:13 +0000586 case 't': // AND masks that can be performed by two rldic{l, r}
Michael J. Spencer20249a12010-10-21 03:16:25 +0000587 // instructions
588 case 'W': // Vector constant that does not require memory
589 case 'j': // Vector constant that is all zeros.
John Thompson8e6065a2010-06-24 22:44:13 +0000590 break;
591 // End FIXME.
Anders Carlssond04c6e22007-11-27 04:11:28 +0000592 }
John Thompson8e6065a2010-06-24 22:44:13 +0000593 return true;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000594 }
Eli Friedmane4277982008-08-20 23:11:40 +0000595 virtual const char *getClobbers() const {
596 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000597 }
Eli Friedmane4277982008-08-20 23:11:40 +0000598};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000599
Eli Friedmane4277982008-08-20 23:11:40 +0000600const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000601#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
602#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000603#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmane4277982008-08-20 23:11:40 +0000604};
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000605
606
Chris Lattnerc0f59212009-03-02 22:27:17 +0000607/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
608/// #defines that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000609void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000610 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000611 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +0000612 Builder.defineMacro("__ppc__");
613 Builder.defineMacro("_ARCH_PPC");
Chris Lattnere03ae302010-02-16 18:14:57 +0000614 Builder.defineMacro("__powerpc__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000615 Builder.defineMacro("__POWERPC__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000616 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000617 Builder.defineMacro("_ARCH_PPC64");
618 Builder.defineMacro("_LP64");
619 Builder.defineMacro("__LP64__");
Chris Lattnere03ae302010-02-16 18:14:57 +0000620 Builder.defineMacro("__powerpc64__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000621 Builder.defineMacro("__ppc64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000622 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +0000623 Builder.defineMacro("__ppc__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000624 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000625
Chris Lattnerc0f59212009-03-02 22:27:17 +0000626 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +0000627 Builder.defineMacro("_BIG_ENDIAN");
628 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000629
Chris Lattnerc0f59212009-03-02 22:27:17 +0000630 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +0000631 Builder.defineMacro("__NATURAL_ALIGNMENT__");
632 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000633
Chris Lattnerc0f59212009-03-02 22:27:17 +0000634 // FIXME: Should be controlled by command line option.
Benjamin Kramera9992772010-01-09 17:55:51 +0000635 Builder.defineMacro("__LONG_DOUBLE_128__");
Michael J. Spencer20249a12010-10-21 03:16:25 +0000636
John Thompson3f6918a2009-11-19 17:18:50 +0000637 if (Opts.AltiVec) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000638 Builder.defineMacro("__VEC__", "10206");
639 Builder.defineMacro("__ALTIVEC__");
John Thompson3f6918a2009-11-19 17:18:50 +0000640 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000641}
642
Chris Lattner393ff042008-04-21 18:56:49 +0000643
Eli Friedmane4277982008-08-20 23:11:40 +0000644const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnere94e0d42009-09-16 05:05:27 +0000645 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
646 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
647 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
648 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
649 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
650 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
651 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
652 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmane4277982008-08-20 23:11:40 +0000653 "mq", "lr", "ctr", "ap",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000654 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmane4277982008-08-20 23:11:40 +0000655 "xer",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000656 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
657 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
658 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
659 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmane4277982008-08-20 23:11:40 +0000660 "vrsave", "vscr",
661 "spe_acc", "spefscr",
662 "sfp"
663};
Reid Spencer5f016e22007-07-11 17:01:13 +0000664
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000665void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000666 unsigned &NumNames) const {
667 Names = GCCRegNames;
668 NumNames = llvm::array_lengthof(GCCRegNames);
669}
Reid Spencer5f016e22007-07-11 17:01:13 +0000670
Eli Friedmane4277982008-08-20 23:11:40 +0000671const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
672 // While some of these aliases do map to different registers
673 // they still share the same register name.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000674 { { "0" }, "r0" },
675 { { "1"}, "r1" },
676 { { "2" }, "r2" },
677 { { "3" }, "r3" },
678 { { "4" }, "r4" },
679 { { "5" }, "r5" },
680 { { "6" }, "r6" },
681 { { "7" }, "r7" },
682 { { "8" }, "r8" },
683 { { "9" }, "r9" },
684 { { "10" }, "r10" },
685 { { "11" }, "r11" },
686 { { "12" }, "r12" },
687 { { "13" }, "r13" },
688 { { "14" }, "r14" },
689 { { "15" }, "r15" },
690 { { "16" }, "r16" },
691 { { "17" }, "r17" },
692 { { "18" }, "r18" },
693 { { "19" }, "r19" },
694 { { "20" }, "r20" },
695 { { "21" }, "r21" },
696 { { "22" }, "r22" },
697 { { "23" }, "r23" },
698 { { "24" }, "r24" },
699 { { "25" }, "r25" },
700 { { "26" }, "r26" },
701 { { "27" }, "r27" },
702 { { "28" }, "r28" },
703 { { "29" }, "r29" },
704 { { "30" }, "r30" },
705 { { "31" }, "r31" },
706 { { "fr0" }, "f0" },
707 { { "fr1" }, "f1" },
708 { { "fr2" }, "f2" },
709 { { "fr3" }, "f3" },
710 { { "fr4" }, "f4" },
711 { { "fr5" }, "f5" },
712 { { "fr6" }, "f6" },
713 { { "fr7" }, "f7" },
714 { { "fr8" }, "f8" },
715 { { "fr9" }, "f9" },
Mike Stump10880392009-09-17 21:15:00 +0000716 { { "fr10" }, "f10" },
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000717 { { "fr11" }, "f11" },
718 { { "fr12" }, "f12" },
719 { { "fr13" }, "f13" },
720 { { "fr14" }, "f14" },
721 { { "fr15" }, "f15" },
722 { { "fr16" }, "f16" },
723 { { "fr17" }, "f17" },
724 { { "fr18" }, "f18" },
725 { { "fr19" }, "f19" },
726 { { "fr20" }, "f20" },
727 { { "fr21" }, "f21" },
728 { { "fr22" }, "f22" },
729 { { "fr23" }, "f23" },
730 { { "fr24" }, "f24" },
731 { { "fr25" }, "f25" },
732 { { "fr26" }, "f26" },
733 { { "fr27" }, "f27" },
734 { { "fr28" }, "f28" },
735 { { "fr29" }, "f29" },
736 { { "fr30" }, "f30" },
737 { { "fr31" }, "f31" },
738 { { "cc" }, "cr0" },
Eli Friedmane4277982008-08-20 23:11:40 +0000739};
740
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000741void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000742 unsigned &NumAliases) const {
743 Aliases = GCCRegAliases;
744 NumAliases = llvm::array_lengthof(GCCRegAliases);
745}
746} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000747
748namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000749class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000750public:
Chris Lattnere03ae302010-02-16 18:14:57 +0000751 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedmaned855cb2008-08-21 00:13:15 +0000752 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +0000753 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnere03ae302010-02-16 18:14:57 +0000754
755 if (getTriple().getOS() == llvm::Triple::FreeBSD)
756 this->SizeType = TargetInfo::UnsignedInt;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000757 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000758};
759} // end anonymous namespace.
760
761namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000762class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000763public:
Eli Friedmane4277982008-08-20 23:11:40 +0000764 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000765 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman3c7b6e42009-07-01 03:36:11 +0000766 IntMaxType = SignedLong;
767 UIntMaxType = UnsignedLong;
768 Int64Type = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000769 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +0000770 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerf291b102008-05-09 06:17:04 +0000771 }
Eli Friedmane4277982008-08-20 23:11:40 +0000772};
773} // end anonymous namespace.
774
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000775
776namespace {
777class DarwinPPCTargetInfo :
778 public DarwinTargetInfo<PPCTargetInfo> {
779public:
780 DarwinPPCTargetInfo(const std::string& triple)
781 : DarwinTargetInfo<PPCTargetInfo>(triple) {
782 HasAlignMac68kSupport = true;
783 }
784};
785
786class DarwinPPC64TargetInfo :
787 public DarwinTargetInfo<PPC64TargetInfo> {
788public:
789 DarwinPPC64TargetInfo(const std::string& triple)
790 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
791 HasAlignMac68kSupport = true;
792 }
793};
794} // end anonymous namespace.
795
Reid Spencer5f016e22007-07-11 17:01:13 +0000796namespace {
Chris Lattner9cbeb632010-03-06 21:21:27 +0000797// MBlaze abstract base class
798class MBlazeTargetInfo : public TargetInfo {
799 static const char * const GCCRegNames[];
800 static const TargetInfo::GCCRegAlias GCCRegAliases[];
801
802public:
803 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
804 DescriptionString = "E-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-"
805 "v64:32:32-v128:32:32-n32";
806 }
807
808 virtual void getTargetBuiltins(const Builtin::Info *&Records,
809 unsigned &NumRecords) const {
810 // FIXME: Implement.
811 Records = 0;
812 NumRecords = 0;
813 }
814
815 virtual void getTargetDefines(const LangOptions &Opts,
816 MacroBuilder &Builder) const;
817
818 virtual const char *getVAListDeclaration() const {
819 return "typedef char* __builtin_va_list;";
820 }
821 virtual const char *getTargetPrefix() const {
822 return "mblaze";
823 }
824 virtual void getGCCRegNames(const char * const *&Names,
825 unsigned &NumNames) const;
826 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
827 unsigned &NumAliases) const;
828 virtual bool validateAsmConstraint(const char *&Name,
829 TargetInfo::ConstraintInfo &Info) const {
830 switch (*Name) {
831 default: return false;
832 case 'O': // Zero
833 return true;
834 case 'b': // Base register
835 case 'f': // Floating point register
836 Info.setAllowsRegister();
837 return true;
838 }
839 }
840 virtual const char *getClobbers() const {
841 return "";
842 }
843};
844
845/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
846/// #defines that are not tied to a specific subtarget.
847void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
848 MacroBuilder &Builder) const {
849 // Target identification.
850 Builder.defineMacro("__microblaze__");
851 Builder.defineMacro("_ARCH_MICROBLAZE");
852 Builder.defineMacro("__MICROBLAZE__");
853
854 // Target properties.
855 Builder.defineMacro("_BIG_ENDIAN");
856 Builder.defineMacro("__BIG_ENDIAN__");
857
858 // Subtarget options.
859 Builder.defineMacro("__REGISTER_PREFIX__", "");
860}
861
862
863const char * const MBlazeTargetInfo::GCCRegNames[] = {
864 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
865 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
866 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
867 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
868 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
869 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
870 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
871 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
872 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
873 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
874};
875
876void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
877 unsigned &NumNames) const {
878 Names = GCCRegNames;
879 NumNames = llvm::array_lengthof(GCCRegNames);
880}
881
882const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
883 { {"f0"}, "r0" },
884 { {"f1"}, "r1" },
885 { {"f2"}, "r2" },
886 { {"f3"}, "r3" },
887 { {"f4"}, "r4" },
888 { {"f5"}, "r5" },
889 { {"f6"}, "r6" },
890 { {"f7"}, "r7" },
891 { {"f8"}, "r8" },
892 { {"f9"}, "r9" },
893 { {"f10"}, "r10" },
894 { {"f11"}, "r11" },
895 { {"f12"}, "r12" },
896 { {"f13"}, "r13" },
897 { {"f14"}, "r14" },
898 { {"f15"}, "r15" },
899 { {"f16"}, "r16" },
900 { {"f17"}, "r17" },
901 { {"f18"}, "r18" },
902 { {"f19"}, "r19" },
903 { {"f20"}, "r20" },
904 { {"f21"}, "r21" },
905 { {"f22"}, "r22" },
906 { {"f23"}, "r23" },
907 { {"f24"}, "r24" },
908 { {"f25"}, "r25" },
909 { {"f26"}, "r26" },
910 { {"f27"}, "r27" },
911 { {"f28"}, "r28" },
912 { {"f29"}, "r29" },
913 { {"f30"}, "r30" },
914 { {"f31"}, "r31" },
915};
916
917void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
918 unsigned &NumAliases) const {
919 Aliases = GCCRegAliases;
920 NumAliases = llvm::array_lengthof(GCCRegAliases);
921}
922} // end anonymous namespace.
923
924namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000925// Namespace for x86 abstract base class
926const Builtin::Info BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000927#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
928#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000929#include "clang/Basic/BuiltinsX86.def"
Eli Friedman618234a2008-08-20 02:34:37 +0000930};
Eli Friedman61538a72008-05-20 14:21:01 +0000931
Nuno Lopes2550d702009-12-23 17:49:57 +0000932static const char* const GCCRegNames[] = {
Eli Friedman618234a2008-08-20 02:34:37 +0000933 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
934 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
935 "argp", "flags", "fspr", "dirflag", "frame",
936 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
937 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
938 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
939 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
940};
941
942const TargetInfo::GCCRegAlias GCCRegAliases[] = {
943 { { "al", "ah", "eax", "rax" }, "ax" },
944 { { "bl", "bh", "ebx", "rbx" }, "bx" },
945 { { "cl", "ch", "ecx", "rcx" }, "cx" },
946 { { "dl", "dh", "edx", "rdx" }, "dx" },
947 { { "esi", "rsi" }, "si" },
948 { { "edi", "rdi" }, "di" },
949 { { "esp", "rsp" }, "sp" },
950 { { "ebp", "rbp" }, "bp" },
951};
952
953// X86 target abstract base class; x86-32 and x86-64 are very close, so
954// most of the implementation can be shared.
955class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +0000956 enum X86SSEEnum {
957 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
958 } SSELevel;
Anders Carlsson9b0fb622010-01-27 03:47:49 +0000959 enum AMD3DNowEnum {
960 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
961 } AMD3DNowLevel;
962
Eric Christophereea12d12010-04-02 23:50:19 +0000963 bool HasAES;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000964 bool HasAVX;
965
Eli Friedman618234a2008-08-20 02:34:37 +0000966public:
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000967 X86TargetInfo(const std::string& triple)
Eric Christophereea12d12010-04-02 23:50:19 +0000968 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000969 HasAES(false), HasAVX(false) {
Eli Friedman618234a2008-08-20 02:34:37 +0000970 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000971 }
972 virtual void getTargetBuiltins(const Builtin::Info *&Records,
973 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000974 Records = BuiltinInfo;
975 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000976 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000977 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000978 unsigned &NumNames) const {
979 Names = GCCRegNames;
980 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000981 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000982 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson3346ae62007-11-24 23:38:12 +0000983 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000984 Aliases = GCCRegAliases;
985 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000986 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000987 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000988 TargetInfo::ConstraintInfo &info) const;
Dale Johannesenf6e2c202010-10-29 23:12:32 +0000989 virtual const llvm::Type* adjustInlineAsmType(std::string& Constraint,
990 const llvm::Type* Ty,
991 llvm::LLVMContext& Context) const;
Eli Friedman618234a2008-08-20 02:34:37 +0000992 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000993 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000994 return "~{dirflag},~{fpsr},~{flags}";
995 }
Chris Lattner33328642009-03-20 15:52:06 +0000996 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000997 MacroBuilder &Builder) const;
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000998 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
999 const std::string &Name,
1000 bool Enabled) const;
Mike Stump1eb44332009-09-09 15:08:12 +00001001 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001002 llvm::StringMap<bool> &Features) const;
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001003 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Reid Spencer5f016e22007-07-11 17:01:13 +00001004};
Chris Lattner3daed522009-03-02 22:20:04 +00001005
Mike Stump1eb44332009-09-09 15:08:12 +00001006void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001007 llvm::StringMap<bool> &Features) const {
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001008 // FIXME: This should not be here.
1009 Features["3dnow"] = false;
1010 Features["3dnowa"] = false;
1011 Features["mmx"] = false;
1012 Features["sse"] = false;
1013 Features["sse2"] = false;
1014 Features["sse3"] = false;
1015 Features["ssse3"] = false;
1016 Features["sse41"] = false;
1017 Features["sse42"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001018 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001019 Features["avx"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001020
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001021 // LLVM does not currently recognize this.
1022 // Features["sse4a"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001023
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001024 // FIXME: This *really* should not be here.
1025
1026 // X86_64 always has SSE2.
1027 if (PointerWidth == 64)
1028 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
1029
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001030 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
1031 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
1032 ;
1033 else if (CPU == "pentium-mmx" || CPU == "pentium2")
1034 setFeatureEnabled(Features, "mmx", true);
1035 else if (CPU == "pentium3")
1036 setFeatureEnabled(Features, "sse", true);
1037 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
1038 setFeatureEnabled(Features, "sse2", true);
1039 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
1040 setFeatureEnabled(Features, "sse3", true);
1041 else if (CPU == "core2")
1042 setFeatureEnabled(Features, "ssse3", true);
1043 else if (CPU == "penryn") {
1044 setFeatureEnabled(Features, "sse4", true);
1045 Features["sse42"] = false;
1046 } else if (CPU == "atom")
1047 setFeatureEnabled(Features, "sse3", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001048 else if (CPU == "corei7") {
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001049 setFeatureEnabled(Features, "sse4", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001050 setFeatureEnabled(Features, "aes", true);
1051 }
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001052 else if (CPU == "k6" || CPU == "winchip-c6")
1053 setFeatureEnabled(Features, "mmx", true);
Mike Stump1eb44332009-09-09 15:08:12 +00001054 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001055 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
1056 setFeatureEnabled(Features, "mmx", true);
1057 setFeatureEnabled(Features, "3dnow", true);
1058 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
1059 setFeatureEnabled(Features, "sse", true);
1060 setFeatureEnabled(Features, "3dnowa", true);
1061 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
1062 CPU == "athlon-fx") {
Mike Stump1eb44332009-09-09 15:08:12 +00001063 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001064 setFeatureEnabled(Features, "3dnowa", true);
1065 } else if (CPU == "c3-2")
1066 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001067}
1068
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001069bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump1eb44332009-09-09 15:08:12 +00001070 const std::string &Name,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001071 bool Enabled) const {
Eric Christopherd39ebe22010-03-04 02:26:37 +00001072 // FIXME: This *really* should not be here. We need some way of translating
1073 // options into llvm subtarget features.
1074 if (!Features.count(Name) &&
1075 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001076 return false;
1077
1078 if (Enabled) {
1079 if (Name == "mmx")
1080 Features["mmx"] = true;
1081 else if (Name == "sse")
1082 Features["mmx"] = Features["sse"] = true;
1083 else if (Name == "sse2")
1084 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
1085 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001086 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001087 Features["sse3"] = true;
1088 else if (Name == "ssse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001089 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001090 Features["ssse3"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001091 else if (Name == "sse4" || Name == "sse4.2")
Mike Stump1eb44332009-09-09 15:08:12 +00001092 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001093 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001094 else if (Name == "sse4.1")
1095 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
1096 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001097 else if (Name == "3dnow")
1098 Features["3dnowa"] = true;
1099 else if (Name == "3dnowa")
1100 Features["3dnow"] = Features["3dnowa"] = true;
Eric Christophereea12d12010-04-02 23:50:19 +00001101 else if (Name == "aes")
1102 Features["aes"] = true;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001103 else if (Name == "avx")
1104 Features["avx"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001105 } else {
1106 if (Name == "mmx")
Mike Stump1eb44332009-09-09 15:08:12 +00001107 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001108 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1109 else if (Name == "sse")
Mike Stump1eb44332009-09-09 15:08:12 +00001110 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001111 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1112 else if (Name == "sse2")
Mike Stump1eb44332009-09-09 15:08:12 +00001113 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001114 Features["sse41"] = Features["sse42"] = false;
1115 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001116 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001117 Features["sse42"] = false;
1118 else if (Name == "ssse3")
1119 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1120 else if (Name == "sse4")
1121 Features["sse41"] = Features["sse42"] = false;
Eric Christopherd41b4ec2010-03-04 02:31:44 +00001122 else if (Name == "sse4.2")
1123 Features["sse42"] = false;
1124 else if (Name == "sse4.1")
1125 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001126 else if (Name == "3dnow")
1127 Features["3dnow"] = Features["3dnowa"] = false;
1128 else if (Name == "3dnowa")
1129 Features["3dnowa"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001130 else if (Name == "aes")
1131 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001132 else if (Name == "avx")
1133 Features["avx"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001134 }
1135
1136 return true;
1137}
1138
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001139/// HandleTargetOptions - Perform initialization based on the user
1140/// configured set of features.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001141void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001142 // Remember the maximum enabled sselevel.
1143 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
1144 // Ignore disabled features.
1145 if (Features[i][0] == '-')
1146 continue;
1147
Eric Christophereea12d12010-04-02 23:50:19 +00001148 if (Features[i].substr(1) == "aes") {
1149 HasAES = true;
1150 continue;
1151 }
1152
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001153 // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
1154 // For now let it be enabled together with other SSE levels.
1155 if (Features[i].substr(1) == "avx") {
1156 HasAVX = true;
1157 continue;
1158 }
1159
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001160 assert(Features[i][0] == '+' && "Invalid target feature!");
1161 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
1162 .Case("sse42", SSE42)
1163 .Case("sse41", SSE41)
1164 .Case("ssse3", SSSE3)
Nuno Lopes33d3bca2010-03-12 10:20:09 +00001165 .Case("sse3", SSE3)
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001166 .Case("sse2", SSE2)
1167 .Case("sse", SSE1)
1168 .Case("mmx", MMX)
1169 .Default(NoMMXSSE);
1170 SSELevel = std::max(SSELevel, Level);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001171
1172 AMD3DNowEnum ThreeDNowLevel =
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001173 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
1174 .Case("3dnowa", AMD3DNowAthlon)
1175 .Case("3dnow", AMD3DNow)
1176 .Default(NoAMD3DNow);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001177
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001178 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001179 }
Chris Lattner3daed522009-03-02 22:20:04 +00001180}
Chris Lattnerc0f59212009-03-02 22:27:17 +00001181
1182/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
1183/// that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +00001184void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001185 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001186 // Target identification.
1187 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001188 Builder.defineMacro("_LP64");
1189 Builder.defineMacro("__LP64__");
1190 Builder.defineMacro("__amd64__");
1191 Builder.defineMacro("__amd64");
1192 Builder.defineMacro("__x86_64");
1193 Builder.defineMacro("__x86_64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +00001194 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +00001195 DefineStd(Builder, "i386", Opts);
Chris Lattnerc0f59212009-03-02 22:27:17 +00001196 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001197
Eric Christophereea12d12010-04-02 23:50:19 +00001198 if (HasAES)
1199 Builder.defineMacro("__AES__");
1200
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001201 if (HasAVX)
1202 Builder.defineMacro("__AVX__");
1203
Chris Lattnerc0f59212009-03-02 22:27:17 +00001204 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001205 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001206
Chris Lattnerc0f59212009-03-02 22:27:17 +00001207 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +00001208 Builder.defineMacro("__nocona");
1209 Builder.defineMacro("__nocona__");
1210 Builder.defineMacro("__tune_nocona__");
1211 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001212
Chris Lattner54175442009-04-19 17:32:33 +00001213 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
1214 // functions in glibc header files that use FP Stack inline asm which the
1215 // backend can't deal with (PR879).
Benjamin Kramera9992772010-01-09 17:55:51 +00001216 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001217
Chris Lattner84f0ea82009-03-02 22:40:39 +00001218 // Each case falls through to the previous one here.
1219 switch (SSELevel) {
1220 case SSE42:
Benjamin Kramera9992772010-01-09 17:55:51 +00001221 Builder.defineMacro("__SSE4_2__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001222 case SSE41:
Benjamin Kramera9992772010-01-09 17:55:51 +00001223 Builder.defineMacro("__SSE4_1__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001224 case SSSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001225 Builder.defineMacro("__SSSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001226 case SSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001227 Builder.defineMacro("__SSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001228 case SSE2:
Benjamin Kramera9992772010-01-09 17:55:51 +00001229 Builder.defineMacro("__SSE2__");
1230 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001231 case SSE1:
Benjamin Kramera9992772010-01-09 17:55:51 +00001232 Builder.defineMacro("__SSE__");
1233 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001234 case MMX:
Benjamin Kramera9992772010-01-09 17:55:51 +00001235 Builder.defineMacro("__MMX__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001236 case NoMMXSSE:
1237 break;
1238 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001239
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001240 if (Opts.Microsoft && PointerWidth == 32) {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001241 switch (SSELevel) {
Michael J. Spencera764e832010-10-21 08:22:51 +00001242 case SSE42:
1243 case SSE41:
1244 case SSSE3:
1245 case SSE3:
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001246 case SSE2:
1247 Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
1248 break;
1249 case SSE1:
1250 Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
1251 break;
1252 default:
1253 Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
1254 }
1255 }
1256
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001257 // Each case falls through to the previous one here.
1258 switch (AMD3DNowLevel) {
1259 case AMD3DNowAthlon:
1260 Builder.defineMacro("__3dNOW_A__");
1261 case AMD3DNow:
1262 Builder.defineMacro("__3dNOW__");
1263 case NoAMD3DNow:
1264 break;
1265 }
Chris Lattnerc0f59212009-03-02 22:27:17 +00001266}
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001267
1268
Eli Friedman618234a2008-08-20 02:34:37 +00001269bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001270X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001271 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001272 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +00001273 default: return false;
Dale Johannesen545be512010-08-24 22:33:12 +00001274 case 'Y': // first letter of a pair:
1275 switch (*(Name+1)) {
1276 default: return false;
1277 case '0': // First SSE register.
1278 case 't': // Any SSE register, when SSE2 is enabled.
1279 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1280 case 'm': // any MMX register, when inter-unit moves enabled.
1281 break; // falls through to setAllowsRegister.
1282 }
Eli Friedman618234a2008-08-20 02:34:37 +00001283 case 'a': // eax.
1284 case 'b': // ebx.
1285 case 'c': // ecx.
1286 case 'd': // edx.
1287 case 'S': // esi.
1288 case 'D': // edi.
1289 case 'A': // edx:eax.
Dale Johannesen545be512010-08-24 22:33:12 +00001290 case 'f': // any x87 floating point stack register.
Eli Friedman618234a2008-08-20 02:34:37 +00001291 case 't': // top of floating point stack.
1292 case 'u': // second from top of floating point stack.
1293 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +00001294 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +00001295 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +00001296 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Dale Johannesen545be512010-08-24 22:33:12 +00001297 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1298 case 'l': // "Index" registers: any general register that can be used as an
1299 // index in a base+index memory access.
1300 Info.setAllowsRegister();
1301 return true;
1302 case 'C': // SSE floating point constant.
1303 case 'G': // x87 floating point constant.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001304 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001305 // x86_64 instructions.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001306 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001307 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +00001308 return true;
1309 }
Dale Johannesen545be512010-08-24 22:33:12 +00001310 return false;
Eli Friedman618234a2008-08-20 02:34:37 +00001311}
1312
Dale Johannesenf6e2c202010-10-29 23:12:32 +00001313const llvm::Type*
1314X86TargetInfo::adjustInlineAsmType(std::string& Constraint,
1315 const llvm::Type* Ty,
1316 llvm::LLVMContext &Context) const {
1317 if (Constraint=="y" && Ty->isVectorTy())
1318 return llvm::Type::getX86_MMXTy(Context);
1319 return Ty;
1320}
1321
1322
Eli Friedman618234a2008-08-20 02:34:37 +00001323std::string
1324X86TargetInfo::convertConstraint(const char Constraint) const {
1325 switch (Constraint) {
1326 case 'a': return std::string("{ax}");
1327 case 'b': return std::string("{bx}");
1328 case 'c': return std::string("{cx}");
1329 case 'd': return std::string("{dx}");
1330 case 'S': return std::string("{si}");
1331 case 'D': return std::string("{di}");
Dale Johannesencee55012010-10-22 21:07:10 +00001332 case 'p': // address
1333 return std::string("im");
Eli Friedman618234a2008-08-20 02:34:37 +00001334 case 't': // top of floating point stack.
1335 return std::string("{st}");
1336 case 'u': // second from top of floating point stack.
1337 return std::string("{st(1)}"); // second from top of floating point stack.
1338 default:
1339 return std::string(1, Constraint);
1340 }
1341}
Eli Friedman618234a2008-08-20 02:34:37 +00001342} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +00001343
1344namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001345// X86-32 generic target
1346class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +00001347public:
Eli Friedman618234a2008-08-20 02:34:37 +00001348 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
1349 DoubleAlign = LongLongAlign = 32;
1350 LongDoubleWidth = 96;
1351 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001352 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1353 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001354 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman1afabd92009-03-29 20:31:09 +00001355 SizeType = UnsignedInt;
1356 PtrDiffType = SignedInt;
1357 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001358 RegParmMax = 3;
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001359
1360 // Use fpret for all types.
1361 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
1362 (1 << TargetInfo::Double) |
1363 (1 << TargetInfo::LongDouble));
Eli Friedman618234a2008-08-20 02:34:37 +00001364 }
1365 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001366 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +00001367 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001368
Chris Lattner21fb98e2009-09-23 06:06:36 +00001369 int getEHDataRegisterNumber(unsigned RegNo) const {
1370 if (RegNo == 0) return 0;
1371 if (RegNo == 1) return 2;
1372 return -1;
1373 }
Eli Friedman618234a2008-08-20 02:34:37 +00001374};
1375} // end anonymous namespace
1376
1377namespace {
Eli Friedman624c1462009-07-05 18:47:56 +00001378class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
1379public:
1380 OpenBSDI386TargetInfo(const std::string& triple) :
1381 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
1382 SizeType = UnsignedLong;
1383 IntPtrType = SignedLong;
Eli Friedman6036ebe2009-07-05 22:31:18 +00001384 PtrDiffType = SignedLong;
Eli Friedman624c1462009-07-05 18:47:56 +00001385 }
1386};
1387} // end anonymous namespace
1388
1389namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +00001390class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman618234a2008-08-20 02:34:37 +00001391public:
Torok Edwin5f6c1942009-06-30 17:10:35 +00001392 DarwinI386TargetInfo(const std::string& triple) :
1393 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman618234a2008-08-20 02:34:37 +00001394 LongDoubleWidth = 128;
1395 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +00001396 SizeType = UnsignedLong;
1397 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001398 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1399 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001400 "a0:0:64-f80:128:128-n8:16:32";
Daniel Dunbar613fd672010-05-27 00:35:16 +00001401 HasAlignMac68kSupport = true;
Torok Edwinb0a5b242009-06-30 17:00:25 +00001402 }
1403
Eli Friedman618234a2008-08-20 02:34:37 +00001404};
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001405} // end anonymous namespace
1406
1407namespace {
Eli Friedman29a30502008-08-21 01:40:19 +00001408// x86-32 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001409class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
Eli Friedman29a30502008-08-21 01:40:19 +00001410public:
1411 WindowsX86_32TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001412 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +00001413 TLSSupported = false;
Chris Lattner85de9e72009-06-24 17:12:15 +00001414 WCharType = UnsignedShort;
Eli Friedman9c2f84e2009-06-08 21:16:17 +00001415 DoubleAlign = LongLongAlign = 64;
1416 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Anton Korobeynikovb3814412009-12-19 02:05:07 +00001417 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1418 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedman29a30502008-08-21 01:40:19 +00001419 }
Michael J. Spencera764e832010-10-21 08:22:51 +00001420 virtual void getTargetDefines(const LangOptions &Opts,
1421 MacroBuilder &Builder) const {
1422 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
1423 }
1424};
1425} // end anonymous namespace
1426
1427namespace {
1428
1429// x86-32 Windows Visual Studio target
1430class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1431public:
1432 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1433 : WindowsX86_32TargetInfo(triple) {
1434 LongDoubleWidth = 64;
1435 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1436 }
1437 virtual void getTargetDefines(const LangOptions &Opts,
1438 MacroBuilder &Builder) const {
1439 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1440 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
1441 // The value of the following reflects processor type.
1442 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1443 // We lost the original triple, so we use the default.
1444 Builder.defineMacro("_M_IX86", "600");
1445 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001446};
1447} // end anonymous namespace
1448
1449namespace {
1450// x86-32 MinGW target
1451class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1452public:
1453 MinGWX86_32TargetInfo(const std::string& triple)
1454 : WindowsX86_32TargetInfo(triple) {
1455 }
1456 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001457 MacroBuilder &Builder) const {
1458 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001459 DefineStd(Builder, "WIN32", Opts);
1460 DefineStd(Builder, "WINNT", Opts);
1461 Builder.defineMacro("_X86_");
Benjamin Kramera9992772010-01-09 17:55:51 +00001462 Builder.defineMacro("__MSVCRT__");
1463 Builder.defineMacro("__MINGW32__");
1464 Builder.defineMacro("__declspec", "__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001465 }
1466};
1467} // end anonymous namespace
1468
1469namespace {
1470// x86-32 Cygwin target
1471class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1472public:
1473 CygwinX86_32TargetInfo(const std::string& triple)
1474 : X86_32TargetInfo(triple) {
1475 TLSSupported = false;
1476 WCharType = UnsignedShort;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001477 DoubleAlign = LongLongAlign = 64;
1478 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1479 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001480 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001481 }
1482 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001483 MacroBuilder &Builder) const {
1484 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1485 Builder.defineMacro("__CYGWIN__");
1486 Builder.defineMacro("__CYGWIN32__");
1487 DefineStd(Builder, "unix", Opts);
Douglas Gregor2b003fd2010-04-21 05:52:38 +00001488 if (Opts.CPlusPlus)
1489 Builder.defineMacro("_GNU_SOURCE");
Eli Friedmanabc4e322009-06-08 06:11:14 +00001490 }
Eli Friedman29a30502008-08-21 01:40:19 +00001491};
1492} // end anonymous namespace
1493
1494namespace {
Chris Lattner86ed3a32010-04-11 19:29:39 +00001495// x86-32 Haiku target
1496class HaikuX86_32TargetInfo : public X86_32TargetInfo {
1497public:
1498 HaikuX86_32TargetInfo(const std::string& triple)
1499 : X86_32TargetInfo(triple) {
1500 SizeType = UnsignedLong;
Chris Lattnerfe1ea7b2010-04-22 17:48:00 +00001501 IntPtrType = SignedLong;
1502 PtrDiffType = SignedLong;
Rafael Espindola19ddda82010-11-09 16:41:02 +00001503 this->UserLabelPrefix = "";
Eli Friedmana7e68452010-08-22 01:00:03 +00001504 }
Chris Lattner86ed3a32010-04-11 19:29:39 +00001505 virtual void getTargetDefines(const LangOptions &Opts,
1506 MacroBuilder &Builder) const {
1507 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1508 Builder.defineMacro("__INTEL__");
1509 Builder.defineMacro("__HAIKU__");
1510 }
1511};
1512} // end anonymous namespace
1513
1514namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001515// x86-64 generic target
1516class X86_64TargetInfo : public X86TargetInfo {
1517public:
Chris Lattner33328642009-03-20 15:52:06 +00001518 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +00001519 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +00001520 LongDoubleWidth = 128;
1521 LongDoubleAlign = 128;
Rafael Espindola6deecb02010-06-04 23:15:27 +00001522 LargeArrayMinWidth = 128;
1523 LargeArrayAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +00001524 IntMaxType = SignedLong;
1525 UIntMaxType = UnsignedLong;
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001526 Int64Type = SignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001527 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +00001528
Eli Friedmaned855cb2008-08-21 00:13:15 +00001529 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1530 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001531 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001532
1533 // Use fpret only for long double.
1534 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
Reid Spencer5f016e22007-07-11 17:01:13 +00001535 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +00001536 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001537 return "typedef struct __va_list_tag {"
1538 " unsigned gp_offset;"
1539 " unsigned fp_offset;"
1540 " void* overflow_arg_area;"
1541 " void* reg_save_area;"
John McCall2b7baf02010-05-28 18:25:28 +00001542 "} __va_list_tag;"
Eli Friedmandc043162009-07-03 00:45:06 +00001543 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +00001544 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001545
Chris Lattner21fb98e2009-09-23 06:06:36 +00001546 int getEHDataRegisterNumber(unsigned RegNo) const {
1547 if (RegNo == 0) return 0;
1548 if (RegNo == 1) return 1;
1549 return -1;
1550 }
Eli Friedman618234a2008-08-20 02:34:37 +00001551};
1552} // end anonymous namespace
1553
1554namespace {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001555// x86-64 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001556class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001557public:
1558 WindowsX86_64TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001559 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001560 TLSSupported = false;
1561 WCharType = UnsignedShort;
Mike Stumpa55cce82009-10-08 23:00:00 +00001562 LongWidth = LongAlign = 32;
Michael J. Spencer237cf582010-10-18 07:10:59 +00001563 DoubleAlign = LongLongAlign = 64;
Nate Begemandbf8ea42010-07-21 02:02:56 +00001564 IntMaxType = SignedLongLong;
1565 UIntMaxType = UnsignedLongLong;
1566 Int64Type = SignedLongLong;
Cameron Esfahani1484e0d2010-09-15 00:28:12 +00001567 SizeType = UnsignedLongLong;
1568 PtrDiffType = SignedLongLong;
1569 IntPtrType = SignedLongLong;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001570 }
1571 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001572 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001573 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001574 Builder.defineMacro("_WIN64");
Michael J. Spencera764e832010-10-21 08:22:51 +00001575 }
1576};
1577} // end anonymous namespace
1578
1579namespace {
1580// x86-64 Windows Visual Studio target
1581class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1582public:
1583 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1584 : WindowsX86_64TargetInfo(triple) {
1585 }
1586 virtual void getTargetDefines(const LangOptions &Opts,
1587 MacroBuilder &Builder) const {
1588 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1589 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
Benjamin Kramera9992772010-01-09 17:55:51 +00001590 Builder.defineMacro("_M_X64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001591 Builder.defineMacro("_M_AMD64");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001592 }
Chris Lattnerf13721d2010-08-31 16:44:54 +00001593 virtual const char *getVAListDeclaration() const {
1594 return "typedef char* __builtin_va_list;";
1595 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001596};
1597} // end anonymous namespace
1598
1599namespace {
1600// x86-64 MinGW target
1601class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1602public:
1603 MinGWX86_64TargetInfo(const std::string& triple)
1604 : WindowsX86_64TargetInfo(triple) {
1605 }
1606 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001607 MacroBuilder &Builder) const {
1608 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001609 DefineStd(Builder, "WIN64", Opts);
Benjamin Kramera9992772010-01-09 17:55:51 +00001610 Builder.defineMacro("__MSVCRT__");
1611 Builder.defineMacro("__MINGW64__");
1612 Builder.defineMacro("__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001613 }
1614};
1615} // end anonymous namespace
1616
1617namespace {
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001618class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1619public:
Mike Stump1eb44332009-09-09 15:08:12 +00001620 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001621 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1622 Int64Type = SignedLongLong;
1623 }
1624};
1625} // end anonymous namespace
1626
1627namespace {
Eli Friedman6036ebe2009-07-05 22:31:18 +00001628class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1629public:
Mike Stump1eb44332009-09-09 15:08:12 +00001630 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman6036ebe2009-07-05 22:31:18 +00001631 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1632 IntMaxType = SignedLongLong;
1633 UIntMaxType = UnsignedLongLong;
1634 Int64Type = SignedLongLong;
1635 }
1636};
1637} // end anonymous namespace
1638
1639namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +00001640class ARMTargetInfo : public TargetInfo {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001641 // Possible FPU choices.
1642 enum FPUMode {
1643 NoFPU,
1644 VFP2FPU,
1645 VFP3FPU,
1646 NeonFPU
1647 };
1648
1649 static bool FPUModeIsVFP(FPUMode Mode) {
1650 return Mode >= VFP2FPU && Mode <= NeonFPU;
1651 }
1652
1653 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1654 static const char * const GCCRegNames[];
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001655
Daniel Dunbareac7c532009-12-18 18:42:37 +00001656 std::string ABI, CPU;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001657
1658 unsigned FPU : 3;
1659
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001660 unsigned IsThumb : 1;
1661
1662 // Initialized via features.
1663 unsigned SoftFloat : 1;
1664 unsigned SoftFloatABI : 1;
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001665
Chris Lattner2752c012010-03-03 19:03:45 +00001666 static const Builtin::Info BuiltinInfo[];
1667
Chris Lattner393ff042008-04-21 18:56:49 +00001668public:
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001669 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbareac7c532009-12-18 18:42:37 +00001670 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001671 {
Daniel Dunbara2a41612009-09-14 00:02:24 +00001672 SizeType = UnsignedInt;
1673 PtrDiffType = SignedInt;
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001674
Chris Lattner9bffb072010-04-23 16:29:58 +00001675 // {} in inline assembly are neon specifiers, not assembly variant
1676 // specifiers.
1677 NoAsmVariants = true;
Michael J. Spencer20249a12010-10-21 03:16:25 +00001678
Daniel Dunbareac7c532009-12-18 18:42:37 +00001679 // FIXME: Should we just treat this as a feature?
Daniel Dunbar0791aa52009-12-18 19:57:13 +00001680 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001681 if (IsThumb) {
1682 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1683 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001684 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001685 } else {
1686 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1687 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001688 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001689 }
John McCallee79a4c2010-08-21 22:46:04 +00001690
1691 // ARM targets default to using the ARM C++ ABI.
1692 CXXABI = CXXABI_ARM;
Eli Friedman61538a72008-05-20 14:21:01 +00001693 }
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001694 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbara2a41612009-09-14 00:02:24 +00001695 virtual bool setABI(const std::string &Name) {
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001696 ABI = Name;
1697
Daniel Dunbara2a41612009-09-14 00:02:24 +00001698 // The defaults (above) are for AAPCS, check if we need to change them.
1699 //
1700 // FIXME: We need support for -meabi... we could just mangle it into the
1701 // name.
1702 if (Name == "apcs-gnu") {
Daniel Dunbard410fa22010-01-27 20:23:08 +00001703 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbara2a41612009-09-14 00:02:24 +00001704 SizeType = UnsignedLong;
1705
Daniel Dunbar684de632010-04-22 16:14:54 +00001706 // Do not respect the alignment of bit-field types when laying out
1707 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
1708 UseBitFieldTypeAlignment = false;
1709
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001710 if (IsThumb) {
1711 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1712 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001713 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001714 } else {
1715 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1716 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001717 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001718 }
1719
Daniel Dunbara2a41612009-09-14 00:02:24 +00001720 // FIXME: Override "preferred align" for double and long long.
1721 } else if (Name == "aapcs") {
1722 // FIXME: Enumerated types are variable width in straight AAPCS.
1723 } else if (Name == "aapcs-linux") {
1724 ;
1725 } else
1726 return false;
1727
1728 return true;
1729 }
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001730
Daniel Dunbara91320b2009-12-21 23:28:17 +00001731 void getDefaultFeatures(const std::string &CPU,
1732 llvm::StringMap<bool> &Features) const {
1733 // FIXME: This should not be here.
1734 Features["vfp2"] = false;
1735 Features["vfp3"] = false;
1736 Features["neon"] = false;
1737
1738 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1739 Features["vfp2"] = true;
1740 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1741 Features["neon"] = true;
1742 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001743
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001744 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1745 const std::string &Name,
1746 bool Enabled) const {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001747 if (Name == "soft-float" || Name == "soft-float-abi") {
1748 Features[Name] = Enabled;
1749 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1750 // These effectively are a single option, reset them when any is enabled.
1751 if (Enabled)
1752 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1753 Features[Name] = Enabled;
1754 } else
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001755 return false;
1756
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001757 return true;
1758 }
1759
1760 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001761 FPU = NoFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001762 SoftFloat = SoftFloatABI = false;
1763 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1764 if (Features[i] == "+soft-float")
1765 SoftFloat = true;
1766 else if (Features[i] == "+soft-float-abi")
1767 SoftFloatABI = true;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001768 else if (Features[i] == "+vfp2")
1769 FPU = VFP2FPU;
1770 else if (Features[i] == "+vfp3")
1771 FPU = VFP3FPU;
1772 else if (Features[i] == "+neon")
1773 FPU = NeonFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001774 }
1775
1776 // Remove front-end specific options which the backend handles differently.
1777 std::vector<std::string>::iterator it;
1778 it = std::find(Features.begin(), Features.end(), "+soft-float");
1779 if (it != Features.end())
1780 Features.erase(it);
1781 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1782 if (it != Features.end())
1783 Features.erase(it);
1784 }
1785
Daniel Dunbareac7c532009-12-18 18:42:37 +00001786 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1787 return llvm::StringSwitch<const char*>(Name)
1788 .Cases("arm8", "arm810", "4")
1789 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1790 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1791 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1792 .Case("ep9312", "4T")
1793 .Cases("arm10tdmi", "arm1020t", "5T")
1794 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1795 .Case("arm926ej-s", "5TEJ")
1796 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1797 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001798 .Case("arm1136j-s", "6J")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001799 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001800 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001801 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1802 .Cases("cortex-a8", "cortex-a9", "7A")
1803 .Default(0);
1804 }
1805 virtual bool setCPU(const std::string &Name) {
1806 if (!getCPUDefineSuffix(Name))
1807 return false;
1808
1809 CPU = Name;
1810 return true;
1811 }
Chris Lattner33328642009-03-20 15:52:06 +00001812 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001813 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001814 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +00001815 Builder.defineMacro("__arm");
1816 Builder.defineMacro("__arm__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001817
Chris Lattnerc0f59212009-03-02 22:27:17 +00001818 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001819 Builder.defineMacro("__ARMEL__");
1820 Builder.defineMacro("__LITTLE_ENDIAN__");
1821 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001822
1823 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramera9992772010-01-09 17:55:51 +00001824 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001825
Mike Stump437bb4b2009-04-08 02:07:04 +00001826 // Subtarget options.
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001827
Daniel Dunbareac7c532009-12-18 18:42:37 +00001828 // FIXME: It's more complicated than this and we don't really support
1829 // interworking.
1830 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramera9992772010-01-09 17:55:51 +00001831 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001832
Daniel Dunbareac7c532009-12-18 18:42:37 +00001833 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramera9992772010-01-09 17:55:51 +00001834 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001835
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001836 if (SoftFloat)
Benjamin Kramera9992772010-01-09 17:55:51 +00001837 Builder.defineMacro("__SOFTFP__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001838
1839 if (CPU == "xscale")
Benjamin Kramera9992772010-01-09 17:55:51 +00001840 Builder.defineMacro("__XSCALE__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001841
Daniel Dunbara91320b2009-12-21 23:28:17 +00001842 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001843 if (IsThumb) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001844 Builder.defineMacro("__THUMBEL__");
1845 Builder.defineMacro("__thumb__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001846 if (IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001847 Builder.defineMacro("__thumb2__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001848 }
1849
1850 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramera9992772010-01-09 17:55:51 +00001851 Builder.defineMacro("__APCS_32__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001852
1853 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramera9992772010-01-09 17:55:51 +00001854 Builder.defineMacro("__VFP_FP__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001855
1856 // This only gets set when Neon instructions are actually available, unlike
1857 // the VFP define, hence the soft float and arch check. This is subtly
1858 // different from gcc, we follow the intent which was that it should be set
1859 // when Neon instructions are actually available.
1860 if (FPU == NeonFPU && !SoftFloat && IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001861 Builder.defineMacro("__ARM_NEON__");
Chris Lattner393ff042008-04-21 18:56:49 +00001862 }
1863 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1864 unsigned &NumRecords) const {
Chris Lattner2752c012010-03-03 19:03:45 +00001865 Records = BuiltinInfo;
1866 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner393ff042008-04-21 18:56:49 +00001867 }
1868 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001869 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +00001870 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001871 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001872 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001873 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001874 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001875 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001876 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001877 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001878 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +00001879 default:
Nate Begemanad487f42008-04-22 05:03:19 +00001880 case 'l': // r0-r7
1881 case 'h': // r8-r15
1882 case 'w': // VFP Floating point register single precision
1883 case 'P': // VFP Floating point register double precision
Chris Lattner44def072009-04-26 07:16:29 +00001884 Info.setAllowsRegister();
Nate Begemanad487f42008-04-22 05:03:19 +00001885 return true;
1886 }
Chris Lattner393ff042008-04-21 18:56:49 +00001887 return false;
1888 }
1889 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001890 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +00001891 return "";
1892 }
1893};
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001894
1895const char * const ARMTargetInfo::GCCRegNames[] = {
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001896 // Integer registers
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001897 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001898 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
1899
1900 // Float registers
1901 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1902 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
1903 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001904 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001905
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001906 // Double registers
1907 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
1908 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
Dale Johannesend1455352010-10-28 01:05:37 +00001909 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
1910 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001911
1912 // Quad registers
Dale Johannesend1455352010-10-28 01:05:37 +00001913 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
1914 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001915};
1916
1917void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001918 unsigned &NumNames) const {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001919 Names = GCCRegNames;
1920 NumNames = llvm::array_lengthof(GCCRegNames);
1921}
1922
1923const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001924 { { "a1" }, "r0" },
1925 { { "a2" }, "r1" },
1926 { { "a3" }, "r2" },
1927 { { "a4" }, "r3" },
1928 { { "v1" }, "r4" },
1929 { { "v2" }, "r5" },
1930 { { "v3" }, "r6" },
1931 { { "v4" }, "r7" },
1932 { { "v5" }, "r8" },
1933 { { "v6", "rfp" }, "r9" },
1934 { { "sl" }, "r10" },
1935 { { "fp" }, "r11" },
1936 { { "ip" }, "r12" },
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001937 { { "r13" }, "sp" },
1938 { { "r14" }, "lr" },
1939 { { "r15" }, "pc" },
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001940 // The S, D and Q registers overlap, but aren't really aliases; we
1941 // don't want to substitute one of these for a different-sized one.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001942};
1943
1944void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1945 unsigned &NumAliases) const {
1946 Aliases = GCCRegAliases;
1947 NumAliases = llvm::array_lengthof(GCCRegAliases);
1948}
Chris Lattner2752c012010-03-03 19:03:45 +00001949
1950const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
1951#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
1952#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
1953#include "clang/Basic/BuiltinsARM.def"
1954};
Chris Lattner393ff042008-04-21 18:56:49 +00001955} // end anonymous namespace.
1956
Eli Friedmana9f54962008-08-20 07:44:10 +00001957
1958namespace {
Mike Stump1eb44332009-09-09 15:08:12 +00001959class DarwinARMTargetInfo :
Torok Edwin5f6c1942009-06-30 17:10:35 +00001960 public DarwinTargetInfo<ARMTargetInfo> {
1961protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +00001962 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +00001963 MacroBuilder &Builder) const {
Daniel Dunbar21ae3192010-01-26 01:44:04 +00001964 getDarwinDefines(Builder, Opts, Triple);
Eli Friedmanb030f022009-04-19 21:38:35 +00001965 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001966
Torok Edwin5f6c1942009-06-30 17:10:35 +00001967public:
Mike Stump1eb44332009-09-09 15:08:12 +00001968 DarwinARMTargetInfo(const std::string& triple)
Daniel Dunbar350b9f32010-05-27 07:00:26 +00001969 : DarwinTargetInfo<ARMTargetInfo>(triple) {
1970 HasAlignMac68kSupport = true;
1971 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001972};
1973} // end anonymous namespace.
1974
Reid Spencer5f016e22007-07-11 17:01:13 +00001975namespace {
Eli Friedman01b86682008-08-20 07:28:14 +00001976class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +00001977 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1978 static const char * const GCCRegNames[];
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00001979 bool SoftFloat;
Gabor Greif26658672008-02-21 16:29:08 +00001980public:
Eli Friedman01b86682008-08-20 07:28:14 +00001981 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1982 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +00001983 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001984 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedman01b86682008-08-20 07:28:14 +00001985 }
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00001986 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1987 const std::string &Name,
1988 bool Enabled) const {
1989 if (Name == "soft-float")
1990 Features[Name] = Enabled;
1991 else
1992 return false;
1993
1994 return true;
1995 }
1996 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
1997 SoftFloat = false;
1998 for (unsigned i = 0, e = Features.size(); i != e; ++i)
1999 if (Features[i] == "+soft-float")
2000 SoftFloat = true;
2001 }
Chris Lattner33328642009-03-20 15:52:06 +00002002 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002003 MacroBuilder &Builder) const {
2004 DefineStd(Builder, "sparc", Opts);
2005 Builder.defineMacro("__sparcv8");
2006 Builder.defineMacro("__REGISTER_PREFIX__", "");
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002007
2008 if (SoftFloat)
2009 Builder.defineMacro("SOFT_FLOAT", "1");
Gabor Greif26658672008-02-21 16:29:08 +00002010 }
2011 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2012 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002013 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +00002014 }
2015 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002016 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +00002017 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002018 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002019 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002020 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002021 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00002022 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +00002023 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002024 // FIXME: Implement!
2025 return false;
Gabor Greif26658672008-02-21 16:29:08 +00002026 }
2027 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002028 // FIXME: Implement!
2029 return "";
Gabor Greif26658672008-02-21 16:29:08 +00002030 }
2031};
2032
Chris Lattnere957f532009-01-27 01:58:38 +00002033const char * const SparcV8TargetInfo::GCCRegNames[] = {
2034 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2035 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2036 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2037 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
2038};
2039
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002040void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002041 unsigned &NumNames) const {
2042 Names = GCCRegNames;
2043 NumNames = llvm::array_lengthof(GCCRegNames);
2044}
2045
2046const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002047 { { "g0" }, "r0" },
2048 { { "g1" }, "r1" },
2049 { { "g2" }, "r2" },
2050 { { "g3" }, "r3" },
2051 { { "g4" }, "r4" },
2052 { { "g5" }, "r5" },
2053 { { "g6" }, "r6" },
2054 { { "g7" }, "r7" },
2055 { { "o0" }, "r8" },
2056 { { "o1" }, "r9" },
2057 { { "o2" }, "r10" },
2058 { { "o3" }, "r11" },
2059 { { "o4" }, "r12" },
2060 { { "o5" }, "r13" },
2061 { { "o6", "sp" }, "r14" },
2062 { { "o7" }, "r15" },
2063 { { "l0" }, "r16" },
2064 { { "l1" }, "r17" },
2065 { { "l2" }, "r18" },
2066 { { "l3" }, "r19" },
2067 { { "l4" }, "r20" },
2068 { { "l5" }, "r21" },
2069 { { "l6" }, "r22" },
2070 { { "l7" }, "r23" },
2071 { { "i0" }, "r24" },
2072 { { "i1" }, "r25" },
2073 { { "i2" }, "r26" },
2074 { { "i3" }, "r27" },
2075 { { "i4" }, "r28" },
2076 { { "i5" }, "r29" },
2077 { { "i6", "fp" }, "r30" },
2078 { { "i7" }, "r31" },
Chris Lattnere957f532009-01-27 01:58:38 +00002079};
2080
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002081void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002082 unsigned &NumAliases) const {
2083 Aliases = GCCRegAliases;
2084 NumAliases = llvm::array_lengthof(GCCRegAliases);
2085}
Gabor Greif26658672008-02-21 16:29:08 +00002086} // end anonymous namespace.
2087
Eli Friedman01b86682008-08-20 07:28:14 +00002088namespace {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002089class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
2090public:
2091 AuroraUXSparcV8TargetInfo(const std::string& triple) :
2092 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
2093 SizeType = UnsignedInt;
2094 PtrDiffType = SignedInt;
2095 }
2096};
Torok Edwin5f6c1942009-06-30 17:10:35 +00002097class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedman01b86682008-08-20 07:28:14 +00002098public:
2099 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwin5f6c1942009-06-30 17:10:35 +00002100 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmanf509d732008-11-02 02:43:55 +00002101 SizeType = UnsignedInt;
2102 PtrDiffType = SignedInt;
Eli Friedman01b86682008-08-20 07:28:14 +00002103 }
2104};
2105} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00002106
Chris Lattner2621fd12008-05-08 05:58:21 +00002107namespace {
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002108 class MSP430TargetInfo : public TargetInfo {
2109 static const char * const GCCRegNames[];
2110 public:
2111 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
2112 TLSSupported = false;
Anton Korobeynikov09f52a62010-01-30 12:55:11 +00002113 IntWidth = 16; IntAlign = 16;
2114 LongWidth = 32; LongLongWidth = 64;
2115 LongAlign = LongLongAlign = 16;
2116 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002117 SizeType = UnsignedInt;
2118 IntMaxType = SignedLong;
2119 UIntMaxType = UnsignedLong;
2120 IntPtrType = SignedShort;
2121 PtrDiffType = SignedInt;
Edward O'Callaghan9cf910e2009-11-21 00:49:54 +00002122 SigAtomicType = SignedLong;
Anton Korobeynikov5d7c2512009-12-19 01:32:37 +00002123 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002124 }
2125 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002126 MacroBuilder &Builder) const {
2127 Builder.defineMacro("MSP430");
2128 Builder.defineMacro("__MSP430__");
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002129 // FIXME: defines for different 'flavours' of MCU
2130 }
2131 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2132 unsigned &NumRecords) const {
2133 // FIXME: Implement.
2134 Records = 0;
2135 NumRecords = 0;
2136 }
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002137 virtual void getGCCRegNames(const char * const *&Names,
2138 unsigned &NumNames) const;
2139 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2140 unsigned &NumAliases) const {
2141 // No aliases.
2142 Aliases = 0;
2143 NumAliases = 0;
2144 }
2145 virtual bool validateAsmConstraint(const char *&Name,
2146 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov03265b62009-10-15 23:17:13 +00002147 // No target constraints for now.
2148 return false;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002149 }
2150 virtual const char *getClobbers() const {
2151 // FIXME: Is this really right?
2152 return "";
2153 }
2154 virtual const char *getVAListDeclaration() const {
2155 // FIXME: implement
Anton Korobeynikoveb716852009-05-08 18:24:57 +00002156 return "typedef char* __builtin_va_list;";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002157 }
2158 };
2159
2160 const char * const MSP430TargetInfo::GCCRegNames[] = {
2161 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2162 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2163 };
2164
2165 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
2166 unsigned &NumNames) const {
2167 Names = GCCRegNames;
2168 NumNames = llvm::array_lengthof(GCCRegNames);
2169 }
2170}
2171
2172
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002173namespace {
2174 class SystemZTargetInfo : public TargetInfo {
2175 static const char * const GCCRegNames[];
2176 public:
2177 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
2178 TLSSupported = false;
2179 IntWidth = IntAlign = 32;
2180 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
2181 PointerWidth = PointerAlign = 64;
Chris Lattner1932e122009-11-07 18:59:41 +00002182 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
2183 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002184 }
2185 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002186 MacroBuilder &Builder) const {
2187 Builder.defineMacro("__s390__");
2188 Builder.defineMacro("__s390x__");
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002189 }
2190 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2191 unsigned &NumRecords) const {
2192 // FIXME: Implement.
2193 Records = 0;
2194 NumRecords = 0;
2195 }
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002196
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002197 virtual void getGCCRegNames(const char * const *&Names,
2198 unsigned &NumNames) const;
2199 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2200 unsigned &NumAliases) const {
2201 // No aliases.
2202 Aliases = 0;
2203 NumAliases = 0;
2204 }
2205 virtual bool validateAsmConstraint(const char *&Name,
2206 TargetInfo::ConstraintInfo &info) const {
2207 // FIXME: implement
2208 return true;
2209 }
2210 virtual const char *getClobbers() const {
2211 // FIXME: Is this really right?
2212 return "";
2213 }
2214 virtual const char *getVAListDeclaration() const {
2215 // FIXME: implement
2216 return "typedef char* __builtin_va_list;";
2217 }
2218 };
2219
2220 const char * const SystemZTargetInfo::GCCRegNames[] = {
2221 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2222 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2223 };
2224
2225 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
2226 unsigned &NumNames) const {
2227 Names = GCCRegNames;
2228 NumNames = llvm::array_lengthof(GCCRegNames);
2229 }
2230}
2231
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002232namespace {
2233 class BlackfinTargetInfo : public TargetInfo {
2234 static const char * const GCCRegNames[];
2235 public:
2236 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
2237 TLSSupported = false;
2238 DoubleAlign = 32;
2239 LongLongAlign = 32;
2240 LongDoubleAlign = 32;
Chris Lattner1932e122009-11-07 18:59:41 +00002241 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002242 }
2243
2244 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002245 MacroBuilder &Builder) const {
2246 DefineStd(Builder, "bfin", Opts);
2247 DefineStd(Builder, "BFIN", Opts);
2248 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002249 // FIXME: This one is really dependent on -mcpu
Benjamin Kramera9992772010-01-09 17:55:51 +00002250 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002251 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
2252 }
2253
2254 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2255 unsigned &NumRecords) const {
2256 // FIXME: Implement.
2257 Records = 0;
2258 NumRecords = 0;
2259 }
2260
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002261 virtual void getGCCRegNames(const char * const *&Names,
2262 unsigned &NumNames) const;
2263
2264 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2265 unsigned &NumAliases) const {
2266 // No aliases.
2267 Aliases = 0;
2268 NumAliases = 0;
2269 }
2270
2271 virtual bool validateAsmConstraint(const char *&Name,
2272 TargetInfo::ConstraintInfo &Info) const {
2273 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
2274 Info.setAllowsRegister();
2275 return true;
2276 }
2277 return false;
2278 }
2279
2280 virtual const char *getClobbers() const {
2281 return "";
2282 }
2283
2284 virtual const char *getVAListDeclaration() const {
2285 return "typedef char* __builtin_va_list;";
2286 }
2287 };
2288
2289 const char * const BlackfinTargetInfo::GCCRegNames[] = {
2290 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2291 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
2292 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
2293 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
2294 "a0", "a1", "cc",
2295 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
2296 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
2297 };
2298
2299 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
2300 unsigned &NumNames) const {
2301 Names = GCCRegNames;
2302 NumNames = llvm::array_lengthof(GCCRegNames);
2303 }
2304}
2305
Eli Friedmanb63decf2009-08-19 20:47:07 +00002306namespace {
2307
Mike Stump1eb44332009-09-09 15:08:12 +00002308 // LLVM and Clang cannot be used directly to output native binaries for
2309 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmanb63decf2009-08-19 20:47:07 +00002310 // type and alignment information.
Mike Stump1eb44332009-09-09 15:08:12 +00002311 //
2312 // TCE uses the llvm bitcode as input and uses it for generating customized
2313 // target processor and program binary. TCE co-design environment is
Eli Friedmanb63decf2009-08-19 20:47:07 +00002314 // publicly available in http://tce.cs.tut.fi
2315
2316 class TCETargetInfo : public TargetInfo{
2317 public:
2318 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
2319 TLSSupported = false;
2320 IntWidth = 32;
2321 LongWidth = LongLongWidth = 32;
Eli Friedmanb63decf2009-08-19 20:47:07 +00002322 PointerWidth = 32;
2323 IntAlign = 32;
2324 LongAlign = LongLongAlign = 32;
2325 PointerAlign = 32;
2326 SizeType = UnsignedInt;
2327 IntMaxType = SignedLong;
2328 UIntMaxType = UnsignedLong;
2329 IntPtrType = SignedInt;
2330 PtrDiffType = SignedInt;
2331 FloatWidth = 32;
2332 FloatAlign = 32;
2333 DoubleWidth = 32;
2334 DoubleAlign = 32;
2335 LongDoubleWidth = 32;
2336 LongDoubleAlign = 32;
2337 FloatFormat = &llvm::APFloat::IEEEsingle;
2338 DoubleFormat = &llvm::APFloat::IEEEsingle;
2339 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner3a47c4e2010-03-04 21:07:38 +00002340 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
2341 "i16:16:32-i32:32:32-i64:32:32-"
2342 "f32:32:32-f64:64:64-v64:64:64-"
2343 "v128:128:128-a0:0:64-n32";
Eli Friedmanb63decf2009-08-19 20:47:07 +00002344 }
2345
2346 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002347 MacroBuilder &Builder) const {
2348 DefineStd(Builder, "tce", Opts);
2349 Builder.defineMacro("__TCE__");
2350 Builder.defineMacro("__TCE_V1__");
Eli Friedmanb63decf2009-08-19 20:47:07 +00002351 }
2352 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2353 unsigned &NumRecords) const {}
Daniel Dunbar55cc2ed2009-08-24 09:54:37 +00002354 virtual const char *getClobbers() const {
2355 return "";
2356 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002357 virtual const char *getVAListDeclaration() const {
2358 return "typedef void* __builtin_va_list;";
2359 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002360 virtual void getGCCRegNames(const char * const *&Names,
2361 unsigned &NumNames) const {}
2362 virtual bool validateAsmConstraint(const char *&Name,
2363 TargetInfo::ConstraintInfo &info) const {
2364 return true;
2365 }
2366 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2367 unsigned &NumAliases) const {}
2368 };
2369}
2370
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002371namespace {
2372class MipsTargetInfo : public TargetInfo {
Eric Christophered734732010-03-02 02:41:08 +00002373 std::string ABI, CPU;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002374 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2375 static const char * const GCCRegNames[];
2376public:
Eric Christophered734732010-03-02 02:41:08 +00002377 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002378 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2379 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2380 }
Eric Christophered734732010-03-02 02:41:08 +00002381 virtual const char *getABI() const { return ABI.c_str(); }
2382 virtual bool setABI(const std::string &Name) {
2383
2384 if ((Name == "o32") || (Name == "eabi")) {
2385 ABI = Name;
2386 return true;
2387 } else
2388 return false;
2389 }
2390 virtual bool setCPU(const std::string &Name) {
2391 CPU = Name;
2392 return true;
2393 }
2394 void getDefaultFeatures(const std::string &CPU,
2395 llvm::StringMap<bool> &Features) const {
2396 Features[ABI] = true;
2397 Features[CPU] = true;
2398 }
2399 virtual void getArchDefines(const LangOptions &Opts,
2400 MacroBuilder &Builder) const {
2401 if (ABI == "o32")
2402 Builder.defineMacro("__mips_o32");
2403 else if (ABI == "eabi")
2404 Builder.defineMacro("__mips_eabi");
2405 }
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002406 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002407 MacroBuilder &Builder) const {
2408 DefineStd(Builder, "mips", Opts);
2409 Builder.defineMacro("_mips");
2410 DefineStd(Builder, "MIPSEB", Opts);
2411 Builder.defineMacro("_MIPSEB");
2412 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002413 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002414 }
2415 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2416 unsigned &NumRecords) const {
2417 // FIXME: Implement!
2418 }
2419 virtual const char *getVAListDeclaration() const {
2420 return "typedef void* __builtin_va_list;";
2421 }
2422 virtual void getGCCRegNames(const char * const *&Names,
2423 unsigned &NumNames) const;
2424 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2425 unsigned &NumAliases) const;
2426 virtual bool validateAsmConstraint(const char *&Name,
2427 TargetInfo::ConstraintInfo &Info) const {
2428 switch (*Name) {
2429 default:
2430 case 'r': // CPU registers.
2431 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2432 case 'y': // Equivalent to "r", backwards compatibility only.
2433 case 'f': // floating-point registers.
2434 Info.setAllowsRegister();
2435 return true;
2436 }
2437 return false;
2438 }
2439
2440 virtual const char *getClobbers() const {
2441 // FIXME: Implement!
2442 return "";
2443 }
2444};
2445
2446const char * const MipsTargetInfo::GCCRegNames[] = {
Michael J. Spencer20249a12010-10-21 03:16:25 +00002447 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002448 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2449 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2450 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2451 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2452 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2453 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2454 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2455 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2456 "$fcc5","$fcc6","$fcc7"
2457};
2458
2459void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2460 unsigned &NumNames) const {
2461 Names = GCCRegNames;
2462 NumNames = llvm::array_lengthof(GCCRegNames);
2463}
2464
2465const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2466 { { "at" }, "$1" },
2467 { { "v0" }, "$2" },
2468 { { "v1" }, "$3" },
2469 { { "a0" }, "$4" },
2470 { { "a1" }, "$5" },
2471 { { "a2" }, "$6" },
2472 { { "a3" }, "$7" },
2473 { { "t0" }, "$8" },
2474 { { "t1" }, "$9" },
2475 { { "t2" }, "$10" },
2476 { { "t3" }, "$11" },
2477 { { "t4" }, "$12" },
2478 { { "t5" }, "$13" },
2479 { { "t6" }, "$14" },
2480 { { "t7" }, "$15" },
2481 { { "s0" }, "$16" },
2482 { { "s1" }, "$17" },
2483 { { "s2" }, "$18" },
2484 { { "s3" }, "$19" },
2485 { { "s4" }, "$20" },
2486 { { "s5" }, "$21" },
2487 { { "s6" }, "$22" },
2488 { { "s7" }, "$23" },
2489 { { "t8" }, "$24" },
2490 { { "t9" }, "$25" },
2491 { { "k0" }, "$26" },
2492 { { "k1" }, "$27" },
2493 { { "gp" }, "$28" },
2494 { { "sp" }, "$29" },
2495 { { "fp" }, "$30" },
2496 { { "ra" }, "$31" }
2497};
2498
2499void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2500 unsigned &NumAliases) const {
2501 Aliases = GCCRegAliases;
2502 NumAliases = llvm::array_lengthof(GCCRegAliases);
2503}
2504} // end anonymous namespace.
2505
2506namespace {
2507class MipselTargetInfo : public MipsTargetInfo {
2508public:
2509 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2510 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2511 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2512 }
2513
2514 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002515 MacroBuilder &Builder) const;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002516};
2517
2518void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002519 MacroBuilder &Builder) const {
2520 DefineStd(Builder, "mips", Opts);
2521 Builder.defineMacro("_mips");
2522 DefineStd(Builder, "MIPSEL", Opts);
2523 Builder.defineMacro("_MIPSEL");
2524 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002525 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002526}
2527} // end anonymous namespace.
2528
Reid Spencer5f016e22007-07-11 17:01:13 +00002529//===----------------------------------------------------------------------===//
2530// Driver code
2531//===----------------------------------------------------------------------===//
2532
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002533static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002534 llvm::Triple Triple(T);
2535 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman61538a72008-05-20 14:21:01 +00002536
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002537 switch (Triple.getArch()) {
2538 default:
2539 return NULL;
Eli Friedman61538a72008-05-20 14:21:01 +00002540
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002541 case llvm::Triple::arm:
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +00002542 case llvm::Triple::thumb:
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002543 switch (os) {
Rafael Espindola022a8a52010-06-10 00:46:51 +00002544 case llvm::Triple::Linux:
2545 return new LinuxTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002546 case llvm::Triple::Darwin:
Eli Friedmaned855cb2008-08-21 00:13:15 +00002547 return new DarwinARMTargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002548 case llvm::Triple::FreeBSD:
Torok Edwin5f6c1942009-06-30 17:10:35 +00002549 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002550 default:
2551 return new ARMTargetInfo(T);
2552 }
Eli Friedman61538a72008-05-20 14:21:01 +00002553
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002554 case llvm::Triple::bfin:
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002555 return new BlackfinTargetInfo(T);
2556
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002557 case llvm::Triple::msp430:
2558 return new MSP430TargetInfo(T);
Eli Friedman61538a72008-05-20 14:21:01 +00002559
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002560 case llvm::Triple::mips:
2561 if (os == llvm::Triple::Psp)
2562 return new PSPTargetInfo<MipsTargetInfo>(T);
2563 if (os == llvm::Triple::Linux)
2564 return new LinuxTargetInfo<MipsTargetInfo>(T);
2565 return new MipsTargetInfo(T);
2566
2567 case llvm::Triple::mipsel:
2568 if (os == llvm::Triple::Psp)
2569 return new PSPTargetInfo<MipselTargetInfo>(T);
2570 if (os == llvm::Triple::Linux)
2571 return new LinuxTargetInfo<MipselTargetInfo>(T);
2572 return new MipselTargetInfo(T);
2573
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002574 case llvm::Triple::ppc:
2575 if (os == llvm::Triple::Darwin)
Daniel Dunbar4c6a2262010-05-30 00:07:30 +00002576 return new DarwinPPCTargetInfo(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002577 else if (os == llvm::Triple::FreeBSD)
2578 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002579 return new PPC32TargetInfo(T);
2580
2581 case llvm::Triple::ppc64:
2582 if (os == llvm::Triple::Darwin)
Daniel Dunbar4c6a2262010-05-30 00:07:30 +00002583 return new DarwinPPC64TargetInfo(T);
John Thompson3f6918a2009-11-19 17:18:50 +00002584 else if (os == llvm::Triple::Lv2)
2585 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002586 else if (os == llvm::Triple::FreeBSD)
2587 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002588 return new PPC64TargetInfo(T);
2589
Chris Lattner9cbeb632010-03-06 21:21:27 +00002590 case llvm::Triple::mblaze:
2591 return new MBlazeTargetInfo(T);
2592
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002593 case llvm::Triple::sparc:
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002594 if (os == llvm::Triple::AuroraUX)
2595 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002596 if (os == llvm::Triple::Solaris)
2597 return new SolarisSparcV8TargetInfo(T);
2598 return new SparcV8TargetInfo(T);
2599
John Thompson3f6918a2009-11-19 17:18:50 +00002600 // FIXME: Need a real SPU target.
2601 case llvm::Triple::cellspu:
2602 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2603
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002604 case llvm::Triple::systemz:
2605 return new SystemZTargetInfo(T);
2606
Eli Friedmanb63decf2009-08-19 20:47:07 +00002607 case llvm::Triple::tce:
2608 return new TCETargetInfo(T);
2609
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002610 case llvm::Triple::x86:
2611 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002612 case llvm::Triple::AuroraUX:
2613 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002614 case llvm::Triple::Darwin:
2615 return new DarwinI386TargetInfo(T);
2616 case llvm::Triple::Linux:
2617 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2618 case llvm::Triple::DragonFly:
2619 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2620 case llvm::Triple::NetBSD:
2621 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2622 case llvm::Triple::OpenBSD:
2623 return new OpenBSDI386TargetInfo(T);
2624 case llvm::Triple::FreeBSD:
2625 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
Chris Lattner38e317d2010-07-07 16:01:42 +00002626 case llvm::Triple::Minix:
2627 return new MinixTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002628 case llvm::Triple::Solaris:
2629 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2630 case llvm::Triple::Cygwin:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002631 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002632 case llvm::Triple::MinGW32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002633 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002634 case llvm::Triple::Win32:
Michael J. Spencera764e832010-10-21 08:22:51 +00002635 return new VisualStudioWindowsX86_32TargetInfo(T);
Chris Lattner86ed3a32010-04-11 19:29:39 +00002636 case llvm::Triple::Haiku:
2637 return new HaikuX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002638 default:
2639 return new X86_32TargetInfo(T);
2640 }
2641
2642 case llvm::Triple::x86_64:
2643 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002644 case llvm::Triple::AuroraUX:
2645 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002646 case llvm::Triple::Darwin:
2647 return new DarwinX86_64TargetInfo(T);
2648 case llvm::Triple::Linux:
2649 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner7a7ca282010-01-09 05:41:14 +00002650 case llvm::Triple::DragonFly:
2651 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002652 case llvm::Triple::NetBSD:
2653 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2654 case llvm::Triple::OpenBSD:
2655 return new OpenBSDX86_64TargetInfo(T);
2656 case llvm::Triple::FreeBSD:
2657 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2658 case llvm::Triple::Solaris:
2659 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002660 case llvm::Triple::MinGW64:
2661 return new MinGWX86_64TargetInfo(T);
2662 case llvm::Triple::Win32: // This is what Triple.h supports now.
Michael J. Spencera764e832010-10-21 08:22:51 +00002663 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002664 default:
2665 return new X86_64TargetInfo(T);
2666 }
2667 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002668}
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002669
2670/// CreateTargetInfo - Return the target info object for the specified target
2671/// triple.
2672TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002673 TargetOptions &Opts) {
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002674 llvm::Triple Triple(Opts.Triple);
2675
2676 // Construct the target
2677 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2678 if (!Target) {
2679 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2680 return 0;
2681 }
2682
Daniel Dunbareac7c532009-12-18 18:42:37 +00002683 // Set the target CPU if specified.
2684 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2685 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2686 return 0;
2687 }
2688
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002689 // Set the target ABI if specified.
2690 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2691 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2692 return 0;
2693 }
2694
Charles Davis98b7c5c2010-06-11 01:06:47 +00002695 // Set the target C++ ABI.
John McCallee79a4c2010-08-21 22:46:04 +00002696 if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Charles Davis98b7c5c2010-06-11 01:06:47 +00002697 Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
2698 return 0;
2699 }
2700
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002701 // Compute the default target features, we need the target to handle this
2702 // because features may have dependencies on one another.
2703 llvm::StringMap<bool> Features;
2704 Target->getDefaultFeatures(Opts.CPU, Features);
2705
2706 // Apply the user specified deltas.
2707 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2708 ie = Opts.Features.end(); it != ie; ++it) {
2709 const char *Name = it->c_str();
2710
2711 // Apply the feature via the target.
2712 if ((Name[0] != '-' && Name[0] != '+') ||
2713 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2714 Diags.Report(diag::err_target_invalid_feature) << Name;
2715 return 0;
2716 }
2717 }
2718
2719 // Add the features to the compile options.
2720 //
2721 // FIXME: If we are completely confident that we have the right set, we only
2722 // need to pass the minuses.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002723 Opts.Features.clear();
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002724 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2725 ie = Features.end(); it != ie; ++it)
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002726 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2727 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002728
2729 return Target.take();
2730}