blob: 19e758747b0c1395ae295766d84cdc9de0b21435 [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 = "";
Douglas Gregor12e84642011-01-12 21:19:25 +0000260 this->WIntType = TargetInfo::UnsignedInt;
Torok Edwin5f6c1942009-06-30 17:10:35 +0000261 }
262};
263
Chris Lattnerb62bb282009-07-13 20:29:08 +0000264// NetBSD Target
265template<typename Target>
266class NetBSDTargetInfo : public OSTargetInfo<Target> {
267protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000268 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000269 MacroBuilder &Builder) const {
Chris Lattnerb62bb282009-07-13 20:29:08 +0000270 // NetBSD defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000271 Builder.defineMacro("__NetBSD__");
272 Builder.defineMacro("__unix__");
273 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000274 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000275 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerb62bb282009-07-13 20:29:08 +0000276 }
277public:
Mike Stump1eb44332009-09-09 15:08:12 +0000278 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerb62bb282009-07-13 20:29:08 +0000279 : OSTargetInfo<Target>(triple) {
280 this->UserLabelPrefix = "";
281 }
282};
283
Torok Edwin5f6c1942009-06-30 17:10:35 +0000284// OpenBSD Target
285template<typename Target>
286class OpenBSDTargetInfo : public OSTargetInfo<Target> {
287protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000288 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000289 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000290 // OpenBSD defines; list based off of gcc output
291
Benjamin Kramera9992772010-01-09 17:55:51 +0000292 Builder.defineMacro("__OpenBSD__");
293 DefineStd(Builder, "unix", Opts);
294 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000295 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000296 Builder.defineMacro("_POSIX_THREADS");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000297 }
298public:
Mike Stump1eb44332009-09-09 15:08:12 +0000299 OpenBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000300 : OSTargetInfo<Target>(triple) {}
301};
302
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000303// PSP Target
304template<typename Target>
305class PSPTargetInfo : public OSTargetInfo<Target> {
306protected:
307 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000308 MacroBuilder &Builder) const {
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000309 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramera9992772010-01-09 17:55:51 +0000310 Builder.defineMacro("PSP");
311 Builder.defineMacro("_PSP");
312 Builder.defineMacro("__psp__");
313 Builder.defineMacro("__ELF__");
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000314 }
315public:
316 PSPTargetInfo(const std::string& triple)
317 : OSTargetInfo<Target>(triple) {
318 this->UserLabelPrefix = "";
319 }
320};
321
John Thompson3f6918a2009-11-19 17:18:50 +0000322// PS3 PPU Target
323template<typename Target>
324class PS3PPUTargetInfo : public OSTargetInfo<Target> {
325protected:
326 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000327 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000328 // PS3 PPU defines.
John Thompsonfb457972010-03-25 16:18:32 +0000329 Builder.defineMacro("__PPC__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000330 Builder.defineMacro("__PPU__");
331 Builder.defineMacro("__CELLOS_LV2__");
332 Builder.defineMacro("__ELF__");
333 Builder.defineMacro("__LP32__");
John Thompson8e6065a2010-06-24 22:44:13 +0000334 Builder.defineMacro("_ARCH_PPC64");
335 Builder.defineMacro("__powerpc64__");
John Thompson3f6918a2009-11-19 17:18:50 +0000336 }
337public:
338 PS3PPUTargetInfo(const std::string& triple)
339 : OSTargetInfo<Target>(triple) {
340 this->UserLabelPrefix = "";
John Thompsonec387af2009-12-18 14:21:08 +0000341 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
John Thompson8e6065a2010-06-24 22:44:13 +0000342 this->IntMaxType = TargetInfo::SignedLongLong;
343 this->UIntMaxType = TargetInfo::UnsignedLongLong;
344 this->Int64Type = TargetInfo::SignedLongLong;
John Thompsonec387af2009-12-18 14:21:08 +0000345 this->SizeType = TargetInfo::UnsignedInt;
John Thompson8e6065a2010-06-24 22:44:13 +0000346 this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
347 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
John Thompson3f6918a2009-11-19 17:18:50 +0000348 }
349};
350
351// FIXME: Need a real SPU target.
352// PS3 SPU Target
353template<typename Target>
354class PS3SPUTargetInfo : public OSTargetInfo<Target> {
355protected:
356 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000357 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000358 // PS3 PPU defines.
Benjamin Kramera9992772010-01-09 17:55:51 +0000359 Builder.defineMacro("__SPU__");
360 Builder.defineMacro("__ELF__");
John Thompson3f6918a2009-11-19 17:18:50 +0000361 }
362public:
363 PS3SPUTargetInfo(const std::string& triple)
364 : OSTargetInfo<Target>(triple) {
365 this->UserLabelPrefix = "";
366 }
367};
368
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000369// AuroraUX target
370template<typename Target>
371class AuroraUXTargetInfo : public OSTargetInfo<Target> {
372protected:
373 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000374 MacroBuilder &Builder) const {
375 DefineStd(Builder, "sun", Opts);
376 DefineStd(Builder, "unix", Opts);
377 Builder.defineMacro("__ELF__");
378 Builder.defineMacro("__svr4__");
379 Builder.defineMacro("__SVR4");
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000380 }
381public:
382 AuroraUXTargetInfo(const std::string& triple)
383 : OSTargetInfo<Target>(triple) {
384 this->UserLabelPrefix = "";
385 this->WCharType = this->SignedLong;
386 // FIXME: WIntType should be SignedLong
387 }
388};
389
Torok Edwin5f6c1942009-06-30 17:10:35 +0000390// Solaris target
391template<typename Target>
392class SolarisTargetInfo : public OSTargetInfo<Target> {
393protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000394 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000395 MacroBuilder &Builder) const {
396 DefineStd(Builder, "sun", Opts);
397 DefineStd(Builder, "unix", Opts);
398 Builder.defineMacro("__ELF__");
399 Builder.defineMacro("__svr4__");
400 Builder.defineMacro("__SVR4");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000401 }
402public:
Mike Stump1eb44332009-09-09 15:08:12 +0000403 SolarisTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000404 : OSTargetInfo<Target>(triple) {
405 this->UserLabelPrefix = "";
406 this->WCharType = this->SignedLong;
407 // FIXME: WIntType should be SignedLong
408 }
409};
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000410
411// Windows target
412template<typename Target>
413class WindowsTargetInfo : public OSTargetInfo<Target> {
414protected:
415 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
416 MacroBuilder &Builder) const {
Michael J. Spencera764e832010-10-21 08:22:51 +0000417 Builder.defineMacro("_WIN32");
418 }
419 void getVisualStudioDefines(const LangOptions &Opts,
420 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000421 if (Opts.CPlusPlus) {
422 if (Opts.RTTI)
423 Builder.defineMacro("_CPPRTTI");
424
425 if (Opts.Exceptions)
426 Builder.defineMacro("_CPPUNWIND");
427 }
428
429 if (!Opts.CharIsSigned)
430 Builder.defineMacro("_CHAR_UNSIGNED");
431
432 // FIXME: POSIXThreads isn't exactly the option this should be defined for,
433 // but it works for now.
434 if (Opts.POSIXThreads)
435 Builder.defineMacro("_MT");
Michael J. Spencera764e832010-10-21 08:22:51 +0000436
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000437 if (Opts.MSCVersion != 0)
438 Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
439
440 if (Opts.Microsoft) {
441 Builder.defineMacro("_MSC_EXTENSIONS");
442
443 if (Opts.CPlusPlus0x) {
444 Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
445 Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
446 Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
447 }
448 }
449
450 Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000451 }
452
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000453public:
454 WindowsTargetInfo(const std::string &triple)
455 : OSTargetInfo<Target>(triple) {}
456};
457
Mike Stump1eb44332009-09-09 15:08:12 +0000458} // end anonymous namespace.
Torok Edwin5f6c1942009-06-30 17:10:35 +0000459
Chris Lattnerd29b6302008-10-05 21:50:58 +0000460//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000461// Specific target implementations.
462//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000463
Eli Friedmane4277982008-08-20 23:11:40 +0000464namespace {
465// PPC abstract base class
466class PPCTargetInfo : public TargetInfo {
467 static const Builtin::Info BuiltinInfo[];
468 static const char * const GCCRegNames[];
469 static const TargetInfo::GCCRegAlias GCCRegAliases[];
470
471public:
Eli Friedman15b91762009-06-05 07:05:05 +0000472 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
473
Eli Friedmane4277982008-08-20 23:11:40 +0000474 virtual void getTargetBuiltins(const Builtin::Info *&Records,
475 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000476 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000477 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000478 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000479
Chris Lattner33328642009-03-20 15:52:06 +0000480 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000481 MacroBuilder &Builder) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000482
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000483 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000484 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000485 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000486 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000487 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000488 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000489 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000490 default: return false;
491 case 'O': // Zero
John Thompson8e6065a2010-06-24 22:44:13 +0000492 break;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000493 case 'b': // Base register
494 case 'f': // Floating point register
Chris Lattner44def072009-04-26 07:16:29 +0000495 Info.setAllowsRegister();
John Thompson8e6065a2010-06-24 22:44:13 +0000496 break;
497 // FIXME: The following are added to allow parsing.
498 // I just took a guess at what the actions should be.
499 // Also, is more specific checking needed? I.e. specific registers?
Michael J. Spencer20249a12010-10-21 03:16:25 +0000500 case 'd': // Floating point register (containing 64-bit value)
John Thompson8e6065a2010-06-24 22:44:13 +0000501 case 'v': // Altivec vector register
502 Info.setAllowsRegister();
503 break;
504 case 'w':
505 switch (Name[1]) {
Michael J. Spencer20249a12010-10-21 03:16:25 +0000506 case 'd':// VSX vector register to hold vector double data
507 case 'f':// VSX vector register to hold vector float data
508 case 's':// VSX vector register to hold scalar float data
509 case 'a':// Any VSX register
John Thompson8e6065a2010-06-24 22:44:13 +0000510 break;
511 default:
512 return false;
513 }
514 Info.setAllowsRegister();
515 Name++; // Skip over 'w'.
516 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000517 case 'h': // `MQ', `CTR', or `LINK' register
518 case 'q': // `MQ' register
519 case 'c': // `CTR' register
520 case 'l': // `LINK' register
521 case 'x': // `CR' register (condition register) number 0
522 case 'y': // `CR' register (condition register)
523 case 'z': // `XER[CA]' carry bit (part of the XER register)
John Thompson8e6065a2010-06-24 22:44:13 +0000524 Info.setAllowsRegister();
525 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000526 case 'I': // Signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000527 case 'J': // Unsigned 16-bit constant shifted left 16 bits
Michael J. Spencer20249a12010-10-21 03:16:25 +0000528 // (use `L' instead for SImode constants)
529 case 'K': // Unsigned 16-bit constant
530 case 'L': // Signed 16-bit constant shifted left 16 bits
531 case 'M': // Constant larger than 31
532 case 'N': // Exact power of 2
533 case 'P': // Constant whose negation is a signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000534 case 'G': // Floating point constant that can be loaded into a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000535 // register with one instruction per word
John Thompson8e6065a2010-06-24 22:44:13 +0000536 case 'H': // Integer/Floating point constant that can be loaded
Michael J. Spencer20249a12010-10-21 03:16:25 +0000537 // into a register using three instructions
John Thompson8e6065a2010-06-24 22:44:13 +0000538 break;
539 case 'm': // Memory operand. Note that on PowerPC targets, m can
540 // include addresses that update the base register. It
541 // is therefore only safe to use `m' in an asm statement
542 // if that asm statement accesses the operand exactly once.
543 // The asm statement must also use `%U<opno>' as a
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000544 // placeholder for the "update" flag in the corresponding
Michael J. Spencer20249a12010-10-21 03:16:25 +0000545 // load or store instruction. For example:
John Thompson8e6065a2010-06-24 22:44:13 +0000546 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
Michael J. Spencer20249a12010-10-21 03:16:25 +0000547 // is correct but:
John Thompson8e6065a2010-06-24 22:44:13 +0000548 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
549 // is not. Use es rather than m if you don't want the base
Michael J. Spencer20249a12010-10-21 03:16:25 +0000550 // register to be updated.
551 case 'e':
John Thompson56b6eca2010-06-25 00:02:05 +0000552 if (Name[1] != 's')
553 return false;
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000554 // es: A "stable" memory operand; that is, one which does not
John Thompson8e6065a2010-06-24 22:44:13 +0000555 // include any automodification of the base register. Unlike
556 // `m', this constraint can be used in asm statements that
557 // might access the operand several times, or that might not
John Thompson56b6eca2010-06-25 00:02:05 +0000558 // access it at all.
John Thompson8e6065a2010-06-24 22:44:13 +0000559 Info.setAllowsMemory();
John Thompson56b6eca2010-06-25 00:02:05 +0000560 Name++; // Skip over 'e'.
John Thompson8e6065a2010-06-24 22:44:13 +0000561 break;
562 case 'Q': // Memory operand that is an offset from a register (it is
Michael J. Spencer20249a12010-10-21 03:16:25 +0000563 // usually better to use `m' or `es' in asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000564 case 'Z': // Memory operand that is an indexed or indirect from a
565 // register (it is usually better to use `m' or `es' in
Michael J. Spencer20249a12010-10-21 03:16:25 +0000566 // asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000567 Info.setAllowsMemory();
568 Info.setAllowsRegister();
569 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000570 case 'R': // AIX TOC entry
John Thompson8e6065a2010-06-24 22:44:13 +0000571 case 'a': // Address operand that is an indexed or indirect from a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000572 // register (`p' is preferable for asm statements)
573 case 'S': // Constant suitable as a 64-bit mask operand
574 case 'T': // Constant suitable as a 32-bit mask operand
575 case 'U': // System V Release 4 small data area reference
John Thompson8e6065a2010-06-24 22:44:13 +0000576 case 't': // AND masks that can be performed by two rldic{l, r}
Michael J. Spencer20249a12010-10-21 03:16:25 +0000577 // instructions
578 case 'W': // Vector constant that does not require memory
579 case 'j': // Vector constant that is all zeros.
John Thompson8e6065a2010-06-24 22:44:13 +0000580 break;
581 // End FIXME.
Anders Carlssond04c6e22007-11-27 04:11:28 +0000582 }
John Thompson8e6065a2010-06-24 22:44:13 +0000583 return true;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000584 }
Eli Friedmane4277982008-08-20 23:11:40 +0000585 virtual const char *getClobbers() const {
586 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000587 }
Eli Friedmane4277982008-08-20 23:11:40 +0000588};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000589
Eli Friedmane4277982008-08-20 23:11:40 +0000590const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +0000591#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
592#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
593 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000594#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmane4277982008-08-20 23:11:40 +0000595};
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000596
597
Chris Lattnerc0f59212009-03-02 22:27:17 +0000598/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
599/// #defines that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000600void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000601 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000602 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +0000603 Builder.defineMacro("__ppc__");
604 Builder.defineMacro("_ARCH_PPC");
Chris Lattnere03ae302010-02-16 18:14:57 +0000605 Builder.defineMacro("__powerpc__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000606 Builder.defineMacro("__POWERPC__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000607 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000608 Builder.defineMacro("_ARCH_PPC64");
609 Builder.defineMacro("_LP64");
610 Builder.defineMacro("__LP64__");
Chris Lattnere03ae302010-02-16 18:14:57 +0000611 Builder.defineMacro("__powerpc64__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000612 Builder.defineMacro("__ppc64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000613 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +0000614 Builder.defineMacro("__ppc__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000615 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000616
Chris Lattnerc0f59212009-03-02 22:27:17 +0000617 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +0000618 Builder.defineMacro("_BIG_ENDIAN");
619 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000620
Chris Lattnerc0f59212009-03-02 22:27:17 +0000621 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +0000622 Builder.defineMacro("__NATURAL_ALIGNMENT__");
623 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000624
Chris Lattnerc0f59212009-03-02 22:27:17 +0000625 // FIXME: Should be controlled by command line option.
Benjamin Kramera9992772010-01-09 17:55:51 +0000626 Builder.defineMacro("__LONG_DOUBLE_128__");
Michael J. Spencer20249a12010-10-21 03:16:25 +0000627
John Thompson3f6918a2009-11-19 17:18:50 +0000628 if (Opts.AltiVec) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000629 Builder.defineMacro("__VEC__", "10206");
630 Builder.defineMacro("__ALTIVEC__");
John Thompson3f6918a2009-11-19 17:18:50 +0000631 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000632}
633
Chris Lattner393ff042008-04-21 18:56:49 +0000634
Eli Friedmane4277982008-08-20 23:11:40 +0000635const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnere94e0d42009-09-16 05:05:27 +0000636 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
637 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
638 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
639 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
640 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
641 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
642 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
643 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmane4277982008-08-20 23:11:40 +0000644 "mq", "lr", "ctr", "ap",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000645 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmane4277982008-08-20 23:11:40 +0000646 "xer",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000647 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
648 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
649 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
650 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmane4277982008-08-20 23:11:40 +0000651 "vrsave", "vscr",
652 "spe_acc", "spefscr",
653 "sfp"
654};
Reid Spencer5f016e22007-07-11 17:01:13 +0000655
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000656void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000657 unsigned &NumNames) const {
658 Names = GCCRegNames;
659 NumNames = llvm::array_lengthof(GCCRegNames);
660}
Reid Spencer5f016e22007-07-11 17:01:13 +0000661
Eli Friedmane4277982008-08-20 23:11:40 +0000662const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
663 // While some of these aliases do map to different registers
664 // they still share the same register name.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000665 { { "0" }, "r0" },
666 { { "1"}, "r1" },
667 { { "2" }, "r2" },
668 { { "3" }, "r3" },
669 { { "4" }, "r4" },
670 { { "5" }, "r5" },
671 { { "6" }, "r6" },
672 { { "7" }, "r7" },
673 { { "8" }, "r8" },
674 { { "9" }, "r9" },
675 { { "10" }, "r10" },
676 { { "11" }, "r11" },
677 { { "12" }, "r12" },
678 { { "13" }, "r13" },
679 { { "14" }, "r14" },
680 { { "15" }, "r15" },
681 { { "16" }, "r16" },
682 { { "17" }, "r17" },
683 { { "18" }, "r18" },
684 { { "19" }, "r19" },
685 { { "20" }, "r20" },
686 { { "21" }, "r21" },
687 { { "22" }, "r22" },
688 { { "23" }, "r23" },
689 { { "24" }, "r24" },
690 { { "25" }, "r25" },
691 { { "26" }, "r26" },
692 { { "27" }, "r27" },
693 { { "28" }, "r28" },
694 { { "29" }, "r29" },
695 { { "30" }, "r30" },
696 { { "31" }, "r31" },
697 { { "fr0" }, "f0" },
698 { { "fr1" }, "f1" },
699 { { "fr2" }, "f2" },
700 { { "fr3" }, "f3" },
701 { { "fr4" }, "f4" },
702 { { "fr5" }, "f5" },
703 { { "fr6" }, "f6" },
704 { { "fr7" }, "f7" },
705 { { "fr8" }, "f8" },
706 { { "fr9" }, "f9" },
Mike Stump10880392009-09-17 21:15:00 +0000707 { { "fr10" }, "f10" },
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000708 { { "fr11" }, "f11" },
709 { { "fr12" }, "f12" },
710 { { "fr13" }, "f13" },
711 { { "fr14" }, "f14" },
712 { { "fr15" }, "f15" },
713 { { "fr16" }, "f16" },
714 { { "fr17" }, "f17" },
715 { { "fr18" }, "f18" },
716 { { "fr19" }, "f19" },
717 { { "fr20" }, "f20" },
718 { { "fr21" }, "f21" },
719 { { "fr22" }, "f22" },
720 { { "fr23" }, "f23" },
721 { { "fr24" }, "f24" },
722 { { "fr25" }, "f25" },
723 { { "fr26" }, "f26" },
724 { { "fr27" }, "f27" },
725 { { "fr28" }, "f28" },
726 { { "fr29" }, "f29" },
727 { { "fr30" }, "f30" },
728 { { "fr31" }, "f31" },
729 { { "cc" }, "cr0" },
Eli Friedmane4277982008-08-20 23:11:40 +0000730};
731
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000732void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000733 unsigned &NumAliases) const {
734 Aliases = GCCRegAliases;
735 NumAliases = llvm::array_lengthof(GCCRegAliases);
736}
737} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000738
739namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000740class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000741public:
Chris Lattnere03ae302010-02-16 18:14:57 +0000742 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedmaned855cb2008-08-21 00:13:15 +0000743 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 +0000744 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnere03ae302010-02-16 18:14:57 +0000745
746 if (getTriple().getOS() == llvm::Triple::FreeBSD)
Roman Divackyc81f2a22011-01-06 08:27:10 +0000747 SizeType = UnsignedInt;
748 }
749
750 virtual const char *getVAListDeclaration() const {
751 // This is the ELF definition, and is overridden by the Darwin sub-target
752 return "typedef struct __va_list_tag {"
753 " unsigned char gpr;"
754 " unsigned char fpr;"
755 " unsigned short reserved;"
756 " void* overflow_arg_area;"
757 " void* reg_save_area;"
758 "} __builtin_va_list[1];";
Eli Friedmaned855cb2008-08-21 00:13:15 +0000759 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000760};
761} // end anonymous namespace.
762
763namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000764class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000765public:
Eli Friedmane4277982008-08-20 23:11:40 +0000766 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000767 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman3c7b6e42009-07-01 03:36:11 +0000768 IntMaxType = SignedLong;
769 UIntMaxType = UnsignedLong;
770 Int64Type = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000771 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 +0000772 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerf291b102008-05-09 06:17:04 +0000773 }
Roman Divackyc81f2a22011-01-06 08:27:10 +0000774 virtual const char *getVAListDeclaration() const {
775 return "typedef char* __builtin_va_list;";
776 }
Eli Friedmane4277982008-08-20 23:11:40 +0000777};
778} // end anonymous namespace.
779
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000780
781namespace {
Roman Divackyc81f2a22011-01-06 08:27:10 +0000782class DarwinPPC32TargetInfo :
783 public DarwinTargetInfo<PPC32TargetInfo> {
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000784public:
Roman Divackyc81f2a22011-01-06 08:27:10 +0000785 DarwinPPC32TargetInfo(const std::string& triple)
786 : DarwinTargetInfo<PPC32TargetInfo>(triple) {
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000787 HasAlignMac68kSupport = true;
Roman Divackyc81f2a22011-01-06 08:27:10 +0000788 BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
789 }
790 virtual const char *getVAListDeclaration() const {
791 return "typedef char* __builtin_va_list;";
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000792 }
793};
794
795class DarwinPPC64TargetInfo :
796 public DarwinTargetInfo<PPC64TargetInfo> {
797public:
798 DarwinPPC64TargetInfo(const std::string& triple)
799 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
800 HasAlignMac68kSupport = true;
801 }
802};
803} // end anonymous namespace.
804
Reid Spencer5f016e22007-07-11 17:01:13 +0000805namespace {
Chris Lattner9cbeb632010-03-06 21:21:27 +0000806// MBlaze abstract base class
807class MBlazeTargetInfo : public TargetInfo {
808 static const char * const GCCRegNames[];
809 static const TargetInfo::GCCRegAlias GCCRegAliases[];
810
811public:
812 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
Wesley Pecka48fa4b2010-12-12 20:56:47 +0000813 DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
Chris Lattner9cbeb632010-03-06 21:21:27 +0000814 }
815
816 virtual void getTargetBuiltins(const Builtin::Info *&Records,
817 unsigned &NumRecords) const {
818 // FIXME: Implement.
819 Records = 0;
820 NumRecords = 0;
821 }
822
823 virtual void getTargetDefines(const LangOptions &Opts,
824 MacroBuilder &Builder) const;
825
826 virtual const char *getVAListDeclaration() const {
827 return "typedef char* __builtin_va_list;";
828 }
829 virtual const char *getTargetPrefix() const {
830 return "mblaze";
831 }
832 virtual void getGCCRegNames(const char * const *&Names,
833 unsigned &NumNames) const;
834 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
835 unsigned &NumAliases) const;
836 virtual bool validateAsmConstraint(const char *&Name,
837 TargetInfo::ConstraintInfo &Info) const {
838 switch (*Name) {
839 default: return false;
840 case 'O': // Zero
841 return true;
842 case 'b': // Base register
843 case 'f': // Floating point register
844 Info.setAllowsRegister();
845 return true;
846 }
847 }
848 virtual const char *getClobbers() const {
849 return "";
850 }
851};
852
853/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
854/// #defines that are not tied to a specific subtarget.
855void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
856 MacroBuilder &Builder) const {
857 // Target identification.
858 Builder.defineMacro("__microblaze__");
859 Builder.defineMacro("_ARCH_MICROBLAZE");
860 Builder.defineMacro("__MICROBLAZE__");
861
862 // Target properties.
863 Builder.defineMacro("_BIG_ENDIAN");
864 Builder.defineMacro("__BIG_ENDIAN__");
865
866 // Subtarget options.
867 Builder.defineMacro("__REGISTER_PREFIX__", "");
868}
869
870
871const char * const MBlazeTargetInfo::GCCRegNames[] = {
872 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
873 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
874 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
875 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
876 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
877 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
878 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
879 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
880 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
881 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
882};
883
884void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
885 unsigned &NumNames) const {
886 Names = GCCRegNames;
887 NumNames = llvm::array_lengthof(GCCRegNames);
888}
889
890const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
891 { {"f0"}, "r0" },
892 { {"f1"}, "r1" },
893 { {"f2"}, "r2" },
894 { {"f3"}, "r3" },
895 { {"f4"}, "r4" },
896 { {"f5"}, "r5" },
897 { {"f6"}, "r6" },
898 { {"f7"}, "r7" },
899 { {"f8"}, "r8" },
900 { {"f9"}, "r9" },
901 { {"f10"}, "r10" },
902 { {"f11"}, "r11" },
903 { {"f12"}, "r12" },
904 { {"f13"}, "r13" },
905 { {"f14"}, "r14" },
906 { {"f15"}, "r15" },
907 { {"f16"}, "r16" },
908 { {"f17"}, "r17" },
909 { {"f18"}, "r18" },
910 { {"f19"}, "r19" },
911 { {"f20"}, "r20" },
912 { {"f21"}, "r21" },
913 { {"f22"}, "r22" },
914 { {"f23"}, "r23" },
915 { {"f24"}, "r24" },
916 { {"f25"}, "r25" },
917 { {"f26"}, "r26" },
918 { {"f27"}, "r27" },
919 { {"f28"}, "r28" },
920 { {"f29"}, "r29" },
921 { {"f30"}, "r30" },
922 { {"f31"}, "r31" },
923};
924
925void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
926 unsigned &NumAliases) const {
927 Aliases = GCCRegAliases;
928 NumAliases = llvm::array_lengthof(GCCRegAliases);
929}
930} // end anonymous namespace.
931
932namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000933// Namespace for x86 abstract base class
934const Builtin::Info BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +0000935#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
936#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
937 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000938#include "clang/Basic/BuiltinsX86.def"
Eli Friedman618234a2008-08-20 02:34:37 +0000939};
Eli Friedman61538a72008-05-20 14:21:01 +0000940
Nuno Lopes2550d702009-12-23 17:49:57 +0000941static const char* const GCCRegNames[] = {
Eli Friedman618234a2008-08-20 02:34:37 +0000942 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
943 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
944 "argp", "flags", "fspr", "dirflag", "frame",
945 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
946 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
947 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
948 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
949};
950
951const TargetInfo::GCCRegAlias GCCRegAliases[] = {
952 { { "al", "ah", "eax", "rax" }, "ax" },
953 { { "bl", "bh", "ebx", "rbx" }, "bx" },
954 { { "cl", "ch", "ecx", "rcx" }, "cx" },
955 { { "dl", "dh", "edx", "rdx" }, "dx" },
956 { { "esi", "rsi" }, "si" },
957 { { "edi", "rdi" }, "di" },
958 { { "esp", "rsp" }, "sp" },
959 { { "ebp", "rbp" }, "bp" },
960};
961
962// X86 target abstract base class; x86-32 and x86-64 are very close, so
963// most of the implementation can be shared.
964class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +0000965 enum X86SSEEnum {
966 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
967 } SSELevel;
Anders Carlsson9b0fb622010-01-27 03:47:49 +0000968 enum AMD3DNowEnum {
969 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
970 } AMD3DNowLevel;
971
Eric Christophereea12d12010-04-02 23:50:19 +0000972 bool HasAES;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000973 bool HasAVX;
974
Eli Friedman618234a2008-08-20 02:34:37 +0000975public:
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000976 X86TargetInfo(const std::string& triple)
Eric Christophereea12d12010-04-02 23:50:19 +0000977 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000978 HasAES(false), HasAVX(false) {
Eli Friedman618234a2008-08-20 02:34:37 +0000979 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000980 }
981 virtual void getTargetBuiltins(const Builtin::Info *&Records,
982 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000983 Records = BuiltinInfo;
984 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000985 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000986 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000987 unsigned &NumNames) const {
988 Names = GCCRegNames;
989 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000990 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000991 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson3346ae62007-11-24 23:38:12 +0000992 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000993 Aliases = GCCRegAliases;
994 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000995 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000996 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000997 TargetInfo::ConstraintInfo &info) const;
Dale Johannesenf6e2c202010-10-29 23:12:32 +0000998 virtual const llvm::Type* adjustInlineAsmType(std::string& Constraint,
999 const llvm::Type* Ty,
1000 llvm::LLVMContext& Context) const;
Eli Friedman618234a2008-08-20 02:34:37 +00001001 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +00001002 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +00001003 return "~{dirflag},~{fpsr},~{flags}";
1004 }
Chris Lattner33328642009-03-20 15:52:06 +00001005 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001006 MacroBuilder &Builder) const;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001007 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1008 const std::string &Name,
1009 bool Enabled) const;
Mike Stump1eb44332009-09-09 15:08:12 +00001010 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001011 llvm::StringMap<bool> &Features) const;
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001012 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Reid Spencer5f016e22007-07-11 17:01:13 +00001013};
Chris Lattner3daed522009-03-02 22:20:04 +00001014
Mike Stump1eb44332009-09-09 15:08:12 +00001015void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001016 llvm::StringMap<bool> &Features) const {
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001017 // FIXME: This should not be here.
1018 Features["3dnow"] = false;
1019 Features["3dnowa"] = false;
1020 Features["mmx"] = false;
1021 Features["sse"] = false;
1022 Features["sse2"] = false;
1023 Features["sse3"] = false;
1024 Features["ssse3"] = false;
1025 Features["sse41"] = false;
1026 Features["sse42"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001027 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001028 Features["avx"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001029
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001030 // LLVM does not currently recognize this.
1031 // Features["sse4a"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001032
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001033 // FIXME: This *really* should not be here.
1034
1035 // X86_64 always has SSE2.
1036 if (PointerWidth == 64)
1037 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
1038
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001039 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
1040 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
1041 ;
1042 else if (CPU == "pentium-mmx" || CPU == "pentium2")
1043 setFeatureEnabled(Features, "mmx", true);
1044 else if (CPU == "pentium3")
1045 setFeatureEnabled(Features, "sse", true);
1046 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
1047 setFeatureEnabled(Features, "sse2", true);
1048 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
1049 setFeatureEnabled(Features, "sse3", true);
1050 else if (CPU == "core2")
1051 setFeatureEnabled(Features, "ssse3", true);
1052 else if (CPU == "penryn") {
1053 setFeatureEnabled(Features, "sse4", true);
1054 Features["sse42"] = false;
1055 } else if (CPU == "atom")
1056 setFeatureEnabled(Features, "sse3", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001057 else if (CPU == "corei7") {
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001058 setFeatureEnabled(Features, "sse4", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001059 setFeatureEnabled(Features, "aes", true);
1060 }
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001061 else if (CPU == "k6" || CPU == "winchip-c6")
1062 setFeatureEnabled(Features, "mmx", true);
Mike Stump1eb44332009-09-09 15:08:12 +00001063 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001064 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
1065 setFeatureEnabled(Features, "mmx", true);
1066 setFeatureEnabled(Features, "3dnow", true);
1067 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
1068 setFeatureEnabled(Features, "sse", true);
1069 setFeatureEnabled(Features, "3dnowa", true);
1070 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
1071 CPU == "athlon-fx") {
Mike Stump1eb44332009-09-09 15:08:12 +00001072 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001073 setFeatureEnabled(Features, "3dnowa", true);
Roman Divackyc8b09a12010-12-29 13:28:29 +00001074 } else if (CPU == "k8-sse3") {
1075 setFeatureEnabled(Features, "sse3", true);
1076 setFeatureEnabled(Features, "3dnowa", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001077 } else if (CPU == "c3-2")
1078 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001079}
1080
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001081bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump1eb44332009-09-09 15:08:12 +00001082 const std::string &Name,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001083 bool Enabled) const {
Eric Christopherd39ebe22010-03-04 02:26:37 +00001084 // FIXME: This *really* should not be here. We need some way of translating
1085 // options into llvm subtarget features.
1086 if (!Features.count(Name) &&
1087 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001088 return false;
1089
1090 if (Enabled) {
1091 if (Name == "mmx")
1092 Features["mmx"] = true;
1093 else if (Name == "sse")
1094 Features["mmx"] = Features["sse"] = true;
1095 else if (Name == "sse2")
1096 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
1097 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001098 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001099 Features["sse3"] = true;
1100 else if (Name == "ssse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001101 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001102 Features["ssse3"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001103 else if (Name == "sse4" || Name == "sse4.2")
Mike Stump1eb44332009-09-09 15:08:12 +00001104 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001105 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001106 else if (Name == "sse4.1")
1107 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
1108 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001109 else if (Name == "3dnow")
1110 Features["3dnowa"] = true;
1111 else if (Name == "3dnowa")
1112 Features["3dnow"] = Features["3dnowa"] = true;
Eric Christophereea12d12010-04-02 23:50:19 +00001113 else if (Name == "aes")
1114 Features["aes"] = true;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001115 else if (Name == "avx")
1116 Features["avx"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001117 } else {
1118 if (Name == "mmx")
Mike Stump1eb44332009-09-09 15:08:12 +00001119 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001120 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1121 else if (Name == "sse")
Mike Stump1eb44332009-09-09 15:08:12 +00001122 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001123 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1124 else if (Name == "sse2")
Mike Stump1eb44332009-09-09 15:08:12 +00001125 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001126 Features["sse41"] = Features["sse42"] = false;
1127 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001128 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001129 Features["sse42"] = false;
1130 else if (Name == "ssse3")
1131 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1132 else if (Name == "sse4")
1133 Features["sse41"] = Features["sse42"] = false;
Eric Christopherd41b4ec2010-03-04 02:31:44 +00001134 else if (Name == "sse4.2")
1135 Features["sse42"] = false;
1136 else if (Name == "sse4.1")
1137 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001138 else if (Name == "3dnow")
1139 Features["3dnow"] = Features["3dnowa"] = false;
1140 else if (Name == "3dnowa")
1141 Features["3dnowa"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001142 else if (Name == "aes")
1143 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001144 else if (Name == "avx")
1145 Features["avx"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001146 }
1147
1148 return true;
1149}
1150
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001151/// HandleTargetOptions - Perform initialization based on the user
1152/// configured set of features.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001153void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001154 // Remember the maximum enabled sselevel.
1155 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
1156 // Ignore disabled features.
1157 if (Features[i][0] == '-')
1158 continue;
1159
Eric Christophereea12d12010-04-02 23:50:19 +00001160 if (Features[i].substr(1) == "aes") {
1161 HasAES = true;
1162 continue;
1163 }
1164
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001165 // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
1166 // For now let it be enabled together with other SSE levels.
1167 if (Features[i].substr(1) == "avx") {
1168 HasAVX = true;
1169 continue;
1170 }
1171
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001172 assert(Features[i][0] == '+' && "Invalid target feature!");
1173 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
1174 .Case("sse42", SSE42)
1175 .Case("sse41", SSE41)
1176 .Case("ssse3", SSSE3)
Nuno Lopes33d3bca2010-03-12 10:20:09 +00001177 .Case("sse3", SSE3)
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001178 .Case("sse2", SSE2)
1179 .Case("sse", SSE1)
1180 .Case("mmx", MMX)
1181 .Default(NoMMXSSE);
1182 SSELevel = std::max(SSELevel, Level);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001183
1184 AMD3DNowEnum ThreeDNowLevel =
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001185 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
1186 .Case("3dnowa", AMD3DNowAthlon)
1187 .Case("3dnow", AMD3DNow)
1188 .Default(NoAMD3DNow);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001189
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001190 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001191 }
Chris Lattner3daed522009-03-02 22:20:04 +00001192}
Chris Lattnerc0f59212009-03-02 22:27:17 +00001193
1194/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
1195/// that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +00001196void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001197 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001198 // Target identification.
1199 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001200 Builder.defineMacro("_LP64");
1201 Builder.defineMacro("__LP64__");
1202 Builder.defineMacro("__amd64__");
1203 Builder.defineMacro("__amd64");
1204 Builder.defineMacro("__x86_64");
1205 Builder.defineMacro("__x86_64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +00001206 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +00001207 DefineStd(Builder, "i386", Opts);
Chris Lattnerc0f59212009-03-02 22:27:17 +00001208 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001209
Eric Christophereea12d12010-04-02 23:50:19 +00001210 if (HasAES)
1211 Builder.defineMacro("__AES__");
1212
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001213 if (HasAVX)
1214 Builder.defineMacro("__AVX__");
1215
Chris Lattnerc0f59212009-03-02 22:27:17 +00001216 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001217 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001218
Chris Lattnerc0f59212009-03-02 22:27:17 +00001219 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +00001220 Builder.defineMacro("__nocona");
1221 Builder.defineMacro("__nocona__");
1222 Builder.defineMacro("__tune_nocona__");
1223 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001224
Chris Lattner54175442009-04-19 17:32:33 +00001225 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
1226 // functions in glibc header files that use FP Stack inline asm which the
1227 // backend can't deal with (PR879).
Benjamin Kramera9992772010-01-09 17:55:51 +00001228 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001229
Chris Lattner84f0ea82009-03-02 22:40:39 +00001230 // Each case falls through to the previous one here.
1231 switch (SSELevel) {
1232 case SSE42:
Benjamin Kramera9992772010-01-09 17:55:51 +00001233 Builder.defineMacro("__SSE4_2__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001234 case SSE41:
Benjamin Kramera9992772010-01-09 17:55:51 +00001235 Builder.defineMacro("__SSE4_1__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001236 case SSSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001237 Builder.defineMacro("__SSSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001238 case SSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001239 Builder.defineMacro("__SSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001240 case SSE2:
Benjamin Kramera9992772010-01-09 17:55:51 +00001241 Builder.defineMacro("__SSE2__");
1242 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001243 case SSE1:
Benjamin Kramera9992772010-01-09 17:55:51 +00001244 Builder.defineMacro("__SSE__");
1245 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001246 case MMX:
Benjamin Kramera9992772010-01-09 17:55:51 +00001247 Builder.defineMacro("__MMX__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001248 case NoMMXSSE:
1249 break;
1250 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001251
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001252 if (Opts.Microsoft && PointerWidth == 32) {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001253 switch (SSELevel) {
Michael J. Spencera764e832010-10-21 08:22:51 +00001254 case SSE42:
1255 case SSE41:
1256 case SSSE3:
1257 case SSE3:
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001258 case SSE2:
1259 Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
1260 break;
1261 case SSE1:
1262 Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
1263 break;
1264 default:
1265 Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
1266 }
1267 }
1268
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001269 // Each case falls through to the previous one here.
1270 switch (AMD3DNowLevel) {
1271 case AMD3DNowAthlon:
1272 Builder.defineMacro("__3dNOW_A__");
1273 case AMD3DNow:
1274 Builder.defineMacro("__3dNOW__");
1275 case NoAMD3DNow:
1276 break;
1277 }
Chris Lattnerc0f59212009-03-02 22:27:17 +00001278}
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001279
1280
Eli Friedman618234a2008-08-20 02:34:37 +00001281bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001282X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001283 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001284 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +00001285 default: return false;
Dale Johannesen545be512010-08-24 22:33:12 +00001286 case 'Y': // first letter of a pair:
1287 switch (*(Name+1)) {
1288 default: return false;
1289 case '0': // First SSE register.
1290 case 't': // Any SSE register, when SSE2 is enabled.
1291 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1292 case 'm': // any MMX register, when inter-unit moves enabled.
1293 break; // falls through to setAllowsRegister.
1294 }
Eli Friedman618234a2008-08-20 02:34:37 +00001295 case 'a': // eax.
1296 case 'b': // ebx.
1297 case 'c': // ecx.
1298 case 'd': // edx.
1299 case 'S': // esi.
1300 case 'D': // edi.
1301 case 'A': // edx:eax.
Dale Johannesen545be512010-08-24 22:33:12 +00001302 case 'f': // any x87 floating point stack register.
Eli Friedman618234a2008-08-20 02:34:37 +00001303 case 't': // top of floating point stack.
1304 case 'u': // second from top of floating point stack.
1305 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +00001306 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +00001307 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +00001308 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Dale Johannesen545be512010-08-24 22:33:12 +00001309 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1310 case 'l': // "Index" registers: any general register that can be used as an
1311 // index in a base+index memory access.
1312 Info.setAllowsRegister();
1313 return true;
1314 case 'C': // SSE floating point constant.
1315 case 'G': // x87 floating point constant.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001316 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001317 // x86_64 instructions.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001318 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001319 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +00001320 return true;
1321 }
Dale Johannesen545be512010-08-24 22:33:12 +00001322 return false;
Eli Friedman618234a2008-08-20 02:34:37 +00001323}
1324
Dale Johannesenf6e2c202010-10-29 23:12:32 +00001325const llvm::Type*
1326X86TargetInfo::adjustInlineAsmType(std::string& Constraint,
1327 const llvm::Type* Ty,
1328 llvm::LLVMContext &Context) const {
1329 if (Constraint=="y" && Ty->isVectorTy())
1330 return llvm::Type::getX86_MMXTy(Context);
1331 return Ty;
1332}
1333
1334
Eli Friedman618234a2008-08-20 02:34:37 +00001335std::string
1336X86TargetInfo::convertConstraint(const char Constraint) const {
1337 switch (Constraint) {
1338 case 'a': return std::string("{ax}");
1339 case 'b': return std::string("{bx}");
1340 case 'c': return std::string("{cx}");
1341 case 'd': return std::string("{dx}");
1342 case 'S': return std::string("{si}");
1343 case 'D': return std::string("{di}");
Dale Johannesencee55012010-10-22 21:07:10 +00001344 case 'p': // address
1345 return std::string("im");
Eli Friedman618234a2008-08-20 02:34:37 +00001346 case 't': // top of floating point stack.
1347 return std::string("{st}");
1348 case 'u': // second from top of floating point stack.
1349 return std::string("{st(1)}"); // second from top of floating point stack.
1350 default:
1351 return std::string(1, Constraint);
1352 }
1353}
Eli Friedman618234a2008-08-20 02:34:37 +00001354} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +00001355
1356namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001357// X86-32 generic target
1358class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +00001359public:
Eli Friedman618234a2008-08-20 02:34:37 +00001360 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
1361 DoubleAlign = LongLongAlign = 32;
1362 LongDoubleWidth = 96;
1363 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001364 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1365 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001366 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman1afabd92009-03-29 20:31:09 +00001367 SizeType = UnsignedInt;
1368 PtrDiffType = SignedInt;
1369 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001370 RegParmMax = 3;
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001371
1372 // Use fpret for all types.
1373 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
1374 (1 << TargetInfo::Double) |
1375 (1 << TargetInfo::LongDouble));
Eli Friedman618234a2008-08-20 02:34:37 +00001376 }
1377 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001378 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +00001379 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001380
Chris Lattner21fb98e2009-09-23 06:06:36 +00001381 int getEHDataRegisterNumber(unsigned RegNo) const {
1382 if (RegNo == 0) return 0;
1383 if (RegNo == 1) return 2;
1384 return -1;
1385 }
Eli Friedman618234a2008-08-20 02:34:37 +00001386};
1387} // end anonymous namespace
1388
1389namespace {
Eli Friedman624c1462009-07-05 18:47:56 +00001390class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
1391public:
1392 OpenBSDI386TargetInfo(const std::string& triple) :
1393 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
1394 SizeType = UnsignedLong;
1395 IntPtrType = SignedLong;
Eli Friedman6036ebe2009-07-05 22:31:18 +00001396 PtrDiffType = SignedLong;
Eli Friedman624c1462009-07-05 18:47:56 +00001397 }
1398};
1399} // end anonymous namespace
1400
1401namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +00001402class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman618234a2008-08-20 02:34:37 +00001403public:
Torok Edwin5f6c1942009-06-30 17:10:35 +00001404 DarwinI386TargetInfo(const std::string& triple) :
1405 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman618234a2008-08-20 02:34:37 +00001406 LongDoubleWidth = 128;
1407 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +00001408 SizeType = UnsignedLong;
1409 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001410 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1411 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001412 "a0:0:64-f80:128:128-n8:16:32";
Daniel Dunbar613fd672010-05-27 00:35:16 +00001413 HasAlignMac68kSupport = true;
Torok Edwinb0a5b242009-06-30 17:00:25 +00001414 }
1415
Eli Friedman618234a2008-08-20 02:34:37 +00001416};
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001417} // end anonymous namespace
1418
1419namespace {
Eli Friedman29a30502008-08-21 01:40:19 +00001420// x86-32 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001421class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
Eli Friedman29a30502008-08-21 01:40:19 +00001422public:
1423 WindowsX86_32TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001424 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +00001425 TLSSupported = false;
Chris Lattner85de9e72009-06-24 17:12:15 +00001426 WCharType = UnsignedShort;
Eli Friedman9c2f84e2009-06-08 21:16:17 +00001427 DoubleAlign = LongLongAlign = 64;
1428 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 +00001429 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1430 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedman29a30502008-08-21 01:40:19 +00001431 }
Michael J. Spencera764e832010-10-21 08:22:51 +00001432 virtual void getTargetDefines(const LangOptions &Opts,
1433 MacroBuilder &Builder) const {
1434 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
1435 }
1436};
1437} // end anonymous namespace
1438
1439namespace {
1440
1441// x86-32 Windows Visual Studio target
1442class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1443public:
1444 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1445 : WindowsX86_32TargetInfo(triple) {
1446 LongDoubleWidth = 64;
1447 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1448 }
1449 virtual void getTargetDefines(const LangOptions &Opts,
1450 MacroBuilder &Builder) const {
1451 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1452 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
1453 // The value of the following reflects processor type.
1454 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1455 // We lost the original triple, so we use the default.
1456 Builder.defineMacro("_M_IX86", "600");
1457 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001458};
1459} // end anonymous namespace
1460
1461namespace {
1462// x86-32 MinGW target
1463class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1464public:
1465 MinGWX86_32TargetInfo(const std::string& triple)
1466 : WindowsX86_32TargetInfo(triple) {
1467 }
1468 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001469 MacroBuilder &Builder) const {
1470 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001471 DefineStd(Builder, "WIN32", Opts);
1472 DefineStd(Builder, "WINNT", Opts);
1473 Builder.defineMacro("_X86_");
Benjamin Kramera9992772010-01-09 17:55:51 +00001474 Builder.defineMacro("__MSVCRT__");
1475 Builder.defineMacro("__MINGW32__");
1476 Builder.defineMacro("__declspec", "__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001477 }
1478};
1479} // end anonymous namespace
1480
1481namespace {
1482// x86-32 Cygwin target
1483class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1484public:
1485 CygwinX86_32TargetInfo(const std::string& triple)
1486 : X86_32TargetInfo(triple) {
1487 TLSSupported = false;
1488 WCharType = UnsignedShort;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001489 DoubleAlign = LongLongAlign = 64;
1490 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1491 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001492 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001493 }
1494 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001495 MacroBuilder &Builder) const {
1496 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1497 Builder.defineMacro("__CYGWIN__");
1498 Builder.defineMacro("__CYGWIN32__");
1499 DefineStd(Builder, "unix", Opts);
Douglas Gregor2b003fd2010-04-21 05:52:38 +00001500 if (Opts.CPlusPlus)
1501 Builder.defineMacro("_GNU_SOURCE");
Eli Friedmanabc4e322009-06-08 06:11:14 +00001502 }
Eli Friedman29a30502008-08-21 01:40:19 +00001503};
1504} // end anonymous namespace
1505
1506namespace {
Chris Lattner86ed3a32010-04-11 19:29:39 +00001507// x86-32 Haiku target
1508class HaikuX86_32TargetInfo : public X86_32TargetInfo {
1509public:
1510 HaikuX86_32TargetInfo(const std::string& triple)
1511 : X86_32TargetInfo(triple) {
1512 SizeType = UnsignedLong;
Chris Lattnerfe1ea7b2010-04-22 17:48:00 +00001513 IntPtrType = SignedLong;
1514 PtrDiffType = SignedLong;
Rafael Espindola19ddda82010-11-09 16:41:02 +00001515 this->UserLabelPrefix = "";
Eli Friedmana7e68452010-08-22 01:00:03 +00001516 }
Chris Lattner86ed3a32010-04-11 19:29:39 +00001517 virtual void getTargetDefines(const LangOptions &Opts,
1518 MacroBuilder &Builder) const {
1519 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1520 Builder.defineMacro("__INTEL__");
1521 Builder.defineMacro("__HAIKU__");
1522 }
1523};
1524} // end anonymous namespace
1525
1526namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001527// x86-64 generic target
1528class X86_64TargetInfo : public X86TargetInfo {
1529public:
Chris Lattner33328642009-03-20 15:52:06 +00001530 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +00001531 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +00001532 LongDoubleWidth = 128;
1533 LongDoubleAlign = 128;
Rafael Espindola6deecb02010-06-04 23:15:27 +00001534 LargeArrayMinWidth = 128;
1535 LargeArrayAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +00001536 IntMaxType = SignedLong;
1537 UIntMaxType = UnsignedLong;
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001538 Int64Type = SignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001539 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +00001540
Eli Friedmaned855cb2008-08-21 00:13:15 +00001541 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1542 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001543 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001544
1545 // Use fpret only for long double.
1546 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
Reid Spencer5f016e22007-07-11 17:01:13 +00001547 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +00001548 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001549 return "typedef struct __va_list_tag {"
1550 " unsigned gp_offset;"
1551 " unsigned fp_offset;"
1552 " void* overflow_arg_area;"
1553 " void* reg_save_area;"
John McCall2b7baf02010-05-28 18:25:28 +00001554 "} __va_list_tag;"
Eli Friedmandc043162009-07-03 00:45:06 +00001555 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +00001556 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001557
Chris Lattner21fb98e2009-09-23 06:06:36 +00001558 int getEHDataRegisterNumber(unsigned RegNo) const {
1559 if (RegNo == 0) return 0;
1560 if (RegNo == 1) return 1;
1561 return -1;
1562 }
Eli Friedman618234a2008-08-20 02:34:37 +00001563};
1564} // end anonymous namespace
1565
1566namespace {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001567// x86-64 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001568class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001569public:
1570 WindowsX86_64TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001571 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001572 TLSSupported = false;
1573 WCharType = UnsignedShort;
Mike Stumpa55cce82009-10-08 23:00:00 +00001574 LongWidth = LongAlign = 32;
Michael J. Spencer237cf582010-10-18 07:10:59 +00001575 DoubleAlign = LongLongAlign = 64;
Nate Begemandbf8ea42010-07-21 02:02:56 +00001576 IntMaxType = SignedLongLong;
1577 UIntMaxType = UnsignedLongLong;
1578 Int64Type = SignedLongLong;
Cameron Esfahani1484e0d2010-09-15 00:28:12 +00001579 SizeType = UnsignedLongLong;
1580 PtrDiffType = SignedLongLong;
1581 IntPtrType = SignedLongLong;
NAKAMURA Takumi8c959d92011-01-17 22:56:08 +00001582 this->UserLabelPrefix = "";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001583 }
1584 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001585 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001586 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001587 Builder.defineMacro("_WIN64");
Michael J. Spencera764e832010-10-21 08:22:51 +00001588 }
NAKAMURA Takumi79521992011-01-17 22:56:23 +00001589 virtual const char *getVAListDeclaration() const {
1590 return "typedef char* __builtin_va_list;";
1591 }
Michael J. Spencera764e832010-10-21 08:22:51 +00001592};
1593} // end anonymous namespace
1594
1595namespace {
1596// x86-64 Windows Visual Studio target
1597class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1598public:
1599 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1600 : WindowsX86_64TargetInfo(triple) {
1601 }
1602 virtual void getTargetDefines(const LangOptions &Opts,
1603 MacroBuilder &Builder) const {
1604 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1605 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
Benjamin Kramera9992772010-01-09 17:55:51 +00001606 Builder.defineMacro("_M_X64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001607 Builder.defineMacro("_M_AMD64");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001608 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001609};
1610} // end anonymous namespace
1611
1612namespace {
1613// x86-64 MinGW target
1614class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1615public:
1616 MinGWX86_64TargetInfo(const std::string& triple)
1617 : WindowsX86_64TargetInfo(triple) {
1618 }
1619 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001620 MacroBuilder &Builder) const {
1621 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001622 DefineStd(Builder, "WIN64", Opts);
Benjamin Kramera9992772010-01-09 17:55:51 +00001623 Builder.defineMacro("__MSVCRT__");
1624 Builder.defineMacro("__MINGW64__");
NAKAMURA Takumi1b24cd32011-01-17 22:56:16 +00001625 Builder.defineMacro("__declspec", "__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001626 }
1627};
1628} // end anonymous namespace
1629
1630namespace {
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001631class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1632public:
Mike Stump1eb44332009-09-09 15:08:12 +00001633 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001634 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1635 Int64Type = SignedLongLong;
1636 }
1637};
1638} // end anonymous namespace
1639
1640namespace {
Eli Friedman6036ebe2009-07-05 22:31:18 +00001641class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1642public:
Mike Stump1eb44332009-09-09 15:08:12 +00001643 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman6036ebe2009-07-05 22:31:18 +00001644 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1645 IntMaxType = SignedLongLong;
1646 UIntMaxType = UnsignedLongLong;
1647 Int64Type = SignedLongLong;
1648 }
1649};
1650} // end anonymous namespace
1651
1652namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +00001653class ARMTargetInfo : public TargetInfo {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001654 // Possible FPU choices.
1655 enum FPUMode {
1656 NoFPU,
1657 VFP2FPU,
1658 VFP3FPU,
1659 NeonFPU
1660 };
1661
1662 static bool FPUModeIsVFP(FPUMode Mode) {
1663 return Mode >= VFP2FPU && Mode <= NeonFPU;
1664 }
1665
1666 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1667 static const char * const GCCRegNames[];
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001668
Daniel Dunbareac7c532009-12-18 18:42:37 +00001669 std::string ABI, CPU;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001670
1671 unsigned FPU : 3;
1672
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001673 unsigned IsThumb : 1;
1674
1675 // Initialized via features.
1676 unsigned SoftFloat : 1;
1677 unsigned SoftFloatABI : 1;
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001678
Chris Lattner2752c012010-03-03 19:03:45 +00001679 static const Builtin::Info BuiltinInfo[];
1680
Chris Lattner393ff042008-04-21 18:56:49 +00001681public:
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001682 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbareac7c532009-12-18 18:42:37 +00001683 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001684 {
Daniel Dunbara2a41612009-09-14 00:02:24 +00001685 SizeType = UnsignedInt;
1686 PtrDiffType = SignedInt;
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001687
Chris Lattner9bffb072010-04-23 16:29:58 +00001688 // {} in inline assembly are neon specifiers, not assembly variant
1689 // specifiers.
1690 NoAsmVariants = true;
Michael J. Spencer20249a12010-10-21 03:16:25 +00001691
Daniel Dunbareac7c532009-12-18 18:42:37 +00001692 // FIXME: Should we just treat this as a feature?
Daniel Dunbar0791aa52009-12-18 19:57:13 +00001693 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001694 if (IsThumb) {
1695 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1696 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001697 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001698 } else {
1699 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1700 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001701 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001702 }
John McCallee79a4c2010-08-21 22:46:04 +00001703
1704 // ARM targets default to using the ARM C++ ABI.
1705 CXXABI = CXXABI_ARM;
Eli Friedman61538a72008-05-20 14:21:01 +00001706 }
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001707 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbara2a41612009-09-14 00:02:24 +00001708 virtual bool setABI(const std::string &Name) {
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001709 ABI = Name;
1710
Daniel Dunbara2a41612009-09-14 00:02:24 +00001711 // The defaults (above) are for AAPCS, check if we need to change them.
1712 //
1713 // FIXME: We need support for -meabi... we could just mangle it into the
1714 // name.
1715 if (Name == "apcs-gnu") {
Daniel Dunbard410fa22010-01-27 20:23:08 +00001716 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbara2a41612009-09-14 00:02:24 +00001717 SizeType = UnsignedLong;
1718
Daniel Dunbar684de632010-04-22 16:14:54 +00001719 // Do not respect the alignment of bit-field types when laying out
1720 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
1721 UseBitFieldTypeAlignment = false;
1722
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001723 if (IsThumb) {
1724 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1725 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001726 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001727 } else {
1728 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1729 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001730 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001731 }
1732
Daniel Dunbara2a41612009-09-14 00:02:24 +00001733 // FIXME: Override "preferred align" for double and long long.
1734 } else if (Name == "aapcs") {
1735 // FIXME: Enumerated types are variable width in straight AAPCS.
1736 } else if (Name == "aapcs-linux") {
1737 ;
1738 } else
1739 return false;
1740
1741 return true;
1742 }
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001743
Daniel Dunbara91320b2009-12-21 23:28:17 +00001744 void getDefaultFeatures(const std::string &CPU,
1745 llvm::StringMap<bool> &Features) const {
1746 // FIXME: This should not be here.
1747 Features["vfp2"] = false;
1748 Features["vfp3"] = false;
1749 Features["neon"] = false;
1750
1751 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1752 Features["vfp2"] = true;
1753 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1754 Features["neon"] = true;
1755 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001756
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001757 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1758 const std::string &Name,
1759 bool Enabled) const {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001760 if (Name == "soft-float" || Name == "soft-float-abi") {
1761 Features[Name] = Enabled;
1762 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1763 // These effectively are a single option, reset them when any is enabled.
1764 if (Enabled)
1765 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1766 Features[Name] = Enabled;
1767 } else
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001768 return false;
1769
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001770 return true;
1771 }
1772
1773 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001774 FPU = NoFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001775 SoftFloat = SoftFloatABI = false;
1776 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1777 if (Features[i] == "+soft-float")
1778 SoftFloat = true;
1779 else if (Features[i] == "+soft-float-abi")
1780 SoftFloatABI = true;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001781 else if (Features[i] == "+vfp2")
1782 FPU = VFP2FPU;
1783 else if (Features[i] == "+vfp3")
1784 FPU = VFP3FPU;
1785 else if (Features[i] == "+neon")
1786 FPU = NeonFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001787 }
1788
1789 // Remove front-end specific options which the backend handles differently.
1790 std::vector<std::string>::iterator it;
1791 it = std::find(Features.begin(), Features.end(), "+soft-float");
1792 if (it != Features.end())
1793 Features.erase(it);
1794 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1795 if (it != Features.end())
1796 Features.erase(it);
1797 }
1798
Daniel Dunbareac7c532009-12-18 18:42:37 +00001799 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1800 return llvm::StringSwitch<const char*>(Name)
1801 .Cases("arm8", "arm810", "4")
1802 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1803 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1804 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1805 .Case("ep9312", "4T")
1806 .Cases("arm10tdmi", "arm1020t", "5T")
1807 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1808 .Case("arm926ej-s", "5TEJ")
1809 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1810 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001811 .Case("arm1136j-s", "6J")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001812 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001813 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001814 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1815 .Cases("cortex-a8", "cortex-a9", "7A")
Bob Wilson06f45632011-01-06 16:57:20 +00001816 .Case("cortex-m3", "7M")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001817 .Default(0);
1818 }
1819 virtual bool setCPU(const std::string &Name) {
1820 if (!getCPUDefineSuffix(Name))
1821 return false;
1822
1823 CPU = Name;
1824 return true;
1825 }
Chris Lattner33328642009-03-20 15:52:06 +00001826 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001827 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001828 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +00001829 Builder.defineMacro("__arm");
1830 Builder.defineMacro("__arm__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001831
Chris Lattnerc0f59212009-03-02 22:27:17 +00001832 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001833 Builder.defineMacro("__ARMEL__");
1834 Builder.defineMacro("__LITTLE_ENDIAN__");
1835 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001836
1837 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramera9992772010-01-09 17:55:51 +00001838 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001839
Mike Stump437bb4b2009-04-08 02:07:04 +00001840 // Subtarget options.
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001841
Daniel Dunbareac7c532009-12-18 18:42:37 +00001842 // FIXME: It's more complicated than this and we don't really support
1843 // interworking.
1844 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramera9992772010-01-09 17:55:51 +00001845 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001846
Daniel Dunbareac7c532009-12-18 18:42:37 +00001847 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramera9992772010-01-09 17:55:51 +00001848 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001849
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001850 if (SoftFloat)
Benjamin Kramera9992772010-01-09 17:55:51 +00001851 Builder.defineMacro("__SOFTFP__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001852
1853 if (CPU == "xscale")
Benjamin Kramera9992772010-01-09 17:55:51 +00001854 Builder.defineMacro("__XSCALE__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001855
Daniel Dunbara91320b2009-12-21 23:28:17 +00001856 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001857 if (IsThumb) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001858 Builder.defineMacro("__THUMBEL__");
1859 Builder.defineMacro("__thumb__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001860 if (IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001861 Builder.defineMacro("__thumb2__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001862 }
1863
1864 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramera9992772010-01-09 17:55:51 +00001865 Builder.defineMacro("__APCS_32__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001866
1867 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramera9992772010-01-09 17:55:51 +00001868 Builder.defineMacro("__VFP_FP__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001869
1870 // This only gets set when Neon instructions are actually available, unlike
1871 // the VFP define, hence the soft float and arch check. This is subtly
1872 // different from gcc, we follow the intent which was that it should be set
1873 // when Neon instructions are actually available.
1874 if (FPU == NeonFPU && !SoftFloat && IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001875 Builder.defineMacro("__ARM_NEON__");
Chris Lattner393ff042008-04-21 18:56:49 +00001876 }
1877 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1878 unsigned &NumRecords) const {
Chris Lattner2752c012010-03-03 19:03:45 +00001879 Records = BuiltinInfo;
1880 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner393ff042008-04-21 18:56:49 +00001881 }
1882 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001883 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +00001884 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001885 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001886 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001887 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001888 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001889 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001890 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001891 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001892 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +00001893 default:
Nate Begemanad487f42008-04-22 05:03:19 +00001894 case 'l': // r0-r7
1895 case 'h': // r8-r15
1896 case 'w': // VFP Floating point register single precision
1897 case 'P': // VFP Floating point register double precision
Chris Lattner44def072009-04-26 07:16:29 +00001898 Info.setAllowsRegister();
Nate Begemanad487f42008-04-22 05:03:19 +00001899 return true;
1900 }
Chris Lattner393ff042008-04-21 18:56:49 +00001901 return false;
1902 }
1903 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001904 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +00001905 return "";
1906 }
1907};
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001908
1909const char * const ARMTargetInfo::GCCRegNames[] = {
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001910 // Integer registers
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001911 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001912 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
1913
1914 // Float registers
1915 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1916 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
1917 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001918 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001919
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001920 // Double registers
1921 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
1922 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
Dale Johannesend1455352010-10-28 01:05:37 +00001923 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
1924 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001925
1926 // Quad registers
Dale Johannesend1455352010-10-28 01:05:37 +00001927 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
1928 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001929};
1930
1931void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001932 unsigned &NumNames) const {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001933 Names = GCCRegNames;
1934 NumNames = llvm::array_lengthof(GCCRegNames);
1935}
1936
1937const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001938 { { "a1" }, "r0" },
1939 { { "a2" }, "r1" },
1940 { { "a3" }, "r2" },
1941 { { "a4" }, "r3" },
1942 { { "v1" }, "r4" },
1943 { { "v2" }, "r5" },
1944 { { "v3" }, "r6" },
1945 { { "v4" }, "r7" },
1946 { { "v5" }, "r8" },
1947 { { "v6", "rfp" }, "r9" },
1948 { { "sl" }, "r10" },
1949 { { "fp" }, "r11" },
1950 { { "ip" }, "r12" },
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001951 { { "r13" }, "sp" },
1952 { { "r14" }, "lr" },
1953 { { "r15" }, "pc" },
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001954 // The S, D and Q registers overlap, but aren't really aliases; we
1955 // don't want to substitute one of these for a different-sized one.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001956};
1957
1958void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1959 unsigned &NumAliases) const {
1960 Aliases = GCCRegAliases;
1961 NumAliases = llvm::array_lengthof(GCCRegAliases);
1962}
Chris Lattner2752c012010-03-03 19:03:45 +00001963
1964const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +00001965#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
1966#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1967 ALL_LANGUAGES, false },
Chris Lattner2752c012010-03-03 19:03:45 +00001968#include "clang/Basic/BuiltinsARM.def"
1969};
Chris Lattner393ff042008-04-21 18:56:49 +00001970} // end anonymous namespace.
1971
Eli Friedmana9f54962008-08-20 07:44:10 +00001972
1973namespace {
Mike Stump1eb44332009-09-09 15:08:12 +00001974class DarwinARMTargetInfo :
Torok Edwin5f6c1942009-06-30 17:10:35 +00001975 public DarwinTargetInfo<ARMTargetInfo> {
1976protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +00001977 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +00001978 MacroBuilder &Builder) const {
Daniel Dunbar21ae3192010-01-26 01:44:04 +00001979 getDarwinDefines(Builder, Opts, Triple);
Eli Friedmanb030f022009-04-19 21:38:35 +00001980 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001981
Torok Edwin5f6c1942009-06-30 17:10:35 +00001982public:
Mike Stump1eb44332009-09-09 15:08:12 +00001983 DarwinARMTargetInfo(const std::string& triple)
Daniel Dunbar350b9f32010-05-27 07:00:26 +00001984 : DarwinTargetInfo<ARMTargetInfo>(triple) {
1985 HasAlignMac68kSupport = true;
1986 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001987};
1988} // end anonymous namespace.
1989
Reid Spencer5f016e22007-07-11 17:01:13 +00001990namespace {
Eli Friedman01b86682008-08-20 07:28:14 +00001991class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +00001992 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1993 static const char * const GCCRegNames[];
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00001994 bool SoftFloat;
Gabor Greif26658672008-02-21 16:29:08 +00001995public:
Eli Friedman01b86682008-08-20 07:28:14 +00001996 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1997 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +00001998 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 +00001999 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedman01b86682008-08-20 07:28:14 +00002000 }
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002001 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
2002 const std::string &Name,
2003 bool Enabled) const {
2004 if (Name == "soft-float")
2005 Features[Name] = Enabled;
2006 else
2007 return false;
2008
2009 return true;
2010 }
2011 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
2012 SoftFloat = false;
2013 for (unsigned i = 0, e = Features.size(); i != e; ++i)
2014 if (Features[i] == "+soft-float")
2015 SoftFloat = true;
2016 }
Chris Lattner33328642009-03-20 15:52:06 +00002017 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002018 MacroBuilder &Builder) const {
2019 DefineStd(Builder, "sparc", Opts);
2020 Builder.defineMacro("__sparcv8");
2021 Builder.defineMacro("__REGISTER_PREFIX__", "");
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002022
2023 if (SoftFloat)
2024 Builder.defineMacro("SOFT_FLOAT", "1");
Gabor Greif26658672008-02-21 16:29:08 +00002025 }
2026 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2027 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002028 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +00002029 }
2030 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002031 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +00002032 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002033 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002034 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002035 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002036 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00002037 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +00002038 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002039 // FIXME: Implement!
2040 return false;
Gabor Greif26658672008-02-21 16:29:08 +00002041 }
2042 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002043 // FIXME: Implement!
2044 return "";
Gabor Greif26658672008-02-21 16:29:08 +00002045 }
2046};
2047
Chris Lattnere957f532009-01-27 01:58:38 +00002048const char * const SparcV8TargetInfo::GCCRegNames[] = {
2049 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2050 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2051 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2052 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
2053};
2054
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002055void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002056 unsigned &NumNames) const {
2057 Names = GCCRegNames;
2058 NumNames = llvm::array_lengthof(GCCRegNames);
2059}
2060
2061const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002062 { { "g0" }, "r0" },
2063 { { "g1" }, "r1" },
2064 { { "g2" }, "r2" },
2065 { { "g3" }, "r3" },
2066 { { "g4" }, "r4" },
2067 { { "g5" }, "r5" },
2068 { { "g6" }, "r6" },
2069 { { "g7" }, "r7" },
2070 { { "o0" }, "r8" },
2071 { { "o1" }, "r9" },
2072 { { "o2" }, "r10" },
2073 { { "o3" }, "r11" },
2074 { { "o4" }, "r12" },
2075 { { "o5" }, "r13" },
2076 { { "o6", "sp" }, "r14" },
2077 { { "o7" }, "r15" },
2078 { { "l0" }, "r16" },
2079 { { "l1" }, "r17" },
2080 { { "l2" }, "r18" },
2081 { { "l3" }, "r19" },
2082 { { "l4" }, "r20" },
2083 { { "l5" }, "r21" },
2084 { { "l6" }, "r22" },
2085 { { "l7" }, "r23" },
2086 { { "i0" }, "r24" },
2087 { { "i1" }, "r25" },
2088 { { "i2" }, "r26" },
2089 { { "i3" }, "r27" },
2090 { { "i4" }, "r28" },
2091 { { "i5" }, "r29" },
2092 { { "i6", "fp" }, "r30" },
2093 { { "i7" }, "r31" },
Chris Lattnere957f532009-01-27 01:58:38 +00002094};
2095
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002096void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002097 unsigned &NumAliases) const {
2098 Aliases = GCCRegAliases;
2099 NumAliases = llvm::array_lengthof(GCCRegAliases);
2100}
Gabor Greif26658672008-02-21 16:29:08 +00002101} // end anonymous namespace.
2102
Eli Friedman01b86682008-08-20 07:28:14 +00002103namespace {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002104class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
2105public:
2106 AuroraUXSparcV8TargetInfo(const std::string& triple) :
2107 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
2108 SizeType = UnsignedInt;
2109 PtrDiffType = SignedInt;
2110 }
2111};
Torok Edwin5f6c1942009-06-30 17:10:35 +00002112class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedman01b86682008-08-20 07:28:14 +00002113public:
2114 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwin5f6c1942009-06-30 17:10:35 +00002115 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmanf509d732008-11-02 02:43:55 +00002116 SizeType = UnsignedInt;
2117 PtrDiffType = SignedInt;
Eli Friedman01b86682008-08-20 07:28:14 +00002118 }
2119};
2120} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00002121
Chris Lattner2621fd12008-05-08 05:58:21 +00002122namespace {
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002123 class MSP430TargetInfo : public TargetInfo {
2124 static const char * const GCCRegNames[];
2125 public:
2126 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
2127 TLSSupported = false;
Anton Korobeynikov09f52a62010-01-30 12:55:11 +00002128 IntWidth = 16; IntAlign = 16;
2129 LongWidth = 32; LongLongWidth = 64;
2130 LongAlign = LongLongAlign = 16;
2131 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002132 SizeType = UnsignedInt;
2133 IntMaxType = SignedLong;
2134 UIntMaxType = UnsignedLong;
2135 IntPtrType = SignedShort;
2136 PtrDiffType = SignedInt;
Edward O'Callaghan9cf910e2009-11-21 00:49:54 +00002137 SigAtomicType = SignedLong;
Anton Korobeynikov5d7c2512009-12-19 01:32:37 +00002138 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002139 }
2140 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002141 MacroBuilder &Builder) const {
2142 Builder.defineMacro("MSP430");
2143 Builder.defineMacro("__MSP430__");
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002144 // FIXME: defines for different 'flavours' of MCU
2145 }
2146 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2147 unsigned &NumRecords) const {
2148 // FIXME: Implement.
2149 Records = 0;
2150 NumRecords = 0;
2151 }
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002152 virtual void getGCCRegNames(const char * const *&Names,
2153 unsigned &NumNames) const;
2154 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2155 unsigned &NumAliases) const {
2156 // No aliases.
2157 Aliases = 0;
2158 NumAliases = 0;
2159 }
2160 virtual bool validateAsmConstraint(const char *&Name,
2161 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov03265b62009-10-15 23:17:13 +00002162 // No target constraints for now.
2163 return false;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002164 }
2165 virtual const char *getClobbers() const {
2166 // FIXME: Is this really right?
2167 return "";
2168 }
2169 virtual const char *getVAListDeclaration() const {
2170 // FIXME: implement
Anton Korobeynikoveb716852009-05-08 18:24:57 +00002171 return "typedef char* __builtin_va_list;";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002172 }
2173 };
2174
2175 const char * const MSP430TargetInfo::GCCRegNames[] = {
2176 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2177 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2178 };
2179
2180 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
2181 unsigned &NumNames) const {
2182 Names = GCCRegNames;
2183 NumNames = llvm::array_lengthof(GCCRegNames);
2184 }
2185}
2186
2187
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002188namespace {
2189 class SystemZTargetInfo : public TargetInfo {
2190 static const char * const GCCRegNames[];
2191 public:
2192 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
2193 TLSSupported = false;
2194 IntWidth = IntAlign = 32;
2195 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
2196 PointerWidth = PointerAlign = 64;
Chris Lattner1932e122009-11-07 18:59:41 +00002197 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
2198 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002199 }
2200 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002201 MacroBuilder &Builder) const {
2202 Builder.defineMacro("__s390__");
2203 Builder.defineMacro("__s390x__");
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002204 }
2205 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2206 unsigned &NumRecords) const {
2207 // FIXME: Implement.
2208 Records = 0;
2209 NumRecords = 0;
2210 }
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002211
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002212 virtual void getGCCRegNames(const char * const *&Names,
2213 unsigned &NumNames) const;
2214 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2215 unsigned &NumAliases) const {
2216 // No aliases.
2217 Aliases = 0;
2218 NumAliases = 0;
2219 }
2220 virtual bool validateAsmConstraint(const char *&Name,
2221 TargetInfo::ConstraintInfo &info) const {
2222 // FIXME: implement
2223 return true;
2224 }
2225 virtual const char *getClobbers() const {
2226 // FIXME: Is this really right?
2227 return "";
2228 }
2229 virtual const char *getVAListDeclaration() const {
2230 // FIXME: implement
2231 return "typedef char* __builtin_va_list;";
2232 }
2233 };
2234
2235 const char * const SystemZTargetInfo::GCCRegNames[] = {
2236 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2237 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2238 };
2239
2240 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
2241 unsigned &NumNames) const {
2242 Names = GCCRegNames;
2243 NumNames = llvm::array_lengthof(GCCRegNames);
2244 }
2245}
2246
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002247namespace {
2248 class BlackfinTargetInfo : public TargetInfo {
2249 static const char * const GCCRegNames[];
2250 public:
2251 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
2252 TLSSupported = false;
2253 DoubleAlign = 32;
2254 LongLongAlign = 32;
2255 LongDoubleAlign = 32;
Chris Lattner1932e122009-11-07 18:59:41 +00002256 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002257 }
2258
2259 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002260 MacroBuilder &Builder) const {
2261 DefineStd(Builder, "bfin", Opts);
2262 DefineStd(Builder, "BFIN", Opts);
2263 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002264 // FIXME: This one is really dependent on -mcpu
Benjamin Kramera9992772010-01-09 17:55:51 +00002265 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002266 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
2267 }
2268
2269 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2270 unsigned &NumRecords) const {
2271 // FIXME: Implement.
2272 Records = 0;
2273 NumRecords = 0;
2274 }
2275
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002276 virtual void getGCCRegNames(const char * const *&Names,
2277 unsigned &NumNames) const;
2278
2279 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2280 unsigned &NumAliases) const {
2281 // No aliases.
2282 Aliases = 0;
2283 NumAliases = 0;
2284 }
2285
2286 virtual bool validateAsmConstraint(const char *&Name,
2287 TargetInfo::ConstraintInfo &Info) const {
2288 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
2289 Info.setAllowsRegister();
2290 return true;
2291 }
2292 return false;
2293 }
2294
2295 virtual const char *getClobbers() const {
2296 return "";
2297 }
2298
2299 virtual const char *getVAListDeclaration() const {
2300 return "typedef char* __builtin_va_list;";
2301 }
2302 };
2303
2304 const char * const BlackfinTargetInfo::GCCRegNames[] = {
2305 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2306 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
2307 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
2308 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
2309 "a0", "a1", "cc",
2310 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
2311 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
2312 };
2313
2314 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
2315 unsigned &NumNames) const {
2316 Names = GCCRegNames;
2317 NumNames = llvm::array_lengthof(GCCRegNames);
2318 }
2319}
2320
Eli Friedmanb63decf2009-08-19 20:47:07 +00002321namespace {
2322
Mike Stump1eb44332009-09-09 15:08:12 +00002323 // LLVM and Clang cannot be used directly to output native binaries for
2324 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmanb63decf2009-08-19 20:47:07 +00002325 // type and alignment information.
Mike Stump1eb44332009-09-09 15:08:12 +00002326 //
2327 // TCE uses the llvm bitcode as input and uses it for generating customized
2328 // target processor and program binary. TCE co-design environment is
Eli Friedmanb63decf2009-08-19 20:47:07 +00002329 // publicly available in http://tce.cs.tut.fi
2330
2331 class TCETargetInfo : public TargetInfo{
2332 public:
2333 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
2334 TLSSupported = false;
2335 IntWidth = 32;
2336 LongWidth = LongLongWidth = 32;
Eli Friedmanb63decf2009-08-19 20:47:07 +00002337 PointerWidth = 32;
2338 IntAlign = 32;
2339 LongAlign = LongLongAlign = 32;
2340 PointerAlign = 32;
2341 SizeType = UnsignedInt;
2342 IntMaxType = SignedLong;
2343 UIntMaxType = UnsignedLong;
2344 IntPtrType = SignedInt;
2345 PtrDiffType = SignedInt;
2346 FloatWidth = 32;
2347 FloatAlign = 32;
2348 DoubleWidth = 32;
2349 DoubleAlign = 32;
2350 LongDoubleWidth = 32;
2351 LongDoubleAlign = 32;
2352 FloatFormat = &llvm::APFloat::IEEEsingle;
2353 DoubleFormat = &llvm::APFloat::IEEEsingle;
2354 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner3a47c4e2010-03-04 21:07:38 +00002355 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
2356 "i16:16:32-i32:32:32-i64:32:32-"
2357 "f32:32:32-f64:64:64-v64:64:64-"
2358 "v128:128:128-a0:0:64-n32";
Eli Friedmanb63decf2009-08-19 20:47:07 +00002359 }
2360
2361 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002362 MacroBuilder &Builder) const {
2363 DefineStd(Builder, "tce", Opts);
2364 Builder.defineMacro("__TCE__");
2365 Builder.defineMacro("__TCE_V1__");
Eli Friedmanb63decf2009-08-19 20:47:07 +00002366 }
2367 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2368 unsigned &NumRecords) const {}
Daniel Dunbar55cc2ed2009-08-24 09:54:37 +00002369 virtual const char *getClobbers() const {
2370 return "";
2371 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002372 virtual const char *getVAListDeclaration() const {
2373 return "typedef void* __builtin_va_list;";
2374 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002375 virtual void getGCCRegNames(const char * const *&Names,
2376 unsigned &NumNames) const {}
2377 virtual bool validateAsmConstraint(const char *&Name,
2378 TargetInfo::ConstraintInfo &info) const {
2379 return true;
2380 }
2381 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2382 unsigned &NumAliases) const {}
2383 };
2384}
2385
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002386namespace {
2387class MipsTargetInfo : public TargetInfo {
Eric Christophered734732010-03-02 02:41:08 +00002388 std::string ABI, CPU;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002389 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2390 static const char * const GCCRegNames[];
2391public:
Eric Christophered734732010-03-02 02:41:08 +00002392 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002393 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2394 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2395 }
Eric Christophered734732010-03-02 02:41:08 +00002396 virtual const char *getABI() const { return ABI.c_str(); }
2397 virtual bool setABI(const std::string &Name) {
2398
2399 if ((Name == "o32") || (Name == "eabi")) {
2400 ABI = Name;
2401 return true;
2402 } else
2403 return false;
2404 }
2405 virtual bool setCPU(const std::string &Name) {
2406 CPU = Name;
2407 return true;
2408 }
2409 void getDefaultFeatures(const std::string &CPU,
2410 llvm::StringMap<bool> &Features) const {
2411 Features[ABI] = true;
2412 Features[CPU] = true;
2413 }
2414 virtual void getArchDefines(const LangOptions &Opts,
2415 MacroBuilder &Builder) const {
2416 if (ABI == "o32")
2417 Builder.defineMacro("__mips_o32");
2418 else if (ABI == "eabi")
2419 Builder.defineMacro("__mips_eabi");
2420 }
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002421 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002422 MacroBuilder &Builder) const {
2423 DefineStd(Builder, "mips", Opts);
2424 Builder.defineMacro("_mips");
2425 DefineStd(Builder, "MIPSEB", Opts);
2426 Builder.defineMacro("_MIPSEB");
2427 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002428 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002429 }
2430 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2431 unsigned &NumRecords) const {
2432 // FIXME: Implement!
2433 }
2434 virtual const char *getVAListDeclaration() const {
2435 return "typedef void* __builtin_va_list;";
2436 }
2437 virtual void getGCCRegNames(const char * const *&Names,
2438 unsigned &NumNames) const;
2439 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2440 unsigned &NumAliases) const;
2441 virtual bool validateAsmConstraint(const char *&Name,
2442 TargetInfo::ConstraintInfo &Info) const {
2443 switch (*Name) {
2444 default:
2445 case 'r': // CPU registers.
2446 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2447 case 'y': // Equivalent to "r", backwards compatibility only.
2448 case 'f': // floating-point registers.
2449 Info.setAllowsRegister();
2450 return true;
2451 }
2452 return false;
2453 }
2454
2455 virtual const char *getClobbers() const {
2456 // FIXME: Implement!
2457 return "";
2458 }
2459};
2460
2461const char * const MipsTargetInfo::GCCRegNames[] = {
Michael J. Spencer20249a12010-10-21 03:16:25 +00002462 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002463 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2464 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2465 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2466 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2467 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2468 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2469 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2470 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2471 "$fcc5","$fcc6","$fcc7"
2472};
2473
2474void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2475 unsigned &NumNames) const {
2476 Names = GCCRegNames;
2477 NumNames = llvm::array_lengthof(GCCRegNames);
2478}
2479
2480const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2481 { { "at" }, "$1" },
2482 { { "v0" }, "$2" },
2483 { { "v1" }, "$3" },
2484 { { "a0" }, "$4" },
2485 { { "a1" }, "$5" },
2486 { { "a2" }, "$6" },
2487 { { "a3" }, "$7" },
2488 { { "t0" }, "$8" },
2489 { { "t1" }, "$9" },
2490 { { "t2" }, "$10" },
2491 { { "t3" }, "$11" },
2492 { { "t4" }, "$12" },
2493 { { "t5" }, "$13" },
2494 { { "t6" }, "$14" },
2495 { { "t7" }, "$15" },
2496 { { "s0" }, "$16" },
2497 { { "s1" }, "$17" },
2498 { { "s2" }, "$18" },
2499 { { "s3" }, "$19" },
2500 { { "s4" }, "$20" },
2501 { { "s5" }, "$21" },
2502 { { "s6" }, "$22" },
2503 { { "s7" }, "$23" },
2504 { { "t8" }, "$24" },
2505 { { "t9" }, "$25" },
2506 { { "k0" }, "$26" },
2507 { { "k1" }, "$27" },
2508 { { "gp" }, "$28" },
2509 { { "sp" }, "$29" },
2510 { { "fp" }, "$30" },
2511 { { "ra" }, "$31" }
2512};
2513
2514void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2515 unsigned &NumAliases) const {
2516 Aliases = GCCRegAliases;
2517 NumAliases = llvm::array_lengthof(GCCRegAliases);
2518}
2519} // end anonymous namespace.
2520
2521namespace {
2522class MipselTargetInfo : public MipsTargetInfo {
2523public:
2524 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2525 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2526 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2527 }
2528
2529 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002530 MacroBuilder &Builder) const;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002531};
2532
2533void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002534 MacroBuilder &Builder) const {
2535 DefineStd(Builder, "mips", Opts);
2536 Builder.defineMacro("_mips");
2537 DefineStd(Builder, "MIPSEL", Opts);
2538 Builder.defineMacro("_MIPSEL");
2539 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002540 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002541}
2542} // end anonymous namespace.
2543
Reid Spencer5f016e22007-07-11 17:01:13 +00002544//===----------------------------------------------------------------------===//
2545// Driver code
2546//===----------------------------------------------------------------------===//
2547
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002548static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002549 llvm::Triple Triple(T);
2550 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman61538a72008-05-20 14:21:01 +00002551
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002552 switch (Triple.getArch()) {
2553 default:
2554 return NULL;
Eli Friedman61538a72008-05-20 14:21:01 +00002555
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002556 case llvm::Triple::arm:
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +00002557 case llvm::Triple::thumb:
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002558 switch (os) {
Rafael Espindola022a8a52010-06-10 00:46:51 +00002559 case llvm::Triple::Linux:
2560 return new LinuxTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002561 case llvm::Triple::Darwin:
Eli Friedmaned855cb2008-08-21 00:13:15 +00002562 return new DarwinARMTargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002563 case llvm::Triple::FreeBSD:
Torok Edwin5f6c1942009-06-30 17:10:35 +00002564 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002565 default:
2566 return new ARMTargetInfo(T);
2567 }
Eli Friedman61538a72008-05-20 14:21:01 +00002568
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002569 case llvm::Triple::bfin:
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002570 return new BlackfinTargetInfo(T);
2571
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002572 case llvm::Triple::msp430:
2573 return new MSP430TargetInfo(T);
Eli Friedman61538a72008-05-20 14:21:01 +00002574
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002575 case llvm::Triple::mips:
2576 if (os == llvm::Triple::Psp)
2577 return new PSPTargetInfo<MipsTargetInfo>(T);
2578 if (os == llvm::Triple::Linux)
2579 return new LinuxTargetInfo<MipsTargetInfo>(T);
2580 return new MipsTargetInfo(T);
2581
2582 case llvm::Triple::mipsel:
2583 if (os == llvm::Triple::Psp)
2584 return new PSPTargetInfo<MipselTargetInfo>(T);
2585 if (os == llvm::Triple::Linux)
2586 return new LinuxTargetInfo<MipselTargetInfo>(T);
2587 return new MipselTargetInfo(T);
2588
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002589 case llvm::Triple::ppc:
2590 if (os == llvm::Triple::Darwin)
Roman Divackyc81f2a22011-01-06 08:27:10 +00002591 return new DarwinPPC32TargetInfo(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002592 else if (os == llvm::Triple::FreeBSD)
2593 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002594 return new PPC32TargetInfo(T);
2595
2596 case llvm::Triple::ppc64:
2597 if (os == llvm::Triple::Darwin)
Daniel Dunbar4c6a2262010-05-30 00:07:30 +00002598 return new DarwinPPC64TargetInfo(T);
John Thompson3f6918a2009-11-19 17:18:50 +00002599 else if (os == llvm::Triple::Lv2)
2600 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002601 else if (os == llvm::Triple::FreeBSD)
2602 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002603 return new PPC64TargetInfo(T);
2604
Chris Lattner9cbeb632010-03-06 21:21:27 +00002605 case llvm::Triple::mblaze:
2606 return new MBlazeTargetInfo(T);
2607
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002608 case llvm::Triple::sparc:
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002609 if (os == llvm::Triple::AuroraUX)
2610 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002611 if (os == llvm::Triple::Solaris)
2612 return new SolarisSparcV8TargetInfo(T);
2613 return new SparcV8TargetInfo(T);
2614
John Thompson3f6918a2009-11-19 17:18:50 +00002615 // FIXME: Need a real SPU target.
2616 case llvm::Triple::cellspu:
2617 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2618
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002619 case llvm::Triple::systemz:
2620 return new SystemZTargetInfo(T);
2621
Eli Friedmanb63decf2009-08-19 20:47:07 +00002622 case llvm::Triple::tce:
2623 return new TCETargetInfo(T);
2624
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002625 case llvm::Triple::x86:
2626 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002627 case llvm::Triple::AuroraUX:
2628 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002629 case llvm::Triple::Darwin:
2630 return new DarwinI386TargetInfo(T);
2631 case llvm::Triple::Linux:
2632 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2633 case llvm::Triple::DragonFly:
2634 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2635 case llvm::Triple::NetBSD:
2636 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2637 case llvm::Triple::OpenBSD:
2638 return new OpenBSDI386TargetInfo(T);
2639 case llvm::Triple::FreeBSD:
2640 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
Chris Lattner38e317d2010-07-07 16:01:42 +00002641 case llvm::Triple::Minix:
2642 return new MinixTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002643 case llvm::Triple::Solaris:
2644 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2645 case llvm::Triple::Cygwin:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002646 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002647 case llvm::Triple::MinGW32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002648 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002649 case llvm::Triple::Win32:
Michael J. Spencera764e832010-10-21 08:22:51 +00002650 return new VisualStudioWindowsX86_32TargetInfo(T);
Chris Lattner86ed3a32010-04-11 19:29:39 +00002651 case llvm::Triple::Haiku:
2652 return new HaikuX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002653 default:
2654 return new X86_32TargetInfo(T);
2655 }
2656
2657 case llvm::Triple::x86_64:
2658 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002659 case llvm::Triple::AuroraUX:
2660 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002661 case llvm::Triple::Darwin:
2662 return new DarwinX86_64TargetInfo(T);
2663 case llvm::Triple::Linux:
2664 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner7a7ca282010-01-09 05:41:14 +00002665 case llvm::Triple::DragonFly:
2666 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002667 case llvm::Triple::NetBSD:
2668 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2669 case llvm::Triple::OpenBSD:
2670 return new OpenBSDX86_64TargetInfo(T);
2671 case llvm::Triple::FreeBSD:
2672 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2673 case llvm::Triple::Solaris:
2674 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002675 case llvm::Triple::MinGW64:
2676 return new MinGWX86_64TargetInfo(T);
2677 case llvm::Triple::Win32: // This is what Triple.h supports now.
Michael J. Spencera764e832010-10-21 08:22:51 +00002678 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002679 default:
2680 return new X86_64TargetInfo(T);
2681 }
2682 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002683}
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002684
2685/// CreateTargetInfo - Return the target info object for the specified target
2686/// triple.
2687TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002688 TargetOptions &Opts) {
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002689 llvm::Triple Triple(Opts.Triple);
2690
2691 // Construct the target
2692 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2693 if (!Target) {
2694 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2695 return 0;
2696 }
2697
Daniel Dunbareac7c532009-12-18 18:42:37 +00002698 // Set the target CPU if specified.
2699 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2700 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2701 return 0;
2702 }
2703
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002704 // Set the target ABI if specified.
2705 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2706 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2707 return 0;
2708 }
2709
Charles Davis98b7c5c2010-06-11 01:06:47 +00002710 // Set the target C++ ABI.
John McCallee79a4c2010-08-21 22:46:04 +00002711 if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Charles Davis98b7c5c2010-06-11 01:06:47 +00002712 Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
2713 return 0;
2714 }
2715
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002716 // Compute the default target features, we need the target to handle this
2717 // because features may have dependencies on one another.
2718 llvm::StringMap<bool> Features;
2719 Target->getDefaultFeatures(Opts.CPU, Features);
2720
2721 // Apply the user specified deltas.
2722 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2723 ie = Opts.Features.end(); it != ie; ++it) {
2724 const char *Name = it->c_str();
2725
2726 // Apply the feature via the target.
2727 if ((Name[0] != '-' && Name[0] != '+') ||
2728 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2729 Diags.Report(diag::err_target_invalid_feature) << Name;
2730 return 0;
2731 }
2732 }
2733
2734 // Add the features to the compile options.
2735 //
2736 // FIXME: If we are completely confident that we have the right set, we only
2737 // need to pass the minuses.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002738 Opts.Features.clear();
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002739 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2740 ie = Features.end(); it != ie; ++it)
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002741 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2742 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002743
2744 return Target.take();
2745}