blob: 16a12604e30d3c3d4175904a27a6bd00f1e45195 [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
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000482 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000483 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000484 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000485 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000486 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000487 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000488 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000489 default: return false;
490 case 'O': // Zero
John Thompson8e6065a2010-06-24 22:44:13 +0000491 break;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000492 case 'b': // Base register
493 case 'f': // Floating point register
Chris Lattner44def072009-04-26 07:16:29 +0000494 Info.setAllowsRegister();
John Thompson8e6065a2010-06-24 22:44:13 +0000495 break;
496 // FIXME: The following are added to allow parsing.
497 // I just took a guess at what the actions should be.
498 // Also, is more specific checking needed? I.e. specific registers?
Michael J. Spencer20249a12010-10-21 03:16:25 +0000499 case 'd': // Floating point register (containing 64-bit value)
John Thompson8e6065a2010-06-24 22:44:13 +0000500 case 'v': // Altivec vector register
501 Info.setAllowsRegister();
502 break;
503 case 'w':
504 switch (Name[1]) {
Michael J. Spencer20249a12010-10-21 03:16:25 +0000505 case 'd':// VSX vector register to hold vector double data
506 case 'f':// VSX vector register to hold vector float data
507 case 's':// VSX vector register to hold scalar float data
508 case 'a':// Any VSX register
John Thompson8e6065a2010-06-24 22:44:13 +0000509 break;
510 default:
511 return false;
512 }
513 Info.setAllowsRegister();
514 Name++; // Skip over 'w'.
515 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000516 case 'h': // `MQ', `CTR', or `LINK' register
517 case 'q': // `MQ' register
518 case 'c': // `CTR' register
519 case 'l': // `LINK' register
520 case 'x': // `CR' register (condition register) number 0
521 case 'y': // `CR' register (condition register)
522 case 'z': // `XER[CA]' carry bit (part of the XER register)
John Thompson8e6065a2010-06-24 22:44:13 +0000523 Info.setAllowsRegister();
524 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000525 case 'I': // Signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000526 case 'J': // Unsigned 16-bit constant shifted left 16 bits
Michael J. Spencer20249a12010-10-21 03:16:25 +0000527 // (use `L' instead for SImode constants)
528 case 'K': // Unsigned 16-bit constant
529 case 'L': // Signed 16-bit constant shifted left 16 bits
530 case 'M': // Constant larger than 31
531 case 'N': // Exact power of 2
532 case 'P': // Constant whose negation is a signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000533 case 'G': // Floating point constant that can be loaded into a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000534 // register with one instruction per word
John Thompson8e6065a2010-06-24 22:44:13 +0000535 case 'H': // Integer/Floating point constant that can be loaded
Michael J. Spencer20249a12010-10-21 03:16:25 +0000536 // into a register using three instructions
John Thompson8e6065a2010-06-24 22:44:13 +0000537 break;
538 case 'm': // Memory operand. Note that on PowerPC targets, m can
539 // include addresses that update the base register. It
540 // is therefore only safe to use `m' in an asm statement
541 // if that asm statement accesses the operand exactly once.
542 // The asm statement must also use `%U<opno>' as a
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000543 // placeholder for the "update" flag in the corresponding
Michael J. Spencer20249a12010-10-21 03:16:25 +0000544 // load or store instruction. For example:
John Thompson8e6065a2010-06-24 22:44:13 +0000545 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
Michael J. Spencer20249a12010-10-21 03:16:25 +0000546 // is correct but:
John Thompson8e6065a2010-06-24 22:44:13 +0000547 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
548 // is not. Use es rather than m if you don't want the base
Michael J. Spencer20249a12010-10-21 03:16:25 +0000549 // register to be updated.
550 case 'e':
John Thompson56b6eca2010-06-25 00:02:05 +0000551 if (Name[1] != 's')
552 return false;
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000553 // es: A "stable" memory operand; that is, one which does not
John Thompson8e6065a2010-06-24 22:44:13 +0000554 // include any automodification of the base register. Unlike
555 // `m', this constraint can be used in asm statements that
556 // might access the operand several times, or that might not
John Thompson56b6eca2010-06-25 00:02:05 +0000557 // access it at all.
John Thompson8e6065a2010-06-24 22:44:13 +0000558 Info.setAllowsMemory();
John Thompson56b6eca2010-06-25 00:02:05 +0000559 Name++; // Skip over 'e'.
John Thompson8e6065a2010-06-24 22:44:13 +0000560 break;
561 case 'Q': // Memory operand that is an offset from a register (it is
Michael J. Spencer20249a12010-10-21 03:16:25 +0000562 // usually better to use `m' or `es' in asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000563 case 'Z': // Memory operand that is an indexed or indirect from a
564 // register (it is usually better to use `m' or `es' in
Michael J. Spencer20249a12010-10-21 03:16:25 +0000565 // asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000566 Info.setAllowsMemory();
567 Info.setAllowsRegister();
568 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000569 case 'R': // AIX TOC entry
John Thompson8e6065a2010-06-24 22:44:13 +0000570 case 'a': // Address operand that is an indexed or indirect from a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000571 // register (`p' is preferable for asm statements)
572 case 'S': // Constant suitable as a 64-bit mask operand
573 case 'T': // Constant suitable as a 32-bit mask operand
574 case 'U': // System V Release 4 small data area reference
John Thompson8e6065a2010-06-24 22:44:13 +0000575 case 't': // AND masks that can be performed by two rldic{l, r}
Michael J. Spencer20249a12010-10-21 03:16:25 +0000576 // instructions
577 case 'W': // Vector constant that does not require memory
578 case 'j': // Vector constant that is all zeros.
John Thompson8e6065a2010-06-24 22:44:13 +0000579 break;
580 // End FIXME.
Anders Carlssond04c6e22007-11-27 04:11:28 +0000581 }
John Thompson8e6065a2010-06-24 22:44:13 +0000582 return true;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000583 }
Eli Friedmane4277982008-08-20 23:11:40 +0000584 virtual const char *getClobbers() const {
585 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000586 }
Eli Friedmane4277982008-08-20 23:11:40 +0000587};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000588
Eli Friedmane4277982008-08-20 23:11:40 +0000589const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +0000590#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
591#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
592 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000593#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmane4277982008-08-20 23:11:40 +0000594};
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000595
596
Chris Lattnerc0f59212009-03-02 22:27:17 +0000597/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
598/// #defines that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000599void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000600 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000601 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +0000602 Builder.defineMacro("__ppc__");
603 Builder.defineMacro("_ARCH_PPC");
Chris Lattnere03ae302010-02-16 18:14:57 +0000604 Builder.defineMacro("__powerpc__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000605 Builder.defineMacro("__POWERPC__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000606 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000607 Builder.defineMacro("_ARCH_PPC64");
608 Builder.defineMacro("_LP64");
609 Builder.defineMacro("__LP64__");
Chris Lattnere03ae302010-02-16 18:14:57 +0000610 Builder.defineMacro("__powerpc64__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000611 Builder.defineMacro("__ppc64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000612 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +0000613 Builder.defineMacro("__ppc__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000614 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000615
Chris Lattnerc0f59212009-03-02 22:27:17 +0000616 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +0000617 Builder.defineMacro("_BIG_ENDIAN");
618 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000619
Chris Lattnerc0f59212009-03-02 22:27:17 +0000620 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +0000621 Builder.defineMacro("__NATURAL_ALIGNMENT__");
622 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000623
Chris Lattnerc0f59212009-03-02 22:27:17 +0000624 // FIXME: Should be controlled by command line option.
Benjamin Kramera9992772010-01-09 17:55:51 +0000625 Builder.defineMacro("__LONG_DOUBLE_128__");
Michael J. Spencer20249a12010-10-21 03:16:25 +0000626
John Thompson3f6918a2009-11-19 17:18:50 +0000627 if (Opts.AltiVec) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000628 Builder.defineMacro("__VEC__", "10206");
629 Builder.defineMacro("__ALTIVEC__");
John Thompson3f6918a2009-11-19 17:18:50 +0000630 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000631}
632
Chris Lattner393ff042008-04-21 18:56:49 +0000633
Eli Friedmane4277982008-08-20 23:11:40 +0000634const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnere94e0d42009-09-16 05:05:27 +0000635 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
636 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
637 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
638 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
639 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
640 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
641 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
642 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmane4277982008-08-20 23:11:40 +0000643 "mq", "lr", "ctr", "ap",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000644 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmane4277982008-08-20 23:11:40 +0000645 "xer",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000646 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
647 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
648 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
649 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmane4277982008-08-20 23:11:40 +0000650 "vrsave", "vscr",
651 "spe_acc", "spefscr",
652 "sfp"
653};
Reid Spencer5f016e22007-07-11 17:01:13 +0000654
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000655void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000656 unsigned &NumNames) const {
657 Names = GCCRegNames;
658 NumNames = llvm::array_lengthof(GCCRegNames);
659}
Reid Spencer5f016e22007-07-11 17:01:13 +0000660
Eli Friedmane4277982008-08-20 23:11:40 +0000661const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
662 // While some of these aliases do map to different registers
663 // they still share the same register name.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000664 { { "0" }, "r0" },
665 { { "1"}, "r1" },
666 { { "2" }, "r2" },
667 { { "3" }, "r3" },
668 { { "4" }, "r4" },
669 { { "5" }, "r5" },
670 { { "6" }, "r6" },
671 { { "7" }, "r7" },
672 { { "8" }, "r8" },
673 { { "9" }, "r9" },
674 { { "10" }, "r10" },
675 { { "11" }, "r11" },
676 { { "12" }, "r12" },
677 { { "13" }, "r13" },
678 { { "14" }, "r14" },
679 { { "15" }, "r15" },
680 { { "16" }, "r16" },
681 { { "17" }, "r17" },
682 { { "18" }, "r18" },
683 { { "19" }, "r19" },
684 { { "20" }, "r20" },
685 { { "21" }, "r21" },
686 { { "22" }, "r22" },
687 { { "23" }, "r23" },
688 { { "24" }, "r24" },
689 { { "25" }, "r25" },
690 { { "26" }, "r26" },
691 { { "27" }, "r27" },
692 { { "28" }, "r28" },
693 { { "29" }, "r29" },
694 { { "30" }, "r30" },
695 { { "31" }, "r31" },
696 { { "fr0" }, "f0" },
697 { { "fr1" }, "f1" },
698 { { "fr2" }, "f2" },
699 { { "fr3" }, "f3" },
700 { { "fr4" }, "f4" },
701 { { "fr5" }, "f5" },
702 { { "fr6" }, "f6" },
703 { { "fr7" }, "f7" },
704 { { "fr8" }, "f8" },
705 { { "fr9" }, "f9" },
Mike Stump10880392009-09-17 21:15:00 +0000706 { { "fr10" }, "f10" },
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000707 { { "fr11" }, "f11" },
708 { { "fr12" }, "f12" },
709 { { "fr13" }, "f13" },
710 { { "fr14" }, "f14" },
711 { { "fr15" }, "f15" },
712 { { "fr16" }, "f16" },
713 { { "fr17" }, "f17" },
714 { { "fr18" }, "f18" },
715 { { "fr19" }, "f19" },
716 { { "fr20" }, "f20" },
717 { { "fr21" }, "f21" },
718 { { "fr22" }, "f22" },
719 { { "fr23" }, "f23" },
720 { { "fr24" }, "f24" },
721 { { "fr25" }, "f25" },
722 { { "fr26" }, "f26" },
723 { { "fr27" }, "f27" },
724 { { "fr28" }, "f28" },
725 { { "fr29" }, "f29" },
726 { { "fr30" }, "f30" },
727 { { "fr31" }, "f31" },
728 { { "cc" }, "cr0" },
Eli Friedmane4277982008-08-20 23:11:40 +0000729};
730
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000731void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000732 unsigned &NumAliases) const {
733 Aliases = GCCRegAliases;
734 NumAliases = llvm::array_lengthof(GCCRegAliases);
735}
736} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000737
738namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000739class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000740public:
Chris Lattnere03ae302010-02-16 18:14:57 +0000741 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedmaned855cb2008-08-21 00:13:15 +0000742 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 +0000743 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnere03ae302010-02-16 18:14:57 +0000744
745 if (getTriple().getOS() == llvm::Triple::FreeBSD)
Roman Divackyc81f2a22011-01-06 08:27:10 +0000746 SizeType = UnsignedInt;
747 }
748
749 virtual const char *getVAListDeclaration() const {
750 // This is the ELF definition, and is overridden by the Darwin sub-target
751 return "typedef struct __va_list_tag {"
752 " unsigned char gpr;"
753 " unsigned char fpr;"
754 " unsigned short reserved;"
755 " void* overflow_arg_area;"
756 " void* reg_save_area;"
757 "} __builtin_va_list[1];";
Eli Friedmaned855cb2008-08-21 00:13:15 +0000758 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000759};
760} // end anonymous namespace.
761
762namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000763class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000764public:
Eli Friedmane4277982008-08-20 23:11:40 +0000765 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000766 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman3c7b6e42009-07-01 03:36:11 +0000767 IntMaxType = SignedLong;
768 UIntMaxType = UnsignedLong;
769 Int64Type = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000770 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 +0000771 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerf291b102008-05-09 06:17:04 +0000772 }
Roman Divackyc81f2a22011-01-06 08:27:10 +0000773 virtual const char *getVAListDeclaration() const {
774 return "typedef char* __builtin_va_list;";
775 }
Eli Friedmane4277982008-08-20 23:11:40 +0000776};
777} // end anonymous namespace.
778
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000779
780namespace {
Roman Divackyc81f2a22011-01-06 08:27:10 +0000781class DarwinPPC32TargetInfo :
782 public DarwinTargetInfo<PPC32TargetInfo> {
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000783public:
Roman Divackyc81f2a22011-01-06 08:27:10 +0000784 DarwinPPC32TargetInfo(const std::string& triple)
785 : DarwinTargetInfo<PPC32TargetInfo>(triple) {
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000786 HasAlignMac68kSupport = true;
Roman Divackyc81f2a22011-01-06 08:27:10 +0000787 BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
788 }
789 virtual const char *getVAListDeclaration() const {
790 return "typedef char* __builtin_va_list;";
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000791 }
792};
793
794class DarwinPPC64TargetInfo :
795 public DarwinTargetInfo<PPC64TargetInfo> {
796public:
797 DarwinPPC64TargetInfo(const std::string& triple)
798 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
799 HasAlignMac68kSupport = true;
800 }
801};
802} // end anonymous namespace.
803
Reid Spencer5f016e22007-07-11 17:01:13 +0000804namespace {
Chris Lattner9cbeb632010-03-06 21:21:27 +0000805// MBlaze abstract base class
806class MBlazeTargetInfo : public TargetInfo {
807 static const char * const GCCRegNames[];
808 static const TargetInfo::GCCRegAlias GCCRegAliases[];
809
810public:
811 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
Wesley Pecka48fa4b2010-12-12 20:56:47 +0000812 DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
Chris Lattner9cbeb632010-03-06 21:21:27 +0000813 }
814
815 virtual void getTargetBuiltins(const Builtin::Info *&Records,
816 unsigned &NumRecords) const {
817 // FIXME: Implement.
818 Records = 0;
819 NumRecords = 0;
820 }
821
822 virtual void getTargetDefines(const LangOptions &Opts,
823 MacroBuilder &Builder) const;
824
825 virtual const char *getVAListDeclaration() const {
826 return "typedef char* __builtin_va_list;";
827 }
828 virtual const char *getTargetPrefix() const {
829 return "mblaze";
830 }
831 virtual void getGCCRegNames(const char * const *&Names,
832 unsigned &NumNames) const;
833 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
834 unsigned &NumAliases) const;
835 virtual bool validateAsmConstraint(const char *&Name,
836 TargetInfo::ConstraintInfo &Info) const {
837 switch (*Name) {
838 default: return false;
839 case 'O': // Zero
840 return true;
841 case 'b': // Base register
842 case 'f': // Floating point register
843 Info.setAllowsRegister();
844 return true;
845 }
846 }
847 virtual const char *getClobbers() const {
848 return "";
849 }
850};
851
852/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
853/// #defines that are not tied to a specific subtarget.
854void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
855 MacroBuilder &Builder) const {
856 // Target identification.
857 Builder.defineMacro("__microblaze__");
858 Builder.defineMacro("_ARCH_MICROBLAZE");
859 Builder.defineMacro("__MICROBLAZE__");
860
861 // Target properties.
862 Builder.defineMacro("_BIG_ENDIAN");
863 Builder.defineMacro("__BIG_ENDIAN__");
864
865 // Subtarget options.
866 Builder.defineMacro("__REGISTER_PREFIX__", "");
867}
868
869
870const char * const MBlazeTargetInfo::GCCRegNames[] = {
871 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
872 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
873 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
874 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
875 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
876 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
877 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
878 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
879 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
880 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
881};
882
883void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
884 unsigned &NumNames) const {
885 Names = GCCRegNames;
886 NumNames = llvm::array_lengthof(GCCRegNames);
887}
888
889const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
890 { {"f0"}, "r0" },
891 { {"f1"}, "r1" },
892 { {"f2"}, "r2" },
893 { {"f3"}, "r3" },
894 { {"f4"}, "r4" },
895 { {"f5"}, "r5" },
896 { {"f6"}, "r6" },
897 { {"f7"}, "r7" },
898 { {"f8"}, "r8" },
899 { {"f9"}, "r9" },
900 { {"f10"}, "r10" },
901 { {"f11"}, "r11" },
902 { {"f12"}, "r12" },
903 { {"f13"}, "r13" },
904 { {"f14"}, "r14" },
905 { {"f15"}, "r15" },
906 { {"f16"}, "r16" },
907 { {"f17"}, "r17" },
908 { {"f18"}, "r18" },
909 { {"f19"}, "r19" },
910 { {"f20"}, "r20" },
911 { {"f21"}, "r21" },
912 { {"f22"}, "r22" },
913 { {"f23"}, "r23" },
914 { {"f24"}, "r24" },
915 { {"f25"}, "r25" },
916 { {"f26"}, "r26" },
917 { {"f27"}, "r27" },
918 { {"f28"}, "r28" },
919 { {"f29"}, "r29" },
920 { {"f30"}, "r30" },
921 { {"f31"}, "r31" },
922};
923
924void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
925 unsigned &NumAliases) const {
926 Aliases = GCCRegAliases;
927 NumAliases = llvm::array_lengthof(GCCRegAliases);
928}
929} // end anonymous namespace.
930
931namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000932// Namespace for x86 abstract base class
933const Builtin::Info BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +0000934#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
935#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
936 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000937#include "clang/Basic/BuiltinsX86.def"
Eli Friedman618234a2008-08-20 02:34:37 +0000938};
Eli Friedman61538a72008-05-20 14:21:01 +0000939
Nuno Lopes2550d702009-12-23 17:49:57 +0000940static const char* const GCCRegNames[] = {
Eli Friedman618234a2008-08-20 02:34:37 +0000941 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
942 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
943 "argp", "flags", "fspr", "dirflag", "frame",
944 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
945 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
946 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
947 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
948};
949
950const TargetInfo::GCCRegAlias GCCRegAliases[] = {
951 { { "al", "ah", "eax", "rax" }, "ax" },
952 { { "bl", "bh", "ebx", "rbx" }, "bx" },
953 { { "cl", "ch", "ecx", "rcx" }, "cx" },
954 { { "dl", "dh", "edx", "rdx" }, "dx" },
955 { { "esi", "rsi" }, "si" },
956 { { "edi", "rdi" }, "di" },
957 { { "esp", "rsp" }, "sp" },
958 { { "ebp", "rbp" }, "bp" },
959};
960
961// X86 target abstract base class; x86-32 and x86-64 are very close, so
962// most of the implementation can be shared.
963class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +0000964 enum X86SSEEnum {
965 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
966 } SSELevel;
Anders Carlsson9b0fb622010-01-27 03:47:49 +0000967 enum AMD3DNowEnum {
968 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
969 } AMD3DNowLevel;
970
Eric Christophereea12d12010-04-02 23:50:19 +0000971 bool HasAES;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000972 bool HasAVX;
973
Eli Friedman618234a2008-08-20 02:34:37 +0000974public:
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000975 X86TargetInfo(const std::string& triple)
Eric Christophereea12d12010-04-02 23:50:19 +0000976 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000977 HasAES(false), HasAVX(false) {
Eli Friedman618234a2008-08-20 02:34:37 +0000978 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000979 }
980 virtual void getTargetBuiltins(const Builtin::Info *&Records,
981 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000982 Records = BuiltinInfo;
983 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000984 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000985 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000986 unsigned &NumNames) const {
987 Names = GCCRegNames;
988 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000989 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000990 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson3346ae62007-11-24 23:38:12 +0000991 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000992 Aliases = GCCRegAliases;
993 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000994 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000995 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000996 TargetInfo::ConstraintInfo &info) const;
Dale Johannesenf6e2c202010-10-29 23:12:32 +0000997 virtual const llvm::Type* adjustInlineAsmType(std::string& Constraint,
998 const llvm::Type* Ty,
999 llvm::LLVMContext& Context) const;
Eli Friedman618234a2008-08-20 02:34:37 +00001000 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +00001001 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +00001002 return "~{dirflag},~{fpsr},~{flags}";
1003 }
Chris Lattner33328642009-03-20 15:52:06 +00001004 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001005 MacroBuilder &Builder) const;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001006 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1007 const std::string &Name,
1008 bool Enabled) const;
Mike Stump1eb44332009-09-09 15:08:12 +00001009 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001010 llvm::StringMap<bool> &Features) const;
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001011 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Reid Spencer5f016e22007-07-11 17:01:13 +00001012};
Chris Lattner3daed522009-03-02 22:20:04 +00001013
Mike Stump1eb44332009-09-09 15:08:12 +00001014void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001015 llvm::StringMap<bool> &Features) const {
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001016 // FIXME: This should not be here.
1017 Features["3dnow"] = false;
1018 Features["3dnowa"] = false;
1019 Features["mmx"] = false;
1020 Features["sse"] = false;
1021 Features["sse2"] = false;
1022 Features["sse3"] = false;
1023 Features["ssse3"] = false;
1024 Features["sse41"] = false;
1025 Features["sse42"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001026 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001027 Features["avx"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001028
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001029 // LLVM does not currently recognize this.
1030 // Features["sse4a"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001031
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001032 // FIXME: This *really* should not be here.
1033
1034 // X86_64 always has SSE2.
1035 if (PointerWidth == 64)
1036 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
1037
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001038 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
1039 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
1040 ;
1041 else if (CPU == "pentium-mmx" || CPU == "pentium2")
1042 setFeatureEnabled(Features, "mmx", true);
1043 else if (CPU == "pentium3")
1044 setFeatureEnabled(Features, "sse", true);
1045 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
1046 setFeatureEnabled(Features, "sse2", true);
1047 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
1048 setFeatureEnabled(Features, "sse3", true);
1049 else if (CPU == "core2")
1050 setFeatureEnabled(Features, "ssse3", true);
1051 else if (CPU == "penryn") {
1052 setFeatureEnabled(Features, "sse4", true);
1053 Features["sse42"] = false;
1054 } else if (CPU == "atom")
1055 setFeatureEnabled(Features, "sse3", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001056 else if (CPU == "corei7") {
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001057 setFeatureEnabled(Features, "sse4", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001058 setFeatureEnabled(Features, "aes", true);
1059 }
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001060 else if (CPU == "k6" || CPU == "winchip-c6")
1061 setFeatureEnabled(Features, "mmx", true);
Mike Stump1eb44332009-09-09 15:08:12 +00001062 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001063 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
1064 setFeatureEnabled(Features, "mmx", true);
1065 setFeatureEnabled(Features, "3dnow", true);
1066 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
1067 setFeatureEnabled(Features, "sse", true);
1068 setFeatureEnabled(Features, "3dnowa", true);
1069 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
1070 CPU == "athlon-fx") {
Mike Stump1eb44332009-09-09 15:08:12 +00001071 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001072 setFeatureEnabled(Features, "3dnowa", true);
Roman Divackyc8b09a12010-12-29 13:28:29 +00001073 } else if (CPU == "k8-sse3") {
1074 setFeatureEnabled(Features, "sse3", true);
1075 setFeatureEnabled(Features, "3dnowa", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001076 } else if (CPU == "c3-2")
1077 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001078}
1079
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001080bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump1eb44332009-09-09 15:08:12 +00001081 const std::string &Name,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001082 bool Enabled) const {
Eric Christopherd39ebe22010-03-04 02:26:37 +00001083 // FIXME: This *really* should not be here. We need some way of translating
1084 // options into llvm subtarget features.
1085 if (!Features.count(Name) &&
1086 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001087 return false;
1088
1089 if (Enabled) {
1090 if (Name == "mmx")
1091 Features["mmx"] = true;
1092 else if (Name == "sse")
1093 Features["mmx"] = Features["sse"] = true;
1094 else if (Name == "sse2")
1095 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
1096 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001097 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001098 Features["sse3"] = true;
1099 else if (Name == "ssse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001100 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001101 Features["ssse3"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001102 else if (Name == "sse4" || Name == "sse4.2")
Mike Stump1eb44332009-09-09 15:08:12 +00001103 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001104 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001105 else if (Name == "sse4.1")
1106 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
1107 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001108 else if (Name == "3dnow")
1109 Features["3dnowa"] = true;
1110 else if (Name == "3dnowa")
1111 Features["3dnow"] = Features["3dnowa"] = true;
Eric Christophereea12d12010-04-02 23:50:19 +00001112 else if (Name == "aes")
1113 Features["aes"] = true;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001114 else if (Name == "avx")
1115 Features["avx"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001116 } else {
1117 if (Name == "mmx")
Mike Stump1eb44332009-09-09 15:08:12 +00001118 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001119 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1120 else if (Name == "sse")
Mike Stump1eb44332009-09-09 15:08:12 +00001121 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001122 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1123 else if (Name == "sse2")
Mike Stump1eb44332009-09-09 15:08:12 +00001124 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001125 Features["sse41"] = Features["sse42"] = false;
1126 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001127 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001128 Features["sse42"] = false;
1129 else if (Name == "ssse3")
1130 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1131 else if (Name == "sse4")
1132 Features["sse41"] = Features["sse42"] = false;
Eric Christopherd41b4ec2010-03-04 02:31:44 +00001133 else if (Name == "sse4.2")
1134 Features["sse42"] = false;
1135 else if (Name == "sse4.1")
1136 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001137 else if (Name == "3dnow")
1138 Features["3dnow"] = Features["3dnowa"] = false;
1139 else if (Name == "3dnowa")
1140 Features["3dnowa"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001141 else if (Name == "aes")
1142 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001143 else if (Name == "avx")
1144 Features["avx"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001145 }
1146
1147 return true;
1148}
1149
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001150/// HandleTargetOptions - Perform initialization based on the user
1151/// configured set of features.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001152void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001153 // Remember the maximum enabled sselevel.
1154 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
1155 // Ignore disabled features.
1156 if (Features[i][0] == '-')
1157 continue;
1158
Eric Christophereea12d12010-04-02 23:50:19 +00001159 if (Features[i].substr(1) == "aes") {
1160 HasAES = true;
1161 continue;
1162 }
1163
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001164 // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
1165 // For now let it be enabled together with other SSE levels.
1166 if (Features[i].substr(1) == "avx") {
1167 HasAVX = true;
1168 continue;
1169 }
1170
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001171 assert(Features[i][0] == '+' && "Invalid target feature!");
1172 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
1173 .Case("sse42", SSE42)
1174 .Case("sse41", SSE41)
1175 .Case("ssse3", SSSE3)
Nuno Lopes33d3bca2010-03-12 10:20:09 +00001176 .Case("sse3", SSE3)
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001177 .Case("sse2", SSE2)
1178 .Case("sse", SSE1)
1179 .Case("mmx", MMX)
1180 .Default(NoMMXSSE);
1181 SSELevel = std::max(SSELevel, Level);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001182
1183 AMD3DNowEnum ThreeDNowLevel =
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001184 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
1185 .Case("3dnowa", AMD3DNowAthlon)
1186 .Case("3dnow", AMD3DNow)
1187 .Default(NoAMD3DNow);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001188
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001189 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001190 }
Chris Lattner3daed522009-03-02 22:20:04 +00001191}
Chris Lattnerc0f59212009-03-02 22:27:17 +00001192
1193/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
1194/// that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +00001195void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001196 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001197 // Target identification.
1198 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001199 Builder.defineMacro("_LP64");
1200 Builder.defineMacro("__LP64__");
1201 Builder.defineMacro("__amd64__");
1202 Builder.defineMacro("__amd64");
1203 Builder.defineMacro("__x86_64");
1204 Builder.defineMacro("__x86_64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +00001205 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +00001206 DefineStd(Builder, "i386", Opts);
Chris Lattnerc0f59212009-03-02 22:27:17 +00001207 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001208
Eric Christophereea12d12010-04-02 23:50:19 +00001209 if (HasAES)
1210 Builder.defineMacro("__AES__");
1211
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001212 if (HasAVX)
1213 Builder.defineMacro("__AVX__");
1214
Chris Lattnerc0f59212009-03-02 22:27:17 +00001215 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001216 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001217
Chris Lattnerc0f59212009-03-02 22:27:17 +00001218 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +00001219 Builder.defineMacro("__nocona");
1220 Builder.defineMacro("__nocona__");
1221 Builder.defineMacro("__tune_nocona__");
1222 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001223
Chris Lattner54175442009-04-19 17:32:33 +00001224 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
1225 // functions in glibc header files that use FP Stack inline asm which the
1226 // backend can't deal with (PR879).
Benjamin Kramera9992772010-01-09 17:55:51 +00001227 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001228
Chris Lattner84f0ea82009-03-02 22:40:39 +00001229 // Each case falls through to the previous one here.
1230 switch (SSELevel) {
1231 case SSE42:
Benjamin Kramera9992772010-01-09 17:55:51 +00001232 Builder.defineMacro("__SSE4_2__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001233 case SSE41:
Benjamin Kramera9992772010-01-09 17:55:51 +00001234 Builder.defineMacro("__SSE4_1__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001235 case SSSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001236 Builder.defineMacro("__SSSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001237 case SSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001238 Builder.defineMacro("__SSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001239 case SSE2:
Benjamin Kramera9992772010-01-09 17:55:51 +00001240 Builder.defineMacro("__SSE2__");
1241 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001242 case SSE1:
Benjamin Kramera9992772010-01-09 17:55:51 +00001243 Builder.defineMacro("__SSE__");
1244 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001245 case MMX:
Benjamin Kramera9992772010-01-09 17:55:51 +00001246 Builder.defineMacro("__MMX__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001247 case NoMMXSSE:
1248 break;
1249 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001250
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001251 if (Opts.Microsoft && PointerWidth == 32) {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001252 switch (SSELevel) {
Michael J. Spencera764e832010-10-21 08:22:51 +00001253 case SSE42:
1254 case SSE41:
1255 case SSSE3:
1256 case SSE3:
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001257 case SSE2:
1258 Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
1259 break;
1260 case SSE1:
1261 Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
1262 break;
1263 default:
1264 Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
1265 }
1266 }
1267
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001268 // Each case falls through to the previous one here.
1269 switch (AMD3DNowLevel) {
1270 case AMD3DNowAthlon:
1271 Builder.defineMacro("__3dNOW_A__");
1272 case AMD3DNow:
1273 Builder.defineMacro("__3dNOW__");
1274 case NoAMD3DNow:
1275 break;
1276 }
Chris Lattnerc0f59212009-03-02 22:27:17 +00001277}
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001278
1279
Eli Friedman618234a2008-08-20 02:34:37 +00001280bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001281X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001282 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001283 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +00001284 default: return false;
Dale Johannesen545be512010-08-24 22:33:12 +00001285 case 'Y': // first letter of a pair:
1286 switch (*(Name+1)) {
1287 default: return false;
1288 case '0': // First SSE register.
1289 case 't': // Any SSE register, when SSE2 is enabled.
1290 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1291 case 'm': // any MMX register, when inter-unit moves enabled.
1292 break; // falls through to setAllowsRegister.
1293 }
Eli Friedman618234a2008-08-20 02:34:37 +00001294 case 'a': // eax.
1295 case 'b': // ebx.
1296 case 'c': // ecx.
1297 case 'd': // edx.
1298 case 'S': // esi.
1299 case 'D': // edi.
1300 case 'A': // edx:eax.
Dale Johannesen545be512010-08-24 22:33:12 +00001301 case 'f': // any x87 floating point stack register.
Eli Friedman618234a2008-08-20 02:34:37 +00001302 case 't': // top of floating point stack.
1303 case 'u': // second from top of floating point stack.
1304 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +00001305 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +00001306 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +00001307 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Dale Johannesen545be512010-08-24 22:33:12 +00001308 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1309 case 'l': // "Index" registers: any general register that can be used as an
1310 // index in a base+index memory access.
1311 Info.setAllowsRegister();
1312 return true;
1313 case 'C': // SSE floating point constant.
1314 case 'G': // x87 floating point constant.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001315 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001316 // x86_64 instructions.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001317 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001318 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +00001319 return true;
1320 }
Dale Johannesen545be512010-08-24 22:33:12 +00001321 return false;
Eli Friedman618234a2008-08-20 02:34:37 +00001322}
1323
Dale Johannesenf6e2c202010-10-29 23:12:32 +00001324const llvm::Type*
1325X86TargetInfo::adjustInlineAsmType(std::string& Constraint,
1326 const llvm::Type* Ty,
1327 llvm::LLVMContext &Context) const {
1328 if (Constraint=="y" && Ty->isVectorTy())
1329 return llvm::Type::getX86_MMXTy(Context);
1330 return Ty;
1331}
1332
1333
Eli Friedman618234a2008-08-20 02:34:37 +00001334std::string
1335X86TargetInfo::convertConstraint(const char Constraint) const {
1336 switch (Constraint) {
1337 case 'a': return std::string("{ax}");
1338 case 'b': return std::string("{bx}");
1339 case 'c': return std::string("{cx}");
1340 case 'd': return std::string("{dx}");
1341 case 'S': return std::string("{si}");
1342 case 'D': return std::string("{di}");
Dale Johannesencee55012010-10-22 21:07:10 +00001343 case 'p': // address
1344 return std::string("im");
Eli Friedman618234a2008-08-20 02:34:37 +00001345 case 't': // top of floating point stack.
1346 return std::string("{st}");
1347 case 'u': // second from top of floating point stack.
1348 return std::string("{st(1)}"); // second from top of floating point stack.
1349 default:
1350 return std::string(1, Constraint);
1351 }
1352}
Eli Friedman618234a2008-08-20 02:34:37 +00001353} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +00001354
1355namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001356// X86-32 generic target
1357class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +00001358public:
Eli Friedman618234a2008-08-20 02:34:37 +00001359 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
1360 DoubleAlign = LongLongAlign = 32;
1361 LongDoubleWidth = 96;
1362 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001363 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1364 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001365 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman1afabd92009-03-29 20:31:09 +00001366 SizeType = UnsignedInt;
1367 PtrDiffType = SignedInt;
1368 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001369 RegParmMax = 3;
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001370
1371 // Use fpret for all types.
1372 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
1373 (1 << TargetInfo::Double) |
1374 (1 << TargetInfo::LongDouble));
Eli Friedman618234a2008-08-20 02:34:37 +00001375 }
1376 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001377 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +00001378 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001379
Chris Lattner21fb98e2009-09-23 06:06:36 +00001380 int getEHDataRegisterNumber(unsigned RegNo) const {
1381 if (RegNo == 0) return 0;
1382 if (RegNo == 1) return 2;
1383 return -1;
1384 }
Eli Friedman618234a2008-08-20 02:34:37 +00001385};
1386} // end anonymous namespace
1387
1388namespace {
Eli Friedman624c1462009-07-05 18:47:56 +00001389class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
1390public:
1391 OpenBSDI386TargetInfo(const std::string& triple) :
1392 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
1393 SizeType = UnsignedLong;
1394 IntPtrType = SignedLong;
Eli Friedman6036ebe2009-07-05 22:31:18 +00001395 PtrDiffType = SignedLong;
Eli Friedman624c1462009-07-05 18:47:56 +00001396 }
1397};
1398} // end anonymous namespace
1399
1400namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +00001401class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman618234a2008-08-20 02:34:37 +00001402public:
Torok Edwin5f6c1942009-06-30 17:10:35 +00001403 DarwinI386TargetInfo(const std::string& triple) :
1404 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman618234a2008-08-20 02:34:37 +00001405 LongDoubleWidth = 128;
1406 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +00001407 SizeType = UnsignedLong;
1408 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001409 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1410 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001411 "a0:0:64-f80:128:128-n8:16:32";
Daniel Dunbar613fd672010-05-27 00:35:16 +00001412 HasAlignMac68kSupport = true;
Torok Edwinb0a5b242009-06-30 17:00:25 +00001413 }
1414
Eli Friedman618234a2008-08-20 02:34:37 +00001415};
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001416} // end anonymous namespace
1417
1418namespace {
Eli Friedman29a30502008-08-21 01:40:19 +00001419// x86-32 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001420class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
Eli Friedman29a30502008-08-21 01:40:19 +00001421public:
1422 WindowsX86_32TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001423 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +00001424 TLSSupported = false;
Chris Lattner85de9e72009-06-24 17:12:15 +00001425 WCharType = UnsignedShort;
Eli Friedman9c2f84e2009-06-08 21:16:17 +00001426 DoubleAlign = LongLongAlign = 64;
1427 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 +00001428 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1429 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedman29a30502008-08-21 01:40:19 +00001430 }
Michael J. Spencera764e832010-10-21 08:22:51 +00001431 virtual void getTargetDefines(const LangOptions &Opts,
1432 MacroBuilder &Builder) const {
1433 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
1434 }
1435};
1436} // end anonymous namespace
1437
1438namespace {
1439
1440// x86-32 Windows Visual Studio target
1441class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1442public:
1443 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1444 : WindowsX86_32TargetInfo(triple) {
1445 LongDoubleWidth = 64;
1446 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1447 }
1448 virtual void getTargetDefines(const LangOptions &Opts,
1449 MacroBuilder &Builder) const {
1450 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1451 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
1452 // The value of the following reflects processor type.
1453 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1454 // We lost the original triple, so we use the default.
1455 Builder.defineMacro("_M_IX86", "600");
1456 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001457};
1458} // end anonymous namespace
1459
1460namespace {
1461// x86-32 MinGW target
1462class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1463public:
1464 MinGWX86_32TargetInfo(const std::string& triple)
1465 : WindowsX86_32TargetInfo(triple) {
1466 }
1467 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001468 MacroBuilder &Builder) const {
1469 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001470 DefineStd(Builder, "WIN32", Opts);
1471 DefineStd(Builder, "WINNT", Opts);
1472 Builder.defineMacro("_X86_");
Benjamin Kramera9992772010-01-09 17:55:51 +00001473 Builder.defineMacro("__MSVCRT__");
1474 Builder.defineMacro("__MINGW32__");
1475 Builder.defineMacro("__declspec", "__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001476 }
1477};
1478} // end anonymous namespace
1479
1480namespace {
1481// x86-32 Cygwin target
1482class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1483public:
1484 CygwinX86_32TargetInfo(const std::string& triple)
1485 : X86_32TargetInfo(triple) {
1486 TLSSupported = false;
1487 WCharType = UnsignedShort;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001488 DoubleAlign = LongLongAlign = 64;
1489 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1490 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001491 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001492 }
1493 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001494 MacroBuilder &Builder) const {
1495 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1496 Builder.defineMacro("__CYGWIN__");
1497 Builder.defineMacro("__CYGWIN32__");
1498 DefineStd(Builder, "unix", Opts);
Douglas Gregor2b003fd2010-04-21 05:52:38 +00001499 if (Opts.CPlusPlus)
1500 Builder.defineMacro("_GNU_SOURCE");
Eli Friedmanabc4e322009-06-08 06:11:14 +00001501 }
Eli Friedman29a30502008-08-21 01:40:19 +00001502};
1503} // end anonymous namespace
1504
1505namespace {
Chris Lattner86ed3a32010-04-11 19:29:39 +00001506// x86-32 Haiku target
1507class HaikuX86_32TargetInfo : public X86_32TargetInfo {
1508public:
1509 HaikuX86_32TargetInfo(const std::string& triple)
1510 : X86_32TargetInfo(triple) {
1511 SizeType = UnsignedLong;
Chris Lattnerfe1ea7b2010-04-22 17:48:00 +00001512 IntPtrType = SignedLong;
1513 PtrDiffType = SignedLong;
Rafael Espindola19ddda82010-11-09 16:41:02 +00001514 this->UserLabelPrefix = "";
Eli Friedmana7e68452010-08-22 01:00:03 +00001515 }
Chris Lattner86ed3a32010-04-11 19:29:39 +00001516 virtual void getTargetDefines(const LangOptions &Opts,
1517 MacroBuilder &Builder) const {
1518 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1519 Builder.defineMacro("__INTEL__");
1520 Builder.defineMacro("__HAIKU__");
1521 }
1522};
1523} // end anonymous namespace
1524
1525namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001526// x86-64 generic target
1527class X86_64TargetInfo : public X86TargetInfo {
1528public:
Chris Lattner33328642009-03-20 15:52:06 +00001529 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +00001530 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +00001531 LongDoubleWidth = 128;
1532 LongDoubleAlign = 128;
Rafael Espindola6deecb02010-06-04 23:15:27 +00001533 LargeArrayMinWidth = 128;
1534 LargeArrayAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +00001535 IntMaxType = SignedLong;
1536 UIntMaxType = UnsignedLong;
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001537 Int64Type = SignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001538 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +00001539
Eli Friedmaned855cb2008-08-21 00:13:15 +00001540 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1541 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001542 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001543
1544 // Use fpret only for long double.
1545 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
Reid Spencer5f016e22007-07-11 17:01:13 +00001546 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +00001547 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001548 return "typedef struct __va_list_tag {"
1549 " unsigned gp_offset;"
1550 " unsigned fp_offset;"
1551 " void* overflow_arg_area;"
1552 " void* reg_save_area;"
John McCall2b7baf02010-05-28 18:25:28 +00001553 "} __va_list_tag;"
Eli Friedmandc043162009-07-03 00:45:06 +00001554 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +00001555 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001556
Chris Lattner21fb98e2009-09-23 06:06:36 +00001557 int getEHDataRegisterNumber(unsigned RegNo) const {
1558 if (RegNo == 0) return 0;
1559 if (RegNo == 1) return 1;
1560 return -1;
1561 }
Eli Friedman618234a2008-08-20 02:34:37 +00001562};
1563} // end anonymous namespace
1564
1565namespace {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001566// x86-64 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001567class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001568public:
1569 WindowsX86_64TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001570 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001571 TLSSupported = false;
1572 WCharType = UnsignedShort;
Mike Stumpa55cce82009-10-08 23:00:00 +00001573 LongWidth = LongAlign = 32;
Michael J. Spencer237cf582010-10-18 07:10:59 +00001574 DoubleAlign = LongLongAlign = 64;
Nate Begemandbf8ea42010-07-21 02:02:56 +00001575 IntMaxType = SignedLongLong;
1576 UIntMaxType = UnsignedLongLong;
1577 Int64Type = SignedLongLong;
Cameron Esfahani1484e0d2010-09-15 00:28:12 +00001578 SizeType = UnsignedLongLong;
1579 PtrDiffType = SignedLongLong;
1580 IntPtrType = SignedLongLong;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001581 }
1582 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001583 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001584 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001585 Builder.defineMacro("_WIN64");
Michael J. Spencera764e832010-10-21 08:22:51 +00001586 }
1587};
1588} // end anonymous namespace
1589
1590namespace {
1591// x86-64 Windows Visual Studio target
1592class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1593public:
1594 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1595 : WindowsX86_64TargetInfo(triple) {
1596 }
1597 virtual void getTargetDefines(const LangOptions &Opts,
1598 MacroBuilder &Builder) const {
1599 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1600 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
Benjamin Kramera9992772010-01-09 17:55:51 +00001601 Builder.defineMacro("_M_X64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001602 Builder.defineMacro("_M_AMD64");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001603 }
Chris Lattnerf13721d2010-08-31 16:44:54 +00001604 virtual const char *getVAListDeclaration() const {
1605 return "typedef char* __builtin_va_list;";
1606 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001607};
1608} // end anonymous namespace
1609
1610namespace {
1611// x86-64 MinGW target
1612class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1613public:
1614 MinGWX86_64TargetInfo(const std::string& triple)
1615 : WindowsX86_64TargetInfo(triple) {
1616 }
1617 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001618 MacroBuilder &Builder) const {
1619 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001620 DefineStd(Builder, "WIN64", Opts);
Benjamin Kramera9992772010-01-09 17:55:51 +00001621 Builder.defineMacro("__MSVCRT__");
1622 Builder.defineMacro("__MINGW64__");
1623 Builder.defineMacro("__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001624 }
1625};
1626} // end anonymous namespace
1627
1628namespace {
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001629class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1630public:
Mike Stump1eb44332009-09-09 15:08:12 +00001631 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001632 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1633 Int64Type = SignedLongLong;
1634 }
1635};
1636} // end anonymous namespace
1637
1638namespace {
Eli Friedman6036ebe2009-07-05 22:31:18 +00001639class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1640public:
Mike Stump1eb44332009-09-09 15:08:12 +00001641 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman6036ebe2009-07-05 22:31:18 +00001642 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1643 IntMaxType = SignedLongLong;
1644 UIntMaxType = UnsignedLongLong;
1645 Int64Type = SignedLongLong;
1646 }
1647};
1648} // end anonymous namespace
1649
1650namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +00001651class ARMTargetInfo : public TargetInfo {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001652 // Possible FPU choices.
1653 enum FPUMode {
1654 NoFPU,
1655 VFP2FPU,
1656 VFP3FPU,
1657 NeonFPU
1658 };
1659
1660 static bool FPUModeIsVFP(FPUMode Mode) {
1661 return Mode >= VFP2FPU && Mode <= NeonFPU;
1662 }
1663
1664 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1665 static const char * const GCCRegNames[];
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001666
Daniel Dunbareac7c532009-12-18 18:42:37 +00001667 std::string ABI, CPU;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001668
1669 unsigned FPU : 3;
1670
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001671 unsigned IsThumb : 1;
1672
1673 // Initialized via features.
1674 unsigned SoftFloat : 1;
1675 unsigned SoftFloatABI : 1;
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001676
Chris Lattner2752c012010-03-03 19:03:45 +00001677 static const Builtin::Info BuiltinInfo[];
1678
Chris Lattner393ff042008-04-21 18:56:49 +00001679public:
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001680 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbareac7c532009-12-18 18:42:37 +00001681 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001682 {
Daniel Dunbara2a41612009-09-14 00:02:24 +00001683 SizeType = UnsignedInt;
1684 PtrDiffType = SignedInt;
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001685
Chris Lattner9bffb072010-04-23 16:29:58 +00001686 // {} in inline assembly are neon specifiers, not assembly variant
1687 // specifiers.
1688 NoAsmVariants = true;
Michael J. Spencer20249a12010-10-21 03:16:25 +00001689
Daniel Dunbareac7c532009-12-18 18:42:37 +00001690 // FIXME: Should we just treat this as a feature?
Daniel Dunbar0791aa52009-12-18 19:57:13 +00001691 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001692 if (IsThumb) {
1693 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1694 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001695 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001696 } else {
1697 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1698 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001699 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001700 }
John McCallee79a4c2010-08-21 22:46:04 +00001701
1702 // ARM targets default to using the ARM C++ ABI.
1703 CXXABI = CXXABI_ARM;
Eli Friedman61538a72008-05-20 14:21:01 +00001704 }
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001705 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbara2a41612009-09-14 00:02:24 +00001706 virtual bool setABI(const std::string &Name) {
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001707 ABI = Name;
1708
Daniel Dunbara2a41612009-09-14 00:02:24 +00001709 // The defaults (above) are for AAPCS, check if we need to change them.
1710 //
1711 // FIXME: We need support for -meabi... we could just mangle it into the
1712 // name.
1713 if (Name == "apcs-gnu") {
Daniel Dunbard410fa22010-01-27 20:23:08 +00001714 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbara2a41612009-09-14 00:02:24 +00001715 SizeType = UnsignedLong;
1716
Daniel Dunbar684de632010-04-22 16:14:54 +00001717 // Do not respect the alignment of bit-field types when laying out
1718 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
1719 UseBitFieldTypeAlignment = false;
1720
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001721 if (IsThumb) {
1722 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1723 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001724 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001725 } else {
1726 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1727 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001728 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001729 }
1730
Daniel Dunbara2a41612009-09-14 00:02:24 +00001731 // FIXME: Override "preferred align" for double and long long.
1732 } else if (Name == "aapcs") {
1733 // FIXME: Enumerated types are variable width in straight AAPCS.
1734 } else if (Name == "aapcs-linux") {
1735 ;
1736 } else
1737 return false;
1738
1739 return true;
1740 }
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001741
Daniel Dunbara91320b2009-12-21 23:28:17 +00001742 void getDefaultFeatures(const std::string &CPU,
1743 llvm::StringMap<bool> &Features) const {
1744 // FIXME: This should not be here.
1745 Features["vfp2"] = false;
1746 Features["vfp3"] = false;
1747 Features["neon"] = false;
1748
1749 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1750 Features["vfp2"] = true;
1751 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1752 Features["neon"] = true;
1753 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001754
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001755 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1756 const std::string &Name,
1757 bool Enabled) const {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001758 if (Name == "soft-float" || Name == "soft-float-abi") {
1759 Features[Name] = Enabled;
1760 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1761 // These effectively are a single option, reset them when any is enabled.
1762 if (Enabled)
1763 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1764 Features[Name] = Enabled;
1765 } else
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001766 return false;
1767
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001768 return true;
1769 }
1770
1771 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001772 FPU = NoFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001773 SoftFloat = SoftFloatABI = false;
1774 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1775 if (Features[i] == "+soft-float")
1776 SoftFloat = true;
1777 else if (Features[i] == "+soft-float-abi")
1778 SoftFloatABI = true;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001779 else if (Features[i] == "+vfp2")
1780 FPU = VFP2FPU;
1781 else if (Features[i] == "+vfp3")
1782 FPU = VFP3FPU;
1783 else if (Features[i] == "+neon")
1784 FPU = NeonFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001785 }
1786
1787 // Remove front-end specific options which the backend handles differently.
1788 std::vector<std::string>::iterator it;
1789 it = std::find(Features.begin(), Features.end(), "+soft-float");
1790 if (it != Features.end())
1791 Features.erase(it);
1792 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1793 if (it != Features.end())
1794 Features.erase(it);
1795 }
1796
Daniel Dunbareac7c532009-12-18 18:42:37 +00001797 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1798 return llvm::StringSwitch<const char*>(Name)
1799 .Cases("arm8", "arm810", "4")
1800 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1801 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1802 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1803 .Case("ep9312", "4T")
1804 .Cases("arm10tdmi", "arm1020t", "5T")
1805 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1806 .Case("arm926ej-s", "5TEJ")
1807 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1808 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001809 .Case("arm1136j-s", "6J")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001810 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001811 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001812 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1813 .Cases("cortex-a8", "cortex-a9", "7A")
Bob Wilson06f45632011-01-06 16:57:20 +00001814 .Case("cortex-m3", "7M")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001815 .Default(0);
1816 }
1817 virtual bool setCPU(const std::string &Name) {
1818 if (!getCPUDefineSuffix(Name))
1819 return false;
1820
1821 CPU = Name;
1822 return true;
1823 }
Chris Lattner33328642009-03-20 15:52:06 +00001824 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001825 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001826 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +00001827 Builder.defineMacro("__arm");
1828 Builder.defineMacro("__arm__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001829
Chris Lattnerc0f59212009-03-02 22:27:17 +00001830 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001831 Builder.defineMacro("__ARMEL__");
1832 Builder.defineMacro("__LITTLE_ENDIAN__");
1833 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001834
1835 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramera9992772010-01-09 17:55:51 +00001836 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001837
Mike Stump437bb4b2009-04-08 02:07:04 +00001838 // Subtarget options.
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001839
Daniel Dunbareac7c532009-12-18 18:42:37 +00001840 // FIXME: It's more complicated than this and we don't really support
1841 // interworking.
1842 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramera9992772010-01-09 17:55:51 +00001843 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001844
Daniel Dunbareac7c532009-12-18 18:42:37 +00001845 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramera9992772010-01-09 17:55:51 +00001846 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001847
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001848 if (SoftFloat)
Benjamin Kramera9992772010-01-09 17:55:51 +00001849 Builder.defineMacro("__SOFTFP__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001850
1851 if (CPU == "xscale")
Benjamin Kramera9992772010-01-09 17:55:51 +00001852 Builder.defineMacro("__XSCALE__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001853
Daniel Dunbara91320b2009-12-21 23:28:17 +00001854 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001855 if (IsThumb) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001856 Builder.defineMacro("__THUMBEL__");
1857 Builder.defineMacro("__thumb__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001858 if (IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001859 Builder.defineMacro("__thumb2__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001860 }
1861
1862 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramera9992772010-01-09 17:55:51 +00001863 Builder.defineMacro("__APCS_32__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001864
1865 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramera9992772010-01-09 17:55:51 +00001866 Builder.defineMacro("__VFP_FP__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001867
1868 // This only gets set when Neon instructions are actually available, unlike
1869 // the VFP define, hence the soft float and arch check. This is subtly
1870 // different from gcc, we follow the intent which was that it should be set
1871 // when Neon instructions are actually available.
1872 if (FPU == NeonFPU && !SoftFloat && IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001873 Builder.defineMacro("__ARM_NEON__");
Chris Lattner393ff042008-04-21 18:56:49 +00001874 }
1875 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1876 unsigned &NumRecords) const {
Chris Lattner2752c012010-03-03 19:03:45 +00001877 Records = BuiltinInfo;
1878 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner393ff042008-04-21 18:56:49 +00001879 }
1880 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001881 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +00001882 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001883 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001884 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001885 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001886 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001887 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001888 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001889 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001890 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +00001891 default:
Nate Begemanad487f42008-04-22 05:03:19 +00001892 case 'l': // r0-r7
1893 case 'h': // r8-r15
1894 case 'w': // VFP Floating point register single precision
1895 case 'P': // VFP Floating point register double precision
Chris Lattner44def072009-04-26 07:16:29 +00001896 Info.setAllowsRegister();
Nate Begemanad487f42008-04-22 05:03:19 +00001897 return true;
1898 }
Chris Lattner393ff042008-04-21 18:56:49 +00001899 return false;
1900 }
1901 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001902 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +00001903 return "";
1904 }
1905};
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001906
1907const char * const ARMTargetInfo::GCCRegNames[] = {
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001908 // Integer registers
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001909 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001910 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
1911
1912 // Float registers
1913 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1914 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
1915 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001916 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001917
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001918 // Double registers
1919 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
1920 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
Dale Johannesend1455352010-10-28 01:05:37 +00001921 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
1922 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001923
1924 // Quad registers
Dale Johannesend1455352010-10-28 01:05:37 +00001925 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
1926 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001927};
1928
1929void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001930 unsigned &NumNames) const {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001931 Names = GCCRegNames;
1932 NumNames = llvm::array_lengthof(GCCRegNames);
1933}
1934
1935const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001936 { { "a1" }, "r0" },
1937 { { "a2" }, "r1" },
1938 { { "a3" }, "r2" },
1939 { { "a4" }, "r3" },
1940 { { "v1" }, "r4" },
1941 { { "v2" }, "r5" },
1942 { { "v3" }, "r6" },
1943 { { "v4" }, "r7" },
1944 { { "v5" }, "r8" },
1945 { { "v6", "rfp" }, "r9" },
1946 { { "sl" }, "r10" },
1947 { { "fp" }, "r11" },
1948 { { "ip" }, "r12" },
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001949 { { "r13" }, "sp" },
1950 { { "r14" }, "lr" },
1951 { { "r15" }, "pc" },
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001952 // The S, D and Q registers overlap, but aren't really aliases; we
1953 // don't want to substitute one of these for a different-sized one.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001954};
1955
1956void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1957 unsigned &NumAliases) const {
1958 Aliases = GCCRegAliases;
1959 NumAliases = llvm::array_lengthof(GCCRegAliases);
1960}
Chris Lattner2752c012010-03-03 19:03:45 +00001961
1962const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +00001963#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
1964#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1965 ALL_LANGUAGES, false },
Chris Lattner2752c012010-03-03 19:03:45 +00001966#include "clang/Basic/BuiltinsARM.def"
1967};
Chris Lattner393ff042008-04-21 18:56:49 +00001968} // end anonymous namespace.
1969
Eli Friedmana9f54962008-08-20 07:44:10 +00001970
1971namespace {
Mike Stump1eb44332009-09-09 15:08:12 +00001972class DarwinARMTargetInfo :
Torok Edwin5f6c1942009-06-30 17:10:35 +00001973 public DarwinTargetInfo<ARMTargetInfo> {
1974protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +00001975 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +00001976 MacroBuilder &Builder) const {
Daniel Dunbar21ae3192010-01-26 01:44:04 +00001977 getDarwinDefines(Builder, Opts, Triple);
Eli Friedmanb030f022009-04-19 21:38:35 +00001978 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001979
Torok Edwin5f6c1942009-06-30 17:10:35 +00001980public:
Mike Stump1eb44332009-09-09 15:08:12 +00001981 DarwinARMTargetInfo(const std::string& triple)
Daniel Dunbar350b9f32010-05-27 07:00:26 +00001982 : DarwinTargetInfo<ARMTargetInfo>(triple) {
1983 HasAlignMac68kSupport = true;
1984 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001985};
1986} // end anonymous namespace.
1987
Reid Spencer5f016e22007-07-11 17:01:13 +00001988namespace {
Eli Friedman01b86682008-08-20 07:28:14 +00001989class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +00001990 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1991 static const char * const GCCRegNames[];
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00001992 bool SoftFloat;
Gabor Greif26658672008-02-21 16:29:08 +00001993public:
Eli Friedman01b86682008-08-20 07:28:14 +00001994 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1995 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +00001996 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 +00001997 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedman01b86682008-08-20 07:28:14 +00001998 }
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00001999 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
2000 const std::string &Name,
2001 bool Enabled) const {
2002 if (Name == "soft-float")
2003 Features[Name] = Enabled;
2004 else
2005 return false;
2006
2007 return true;
2008 }
2009 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
2010 SoftFloat = false;
2011 for (unsigned i = 0, e = Features.size(); i != e; ++i)
2012 if (Features[i] == "+soft-float")
2013 SoftFloat = true;
2014 }
Chris Lattner33328642009-03-20 15:52:06 +00002015 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002016 MacroBuilder &Builder) const {
2017 DefineStd(Builder, "sparc", Opts);
2018 Builder.defineMacro("__sparcv8");
2019 Builder.defineMacro("__REGISTER_PREFIX__", "");
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002020
2021 if (SoftFloat)
2022 Builder.defineMacro("SOFT_FLOAT", "1");
Gabor Greif26658672008-02-21 16:29:08 +00002023 }
2024 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2025 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002026 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +00002027 }
2028 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002029 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +00002030 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002031 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002032 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002033 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002034 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00002035 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +00002036 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002037 // FIXME: Implement!
2038 return false;
Gabor Greif26658672008-02-21 16:29:08 +00002039 }
2040 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002041 // FIXME: Implement!
2042 return "";
Gabor Greif26658672008-02-21 16:29:08 +00002043 }
2044};
2045
Chris Lattnere957f532009-01-27 01:58:38 +00002046const char * const SparcV8TargetInfo::GCCRegNames[] = {
2047 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2048 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2049 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2050 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
2051};
2052
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002053void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002054 unsigned &NumNames) const {
2055 Names = GCCRegNames;
2056 NumNames = llvm::array_lengthof(GCCRegNames);
2057}
2058
2059const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002060 { { "g0" }, "r0" },
2061 { { "g1" }, "r1" },
2062 { { "g2" }, "r2" },
2063 { { "g3" }, "r3" },
2064 { { "g4" }, "r4" },
2065 { { "g5" }, "r5" },
2066 { { "g6" }, "r6" },
2067 { { "g7" }, "r7" },
2068 { { "o0" }, "r8" },
2069 { { "o1" }, "r9" },
2070 { { "o2" }, "r10" },
2071 { { "o3" }, "r11" },
2072 { { "o4" }, "r12" },
2073 { { "o5" }, "r13" },
2074 { { "o6", "sp" }, "r14" },
2075 { { "o7" }, "r15" },
2076 { { "l0" }, "r16" },
2077 { { "l1" }, "r17" },
2078 { { "l2" }, "r18" },
2079 { { "l3" }, "r19" },
2080 { { "l4" }, "r20" },
2081 { { "l5" }, "r21" },
2082 { { "l6" }, "r22" },
2083 { { "l7" }, "r23" },
2084 { { "i0" }, "r24" },
2085 { { "i1" }, "r25" },
2086 { { "i2" }, "r26" },
2087 { { "i3" }, "r27" },
2088 { { "i4" }, "r28" },
2089 { { "i5" }, "r29" },
2090 { { "i6", "fp" }, "r30" },
2091 { { "i7" }, "r31" },
Chris Lattnere957f532009-01-27 01:58:38 +00002092};
2093
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002094void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002095 unsigned &NumAliases) const {
2096 Aliases = GCCRegAliases;
2097 NumAliases = llvm::array_lengthof(GCCRegAliases);
2098}
Gabor Greif26658672008-02-21 16:29:08 +00002099} // end anonymous namespace.
2100
Eli Friedman01b86682008-08-20 07:28:14 +00002101namespace {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002102class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
2103public:
2104 AuroraUXSparcV8TargetInfo(const std::string& triple) :
2105 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
2106 SizeType = UnsignedInt;
2107 PtrDiffType = SignedInt;
2108 }
2109};
Torok Edwin5f6c1942009-06-30 17:10:35 +00002110class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedman01b86682008-08-20 07:28:14 +00002111public:
2112 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwin5f6c1942009-06-30 17:10:35 +00002113 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmanf509d732008-11-02 02:43:55 +00002114 SizeType = UnsignedInt;
2115 PtrDiffType = SignedInt;
Eli Friedman01b86682008-08-20 07:28:14 +00002116 }
2117};
2118} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00002119
Chris Lattner2621fd12008-05-08 05:58:21 +00002120namespace {
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002121 class MSP430TargetInfo : public TargetInfo {
2122 static const char * const GCCRegNames[];
2123 public:
2124 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
2125 TLSSupported = false;
Anton Korobeynikov09f52a62010-01-30 12:55:11 +00002126 IntWidth = 16; IntAlign = 16;
2127 LongWidth = 32; LongLongWidth = 64;
2128 LongAlign = LongLongAlign = 16;
2129 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002130 SizeType = UnsignedInt;
2131 IntMaxType = SignedLong;
2132 UIntMaxType = UnsignedLong;
2133 IntPtrType = SignedShort;
2134 PtrDiffType = SignedInt;
Edward O'Callaghan9cf910e2009-11-21 00:49:54 +00002135 SigAtomicType = SignedLong;
Anton Korobeynikov5d7c2512009-12-19 01:32:37 +00002136 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002137 }
2138 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002139 MacroBuilder &Builder) const {
2140 Builder.defineMacro("MSP430");
2141 Builder.defineMacro("__MSP430__");
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002142 // FIXME: defines for different 'flavours' of MCU
2143 }
2144 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2145 unsigned &NumRecords) const {
2146 // FIXME: Implement.
2147 Records = 0;
2148 NumRecords = 0;
2149 }
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002150 virtual void getGCCRegNames(const char * const *&Names,
2151 unsigned &NumNames) const;
2152 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2153 unsigned &NumAliases) const {
2154 // No aliases.
2155 Aliases = 0;
2156 NumAliases = 0;
2157 }
2158 virtual bool validateAsmConstraint(const char *&Name,
2159 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov03265b62009-10-15 23:17:13 +00002160 // No target constraints for now.
2161 return false;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002162 }
2163 virtual const char *getClobbers() const {
2164 // FIXME: Is this really right?
2165 return "";
2166 }
2167 virtual const char *getVAListDeclaration() const {
2168 // FIXME: implement
Anton Korobeynikoveb716852009-05-08 18:24:57 +00002169 return "typedef char* __builtin_va_list;";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002170 }
2171 };
2172
2173 const char * const MSP430TargetInfo::GCCRegNames[] = {
2174 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2175 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2176 };
2177
2178 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
2179 unsigned &NumNames) const {
2180 Names = GCCRegNames;
2181 NumNames = llvm::array_lengthof(GCCRegNames);
2182 }
2183}
2184
2185
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002186namespace {
2187 class SystemZTargetInfo : public TargetInfo {
2188 static const char * const GCCRegNames[];
2189 public:
2190 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
2191 TLSSupported = false;
2192 IntWidth = IntAlign = 32;
2193 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
2194 PointerWidth = PointerAlign = 64;
Chris Lattner1932e122009-11-07 18:59:41 +00002195 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
2196 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002197 }
2198 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002199 MacroBuilder &Builder) const {
2200 Builder.defineMacro("__s390__");
2201 Builder.defineMacro("__s390x__");
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002202 }
2203 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2204 unsigned &NumRecords) const {
2205 // FIXME: Implement.
2206 Records = 0;
2207 NumRecords = 0;
2208 }
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002209
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002210 virtual void getGCCRegNames(const char * const *&Names,
2211 unsigned &NumNames) const;
2212 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2213 unsigned &NumAliases) const {
2214 // No aliases.
2215 Aliases = 0;
2216 NumAliases = 0;
2217 }
2218 virtual bool validateAsmConstraint(const char *&Name,
2219 TargetInfo::ConstraintInfo &info) const {
2220 // FIXME: implement
2221 return true;
2222 }
2223 virtual const char *getClobbers() const {
2224 // FIXME: Is this really right?
2225 return "";
2226 }
2227 virtual const char *getVAListDeclaration() const {
2228 // FIXME: implement
2229 return "typedef char* __builtin_va_list;";
2230 }
2231 };
2232
2233 const char * const SystemZTargetInfo::GCCRegNames[] = {
2234 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2235 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2236 };
2237
2238 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
2239 unsigned &NumNames) const {
2240 Names = GCCRegNames;
2241 NumNames = llvm::array_lengthof(GCCRegNames);
2242 }
2243}
2244
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002245namespace {
2246 class BlackfinTargetInfo : public TargetInfo {
2247 static const char * const GCCRegNames[];
2248 public:
2249 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
2250 TLSSupported = false;
2251 DoubleAlign = 32;
2252 LongLongAlign = 32;
2253 LongDoubleAlign = 32;
Chris Lattner1932e122009-11-07 18:59:41 +00002254 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002255 }
2256
2257 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002258 MacroBuilder &Builder) const {
2259 DefineStd(Builder, "bfin", Opts);
2260 DefineStd(Builder, "BFIN", Opts);
2261 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002262 // FIXME: This one is really dependent on -mcpu
Benjamin Kramera9992772010-01-09 17:55:51 +00002263 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002264 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
2265 }
2266
2267 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2268 unsigned &NumRecords) const {
2269 // FIXME: Implement.
2270 Records = 0;
2271 NumRecords = 0;
2272 }
2273
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002274 virtual void getGCCRegNames(const char * const *&Names,
2275 unsigned &NumNames) const;
2276
2277 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2278 unsigned &NumAliases) const {
2279 // No aliases.
2280 Aliases = 0;
2281 NumAliases = 0;
2282 }
2283
2284 virtual bool validateAsmConstraint(const char *&Name,
2285 TargetInfo::ConstraintInfo &Info) const {
2286 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
2287 Info.setAllowsRegister();
2288 return true;
2289 }
2290 return false;
2291 }
2292
2293 virtual const char *getClobbers() const {
2294 return "";
2295 }
2296
2297 virtual const char *getVAListDeclaration() const {
2298 return "typedef char* __builtin_va_list;";
2299 }
2300 };
2301
2302 const char * const BlackfinTargetInfo::GCCRegNames[] = {
2303 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2304 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
2305 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
2306 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
2307 "a0", "a1", "cc",
2308 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
2309 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
2310 };
2311
2312 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
2313 unsigned &NumNames) const {
2314 Names = GCCRegNames;
2315 NumNames = llvm::array_lengthof(GCCRegNames);
2316 }
2317}
2318
Eli Friedmanb63decf2009-08-19 20:47:07 +00002319namespace {
2320
Mike Stump1eb44332009-09-09 15:08:12 +00002321 // LLVM and Clang cannot be used directly to output native binaries for
2322 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmanb63decf2009-08-19 20:47:07 +00002323 // type and alignment information.
Mike Stump1eb44332009-09-09 15:08:12 +00002324 //
2325 // TCE uses the llvm bitcode as input and uses it for generating customized
2326 // target processor and program binary. TCE co-design environment is
Eli Friedmanb63decf2009-08-19 20:47:07 +00002327 // publicly available in http://tce.cs.tut.fi
2328
2329 class TCETargetInfo : public TargetInfo{
2330 public:
2331 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
2332 TLSSupported = false;
2333 IntWidth = 32;
2334 LongWidth = LongLongWidth = 32;
Eli Friedmanb63decf2009-08-19 20:47:07 +00002335 PointerWidth = 32;
2336 IntAlign = 32;
2337 LongAlign = LongLongAlign = 32;
2338 PointerAlign = 32;
2339 SizeType = UnsignedInt;
2340 IntMaxType = SignedLong;
2341 UIntMaxType = UnsignedLong;
2342 IntPtrType = SignedInt;
2343 PtrDiffType = SignedInt;
2344 FloatWidth = 32;
2345 FloatAlign = 32;
2346 DoubleWidth = 32;
2347 DoubleAlign = 32;
2348 LongDoubleWidth = 32;
2349 LongDoubleAlign = 32;
2350 FloatFormat = &llvm::APFloat::IEEEsingle;
2351 DoubleFormat = &llvm::APFloat::IEEEsingle;
2352 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner3a47c4e2010-03-04 21:07:38 +00002353 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
2354 "i16:16:32-i32:32:32-i64:32:32-"
2355 "f32:32:32-f64:64:64-v64:64:64-"
2356 "v128:128:128-a0:0:64-n32";
Eli Friedmanb63decf2009-08-19 20:47:07 +00002357 }
2358
2359 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002360 MacroBuilder &Builder) const {
2361 DefineStd(Builder, "tce", Opts);
2362 Builder.defineMacro("__TCE__");
2363 Builder.defineMacro("__TCE_V1__");
Eli Friedmanb63decf2009-08-19 20:47:07 +00002364 }
2365 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2366 unsigned &NumRecords) const {}
Daniel Dunbar55cc2ed2009-08-24 09:54:37 +00002367 virtual const char *getClobbers() const {
2368 return "";
2369 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002370 virtual const char *getVAListDeclaration() const {
2371 return "typedef void* __builtin_va_list;";
2372 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002373 virtual void getGCCRegNames(const char * const *&Names,
2374 unsigned &NumNames) const {}
2375 virtual bool validateAsmConstraint(const char *&Name,
2376 TargetInfo::ConstraintInfo &info) const {
2377 return true;
2378 }
2379 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2380 unsigned &NumAliases) const {}
2381 };
2382}
2383
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002384namespace {
2385class MipsTargetInfo : public TargetInfo {
Eric Christophered734732010-03-02 02:41:08 +00002386 std::string ABI, CPU;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002387 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2388 static const char * const GCCRegNames[];
2389public:
Eric Christophered734732010-03-02 02:41:08 +00002390 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002391 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2392 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2393 }
Eric Christophered734732010-03-02 02:41:08 +00002394 virtual const char *getABI() const { return ABI.c_str(); }
2395 virtual bool setABI(const std::string &Name) {
2396
2397 if ((Name == "o32") || (Name == "eabi")) {
2398 ABI = Name;
2399 return true;
2400 } else
2401 return false;
2402 }
2403 virtual bool setCPU(const std::string &Name) {
2404 CPU = Name;
2405 return true;
2406 }
2407 void getDefaultFeatures(const std::string &CPU,
2408 llvm::StringMap<bool> &Features) const {
2409 Features[ABI] = true;
2410 Features[CPU] = true;
2411 }
2412 virtual void getArchDefines(const LangOptions &Opts,
2413 MacroBuilder &Builder) const {
2414 if (ABI == "o32")
2415 Builder.defineMacro("__mips_o32");
2416 else if (ABI == "eabi")
2417 Builder.defineMacro("__mips_eabi");
2418 }
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002419 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002420 MacroBuilder &Builder) const {
2421 DefineStd(Builder, "mips", Opts);
2422 Builder.defineMacro("_mips");
2423 DefineStd(Builder, "MIPSEB", Opts);
2424 Builder.defineMacro("_MIPSEB");
2425 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002426 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002427 }
2428 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2429 unsigned &NumRecords) const {
2430 // FIXME: Implement!
2431 }
2432 virtual const char *getVAListDeclaration() const {
2433 return "typedef void* __builtin_va_list;";
2434 }
2435 virtual void getGCCRegNames(const char * const *&Names,
2436 unsigned &NumNames) const;
2437 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2438 unsigned &NumAliases) const;
2439 virtual bool validateAsmConstraint(const char *&Name,
2440 TargetInfo::ConstraintInfo &Info) const {
2441 switch (*Name) {
2442 default:
2443 case 'r': // CPU registers.
2444 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2445 case 'y': // Equivalent to "r", backwards compatibility only.
2446 case 'f': // floating-point registers.
2447 Info.setAllowsRegister();
2448 return true;
2449 }
2450 return false;
2451 }
2452
2453 virtual const char *getClobbers() const {
2454 // FIXME: Implement!
2455 return "";
2456 }
2457};
2458
2459const char * const MipsTargetInfo::GCCRegNames[] = {
Michael J. Spencer20249a12010-10-21 03:16:25 +00002460 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002461 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2462 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2463 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2464 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2465 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2466 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2467 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2468 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2469 "$fcc5","$fcc6","$fcc7"
2470};
2471
2472void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2473 unsigned &NumNames) const {
2474 Names = GCCRegNames;
2475 NumNames = llvm::array_lengthof(GCCRegNames);
2476}
2477
2478const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2479 { { "at" }, "$1" },
2480 { { "v0" }, "$2" },
2481 { { "v1" }, "$3" },
2482 { { "a0" }, "$4" },
2483 { { "a1" }, "$5" },
2484 { { "a2" }, "$6" },
2485 { { "a3" }, "$7" },
2486 { { "t0" }, "$8" },
2487 { { "t1" }, "$9" },
2488 { { "t2" }, "$10" },
2489 { { "t3" }, "$11" },
2490 { { "t4" }, "$12" },
2491 { { "t5" }, "$13" },
2492 { { "t6" }, "$14" },
2493 { { "t7" }, "$15" },
2494 { { "s0" }, "$16" },
2495 { { "s1" }, "$17" },
2496 { { "s2" }, "$18" },
2497 { { "s3" }, "$19" },
2498 { { "s4" }, "$20" },
2499 { { "s5" }, "$21" },
2500 { { "s6" }, "$22" },
2501 { { "s7" }, "$23" },
2502 { { "t8" }, "$24" },
2503 { { "t9" }, "$25" },
2504 { { "k0" }, "$26" },
2505 { { "k1" }, "$27" },
2506 { { "gp" }, "$28" },
2507 { { "sp" }, "$29" },
2508 { { "fp" }, "$30" },
2509 { { "ra" }, "$31" }
2510};
2511
2512void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2513 unsigned &NumAliases) const {
2514 Aliases = GCCRegAliases;
2515 NumAliases = llvm::array_lengthof(GCCRegAliases);
2516}
2517} // end anonymous namespace.
2518
2519namespace {
2520class MipselTargetInfo : public MipsTargetInfo {
2521public:
2522 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2523 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2524 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2525 }
2526
2527 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002528 MacroBuilder &Builder) const;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002529};
2530
2531void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002532 MacroBuilder &Builder) const {
2533 DefineStd(Builder, "mips", Opts);
2534 Builder.defineMacro("_mips");
2535 DefineStd(Builder, "MIPSEL", Opts);
2536 Builder.defineMacro("_MIPSEL");
2537 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002538 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002539}
2540} // end anonymous namespace.
2541
Reid Spencer5f016e22007-07-11 17:01:13 +00002542//===----------------------------------------------------------------------===//
2543// Driver code
2544//===----------------------------------------------------------------------===//
2545
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002546static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002547 llvm::Triple Triple(T);
2548 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman61538a72008-05-20 14:21:01 +00002549
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002550 switch (Triple.getArch()) {
2551 default:
2552 return NULL;
Eli Friedman61538a72008-05-20 14:21:01 +00002553
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002554 case llvm::Triple::arm:
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +00002555 case llvm::Triple::thumb:
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002556 switch (os) {
Rafael Espindola022a8a52010-06-10 00:46:51 +00002557 case llvm::Triple::Linux:
2558 return new LinuxTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002559 case llvm::Triple::Darwin:
Eli Friedmaned855cb2008-08-21 00:13:15 +00002560 return new DarwinARMTargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002561 case llvm::Triple::FreeBSD:
Torok Edwin5f6c1942009-06-30 17:10:35 +00002562 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002563 default:
2564 return new ARMTargetInfo(T);
2565 }
Eli Friedman61538a72008-05-20 14:21:01 +00002566
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002567 case llvm::Triple::bfin:
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002568 return new BlackfinTargetInfo(T);
2569
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002570 case llvm::Triple::msp430:
2571 return new MSP430TargetInfo(T);
Eli Friedman61538a72008-05-20 14:21:01 +00002572
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002573 case llvm::Triple::mips:
2574 if (os == llvm::Triple::Psp)
2575 return new PSPTargetInfo<MipsTargetInfo>(T);
2576 if (os == llvm::Triple::Linux)
2577 return new LinuxTargetInfo<MipsTargetInfo>(T);
2578 return new MipsTargetInfo(T);
2579
2580 case llvm::Triple::mipsel:
2581 if (os == llvm::Triple::Psp)
2582 return new PSPTargetInfo<MipselTargetInfo>(T);
2583 if (os == llvm::Triple::Linux)
2584 return new LinuxTargetInfo<MipselTargetInfo>(T);
2585 return new MipselTargetInfo(T);
2586
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002587 case llvm::Triple::ppc:
2588 if (os == llvm::Triple::Darwin)
Roman Divackyc81f2a22011-01-06 08:27:10 +00002589 return new DarwinPPC32TargetInfo(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002590 else if (os == llvm::Triple::FreeBSD)
2591 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002592 return new PPC32TargetInfo(T);
2593
2594 case llvm::Triple::ppc64:
2595 if (os == llvm::Triple::Darwin)
Daniel Dunbar4c6a2262010-05-30 00:07:30 +00002596 return new DarwinPPC64TargetInfo(T);
John Thompson3f6918a2009-11-19 17:18:50 +00002597 else if (os == llvm::Triple::Lv2)
2598 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002599 else if (os == llvm::Triple::FreeBSD)
2600 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002601 return new PPC64TargetInfo(T);
2602
Chris Lattner9cbeb632010-03-06 21:21:27 +00002603 case llvm::Triple::mblaze:
2604 return new MBlazeTargetInfo(T);
2605
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002606 case llvm::Triple::sparc:
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002607 if (os == llvm::Triple::AuroraUX)
2608 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002609 if (os == llvm::Triple::Solaris)
2610 return new SolarisSparcV8TargetInfo(T);
2611 return new SparcV8TargetInfo(T);
2612
John Thompson3f6918a2009-11-19 17:18:50 +00002613 // FIXME: Need a real SPU target.
2614 case llvm::Triple::cellspu:
2615 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2616
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002617 case llvm::Triple::systemz:
2618 return new SystemZTargetInfo(T);
2619
Eli Friedmanb63decf2009-08-19 20:47:07 +00002620 case llvm::Triple::tce:
2621 return new TCETargetInfo(T);
2622
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002623 case llvm::Triple::x86:
2624 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002625 case llvm::Triple::AuroraUX:
2626 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002627 case llvm::Triple::Darwin:
2628 return new DarwinI386TargetInfo(T);
2629 case llvm::Triple::Linux:
2630 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2631 case llvm::Triple::DragonFly:
2632 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2633 case llvm::Triple::NetBSD:
2634 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2635 case llvm::Triple::OpenBSD:
2636 return new OpenBSDI386TargetInfo(T);
2637 case llvm::Triple::FreeBSD:
2638 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
Chris Lattner38e317d2010-07-07 16:01:42 +00002639 case llvm::Triple::Minix:
2640 return new MinixTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002641 case llvm::Triple::Solaris:
2642 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2643 case llvm::Triple::Cygwin:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002644 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002645 case llvm::Triple::MinGW32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002646 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002647 case llvm::Triple::Win32:
Michael J. Spencera764e832010-10-21 08:22:51 +00002648 return new VisualStudioWindowsX86_32TargetInfo(T);
Chris Lattner86ed3a32010-04-11 19:29:39 +00002649 case llvm::Triple::Haiku:
2650 return new HaikuX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002651 default:
2652 return new X86_32TargetInfo(T);
2653 }
2654
2655 case llvm::Triple::x86_64:
2656 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002657 case llvm::Triple::AuroraUX:
2658 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002659 case llvm::Triple::Darwin:
2660 return new DarwinX86_64TargetInfo(T);
2661 case llvm::Triple::Linux:
2662 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner7a7ca282010-01-09 05:41:14 +00002663 case llvm::Triple::DragonFly:
2664 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002665 case llvm::Triple::NetBSD:
2666 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2667 case llvm::Triple::OpenBSD:
2668 return new OpenBSDX86_64TargetInfo(T);
2669 case llvm::Triple::FreeBSD:
2670 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2671 case llvm::Triple::Solaris:
2672 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002673 case llvm::Triple::MinGW64:
2674 return new MinGWX86_64TargetInfo(T);
2675 case llvm::Triple::Win32: // This is what Triple.h supports now.
Michael J. Spencera764e832010-10-21 08:22:51 +00002676 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002677 default:
2678 return new X86_64TargetInfo(T);
2679 }
2680 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002681}
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002682
2683/// CreateTargetInfo - Return the target info object for the specified target
2684/// triple.
2685TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002686 TargetOptions &Opts) {
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002687 llvm::Triple Triple(Opts.Triple);
2688
2689 // Construct the target
2690 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2691 if (!Target) {
2692 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2693 return 0;
2694 }
2695
Daniel Dunbareac7c532009-12-18 18:42:37 +00002696 // Set the target CPU if specified.
2697 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2698 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2699 return 0;
2700 }
2701
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002702 // Set the target ABI if specified.
2703 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2704 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2705 return 0;
2706 }
2707
Charles Davis98b7c5c2010-06-11 01:06:47 +00002708 // Set the target C++ ABI.
John McCallee79a4c2010-08-21 22:46:04 +00002709 if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Charles Davis98b7c5c2010-06-11 01:06:47 +00002710 Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
2711 return 0;
2712 }
2713
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002714 // Compute the default target features, we need the target to handle this
2715 // because features may have dependencies on one another.
2716 llvm::StringMap<bool> Features;
2717 Target->getDefaultFeatures(Opts.CPU, Features);
2718
2719 // Apply the user specified deltas.
2720 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2721 ie = Opts.Features.end(); it != ie; ++it) {
2722 const char *Name = it->c_str();
2723
2724 // Apply the feature via the target.
2725 if ((Name[0] != '-' && Name[0] != '+') ||
2726 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2727 Diags.Report(diag::err_target_invalid_feature) << Name;
2728 return 0;
2729 }
2730 }
2731
2732 // Add the features to the compile options.
2733 //
2734 // FIXME: If we are completely confident that we have the right set, we only
2735 // need to pass the minuses.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002736 Opts.Features.clear();
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002737 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2738 ie = Features.end(); it != ie; ++it)
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002739 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2740 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002741
2742 return Target.take();
2743}