blob: 697603bbac85561d1ad2d917fb4ccb6f2b11fcd4 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikova7c47172009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenekbbced582007-12-12 18:05:32 +000011// target triple.
Reid Spencer5f016e22007-07-11 17:01:13 +000012//
13//===----------------------------------------------------------------------===//
14
Reid Spencer5f016e22007-07-11 17:01:13 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000016#include "clang/Basic/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
Chris Lattner8fc4dfb2008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Chandler Carruth103b71c2010-01-20 06:13:02 +000019#include "clang/Basic/MacroBuilder.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000020#include "clang/Basic/TargetBuiltins.h"
21#include "clang/Basic/TargetOptions.h"
Eli Friedman25531262008-05-20 14:27:34 +000022#include "llvm/ADT/APFloat.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000023#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar29a790b2009-11-11 09:38:56 +000024#include "llvm/ADT/STLExtras.h"
Daniel Dunbar77659342009-08-19 20:04:03 +000025#include "llvm/ADT/StringRef.h"
Daniel Dunbar29a790b2009-11-11 09:38:56 +000026#include "llvm/ADT/StringSwitch.h"
Chris Lattner4c28b1c2009-08-12 06:24:27 +000027#include "llvm/ADT/Triple.h"
Chris Lattner797c3c42009-08-10 19:03:04 +000028#include "llvm/MC/MCSectionMachO.h"
Dale Johannesen1e592cb2010-10-29 23:24:33 +000029#include "llvm/Type.h"
Benjamin Kramer48725082010-01-09 18:20:57 +000030#include <algorithm>
Reid Spencer5f016e22007-07-11 17:01:13 +000031using namespace clang;
32
Reid Spencer5f016e22007-07-11 17:01:13 +000033//===----------------------------------------------------------------------===//
34// Common code shared among targets.
35//===----------------------------------------------------------------------===//
36
Chris Lattnerca45cff2009-03-20 16:06:38 +000037/// DefineStd - Define a macro name and standard variants. For example if
38/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
39/// when in GNU mode.
Benjamin Kramera9992772010-01-09 17:55:51 +000040static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
Chris Lattnerca45cff2009-03-20 16:06:38 +000041 const LangOptions &Opts) {
42 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000043
Chris Lattnerca45cff2009-03-20 16:06:38 +000044 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
45 // in the user's namespace.
46 if (Opts.GNUMode)
Benjamin Kramera9992772010-01-09 17:55:51 +000047 Builder.defineMacro(MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000048
Chris Lattnerca45cff2009-03-20 16:06:38 +000049 // Define __unix.
Benjamin Kramera9992772010-01-09 17:55:51 +000050 Builder.defineMacro("__" + MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000051
Chris Lattnerca45cff2009-03-20 16:06:38 +000052 // Define __unix__.
Benjamin Kramera9992772010-01-09 17:55:51 +000053 Builder.defineMacro("__" + MacroName + "__");
Chris Lattnerca45cff2009-03-20 16:06:38 +000054}
55
Chris Lattnerd29b6302008-10-05 21:50:58 +000056//===----------------------------------------------------------------------===//
57// Defines specific to certain operating systems.
58//===----------------------------------------------------------------------===//
Chris Lattner797c3c42009-08-10 19:03:04 +000059
Torok Edwin5f6c1942009-06-30 17:10:35 +000060namespace {
Douglas Gregora3844922009-07-01 15:12:53 +000061template<typename TgtInfo>
62class OSTargetInfo : public TgtInfo {
Torok Edwin5f6c1942009-06-30 17:10:35 +000063protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +000064 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +000065 MacroBuilder &Builder) const=0;
Torok Edwin5f6c1942009-06-30 17:10:35 +000066public:
Douglas Gregora3844922009-07-01 15:12:53 +000067 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwin5f6c1942009-06-30 17:10:35 +000068 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +000069 MacroBuilder &Builder) const {
70 TgtInfo::getTargetDefines(Opts, Builder);
71 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
Torok Edwinb0a5b242009-06-30 17:00:25 +000072 }
Torok Edwin5f6c1942009-06-30 17:10:35 +000073
74};
Chris Lattner4c28b1c2009-08-12 06:24:27 +000075} // end anonymous namespace
Torok Edwinb0a5b242009-06-30 17:00:25 +000076
Chris Lattner797c3c42009-08-10 19:03:04 +000077
Daniel Dunbar21ae3192010-01-26 01:44:04 +000078static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
79 const llvm::Triple &Triple) {
Benjamin Kramera9992772010-01-09 17:55:51 +000080 Builder.defineMacro("__APPLE_CC__", "5621");
81 Builder.defineMacro("__APPLE__");
82 Builder.defineMacro("__MACH__");
83 Builder.defineMacro("OBJC_NEW_PROPERTIES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000084
Chris Lattner10d24272009-04-07 16:50:40 +000085 // __weak is always defined, for use in blocks and with objc pointers.
Benjamin Kramera9992772010-01-09 17:55:51 +000086 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000087
Chris Lattner10d24272009-04-07 16:50:40 +000088 // Darwin defines __strong even in C mode (just to nothing).
89 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Benjamin Kramera9992772010-01-09 17:55:51 +000090 Builder.defineMacro("__strong", "");
Chris Lattner10d24272009-04-07 16:50:40 +000091 else
Benjamin Kramera9992772010-01-09 17:55:51 +000092 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
Eli Friedman2de4fee2009-06-04 23:00:29 +000093
94 if (Opts.Static)
Benjamin Kramera9992772010-01-09 17:55:51 +000095 Builder.defineMacro("__STATIC__");
Eli Friedman2de4fee2009-06-04 23:00:29 +000096 else
Benjamin Kramera9992772010-01-09 17:55:51 +000097 Builder.defineMacro("__DYNAMIC__");
Daniel Dunbar5345c392009-09-03 04:54:28 +000098
99 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000100 Builder.defineMacro("_REENTRANT");
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000101
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000102 // Get the OS version number from the triple.
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000103 unsigned Maj, Min, Rev;
Mike Stump1eb44332009-09-09 15:08:12 +0000104
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000105 // If no version was given, default to to 10.4.0, for simplifying tests.
106 if (Triple.getOSName() == "darwin") {
107 Min = Rev = 0;
108 Maj = 8;
109 } else
110 Triple.getDarwinNumber(Maj, Min, Rev);
111
112 // Set the appropriate OS version define.
113 if (Triple.getEnvironmentName() == "iphoneos") {
114 assert(Maj < 10 && Min < 99 && Rev < 99 && "Invalid version!");
115 char Str[6];
116 Str[0] = '0' + Maj;
117 Str[1] = '0' + (Min / 10);
118 Str[2] = '0' + (Min % 10);
119 Str[3] = '0' + (Rev / 10);
120 Str[4] = '0' + (Rev % 10);
121 Str[5] = '\0';
122 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
123 } else {
124 // For historical reasons that make little sense, the version passed here is
125 // the "darwin" version, which drops the 10 and offsets by 4.
126 Rev = Min;
127 Min = Maj - 4;
128 Maj = 10;
129
130 assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
131 assert(Maj < 99 && Min < 10 && Rev < 10 && "Invalid version!");
132 char Str[5];
133 Str[0] = '0' + (Maj / 10);
134 Str[1] = '0' + (Maj % 10);
135 Str[2] = '0' + Min;
136 Str[3] = '0' + Rev;
137 Str[4] = '\0';
138 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000139 }
Eli Friedman618234a2008-08-20 02:34:37 +0000140}
Reid Spencer5f016e22007-07-11 17:01:13 +0000141
Chris Lattner797c3c42009-08-10 19:03:04 +0000142namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000143template<typename Target>
144class DarwinTargetInfo : public OSTargetInfo<Target> {
145protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000146 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000147 MacroBuilder &Builder) const {
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000148 getDarwinDefines(Builder, Opts, Triple);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000149 }
Mike Stump1eb44332009-09-09 15:08:12 +0000150
Torok Edwin5f6c1942009-06-30 17:10:35 +0000151public:
152 DarwinTargetInfo(const std::string& triple) :
153 OSTargetInfo<Target>(triple) {
Eric Christopherdd53ec92010-06-25 19:04:52 +0000154 this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;
Torok Edwin5f6c1942009-06-30 17:10:35 +0000155 }
156
Anders Carlssonf959fb52010-01-30 18:33:31 +0000157 virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
Chris Lattner797c3c42009-08-10 19:03:04 +0000158 // Let MCSectionMachO validate this.
159 llvm::StringRef Segment, Section;
160 unsigned TAA, StubSize;
161 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
162 TAA, StubSize);
163 }
Michael J. Spencer20249a12010-10-21 03:16:25 +0000164
Anders Carlsson18af3682010-06-08 22:47:50 +0000165 virtual const char *getStaticInitSectionSpecifier() const {
166 // FIXME: We should return 0 when building kexts.
167 return "__TEXT,__StaticInit,regular,pure_instructions";
168 }
Michael J. Spencer20249a12010-10-21 03:16:25 +0000169
Torok Edwin5f6c1942009-06-30 17:10:35 +0000170};
171
Chris Lattner797c3c42009-08-10 19:03:04 +0000172
Torok Edwin5f6c1942009-06-30 17:10:35 +0000173// DragonFlyBSD Target
174template<typename Target>
175class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
176protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000177 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000178 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000179 // DragonFly defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000180 Builder.defineMacro("__DragonFly__");
181 Builder.defineMacro("__DragonFly_cc_version", "100001");
182 Builder.defineMacro("__ELF__");
183 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
184 Builder.defineMacro("__tune_i386__");
185 DefineStd(Builder, "unix", Opts);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000186 }
187public:
Mike Stump1eb44332009-09-09 15:08:12 +0000188 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000189 : OSTargetInfo<Target>(triple) {}
190};
191
192// FreeBSD Target
193template<typename Target>
194class FreeBSDTargetInfo : public OSTargetInfo<Target> {
195protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000196 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000197 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000198 // FreeBSD defines; list based off of gcc output
199
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000200 // FIXME: Move version number handling to llvm::Triple.
Benjamin Kramer3bb65302010-01-30 19:55:01 +0000201 llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000202
Benjamin Kramer3bb65302010-01-30 19:55:01 +0000203 Builder.defineMacro("__FreeBSD__", Release);
204 Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
Benjamin Kramera9992772010-01-09 17:55:51 +0000205 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
206 DefineStd(Builder, "unix", Opts);
207 Builder.defineMacro("__ELF__");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000208 }
209public:
Mike Stump1eb44332009-09-09 15:08:12 +0000210 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands1e90faf2009-07-08 13:55:08 +0000211 : OSTargetInfo<Target>(triple) {
212 this->UserLabelPrefix = "";
213 }
Torok Edwin5f6c1942009-06-30 17:10:35 +0000214};
215
Chris Lattner38e317d2010-07-07 16:01:42 +0000216// Minix Target
217template<typename Target>
218class MinixTargetInfo : public OSTargetInfo<Target> {
219protected:
220 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
221 MacroBuilder &Builder) const {
222 // Minix defines
223
224 Builder.defineMacro("__minix", "3");
225 Builder.defineMacro("_EM_WSIZE", "4");
226 Builder.defineMacro("_EM_PSIZE", "4");
227 Builder.defineMacro("_EM_SSIZE", "2");
228 Builder.defineMacro("_EM_LSIZE", "4");
229 Builder.defineMacro("_EM_FSIZE", "4");
230 Builder.defineMacro("_EM_DSIZE", "8");
231 DefineStd(Builder, "unix", Opts);
232 }
233public:
234 MinixTargetInfo(const std::string &triple)
235 : OSTargetInfo<Target>(triple) {
236 this->UserLabelPrefix = "";
237 }
238};
239
Torok Edwin5f6c1942009-06-30 17:10:35 +0000240// Linux target
241template<typename Target>
242class LinuxTargetInfo : public OSTargetInfo<Target> {
243protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000244 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000245 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000246 // Linux defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000247 DefineStd(Builder, "unix", Opts);
248 DefineStd(Builder, "linux", Opts);
249 Builder.defineMacro("__gnu_linux__");
250 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000251 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000252 Builder.defineMacro("_REENTRANT");
Douglas Gregor2b003fd2010-04-21 05:52:38 +0000253 if (Opts.CPlusPlus)
254 Builder.defineMacro("_GNU_SOURCE");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000255 }
256public:
Mike Stump1eb44332009-09-09 15:08:12 +0000257 LinuxTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000258 : OSTargetInfo<Target>(triple) {
259 this->UserLabelPrefix = "";
260 }
261};
262
Chris Lattnerb62bb282009-07-13 20:29:08 +0000263// NetBSD Target
264template<typename Target>
265class NetBSDTargetInfo : public OSTargetInfo<Target> {
266protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000267 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000268 MacroBuilder &Builder) const {
Chris Lattnerb62bb282009-07-13 20:29:08 +0000269 // NetBSD defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000270 Builder.defineMacro("__NetBSD__");
271 Builder.defineMacro("__unix__");
272 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000273 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000274 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerb62bb282009-07-13 20:29:08 +0000275 }
276public:
Mike Stump1eb44332009-09-09 15:08:12 +0000277 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerb62bb282009-07-13 20:29:08 +0000278 : OSTargetInfo<Target>(triple) {
279 this->UserLabelPrefix = "";
280 }
281};
282
Torok Edwin5f6c1942009-06-30 17:10:35 +0000283// OpenBSD Target
284template<typename Target>
285class OpenBSDTargetInfo : public OSTargetInfo<Target> {
286protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000287 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000288 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000289 // OpenBSD defines; list based off of gcc output
290
Benjamin Kramera9992772010-01-09 17:55:51 +0000291 Builder.defineMacro("__OpenBSD__");
292 DefineStd(Builder, "unix", Opts);
293 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000294 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000295 Builder.defineMacro("_POSIX_THREADS");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000296 }
297public:
Mike Stump1eb44332009-09-09 15:08:12 +0000298 OpenBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000299 : OSTargetInfo<Target>(triple) {}
300};
301
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000302// PSP Target
303template<typename Target>
304class PSPTargetInfo : public OSTargetInfo<Target> {
305protected:
306 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000307 MacroBuilder &Builder) const {
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000308 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramera9992772010-01-09 17:55:51 +0000309 Builder.defineMacro("PSP");
310 Builder.defineMacro("_PSP");
311 Builder.defineMacro("__psp__");
312 Builder.defineMacro("__ELF__");
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000313 }
314public:
315 PSPTargetInfo(const std::string& triple)
316 : OSTargetInfo<Target>(triple) {
317 this->UserLabelPrefix = "";
318 }
319};
320
John Thompson3f6918a2009-11-19 17:18:50 +0000321// PS3 PPU Target
322template<typename Target>
323class PS3PPUTargetInfo : public OSTargetInfo<Target> {
324protected:
325 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000326 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000327 // PS3 PPU defines.
John Thompsonfb457972010-03-25 16:18:32 +0000328 Builder.defineMacro("__PPC__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000329 Builder.defineMacro("__PPU__");
330 Builder.defineMacro("__CELLOS_LV2__");
331 Builder.defineMacro("__ELF__");
332 Builder.defineMacro("__LP32__");
John Thompson8e6065a2010-06-24 22:44:13 +0000333 Builder.defineMacro("_ARCH_PPC64");
334 Builder.defineMacro("__powerpc64__");
John Thompson3f6918a2009-11-19 17:18:50 +0000335 }
336public:
337 PS3PPUTargetInfo(const std::string& triple)
338 : OSTargetInfo<Target>(triple) {
339 this->UserLabelPrefix = "";
John Thompsonec387af2009-12-18 14:21:08 +0000340 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
John Thompson8e6065a2010-06-24 22:44:13 +0000341 this->IntMaxType = TargetInfo::SignedLongLong;
342 this->UIntMaxType = TargetInfo::UnsignedLongLong;
343 this->Int64Type = TargetInfo::SignedLongLong;
John Thompsonec387af2009-12-18 14:21:08 +0000344 this->SizeType = TargetInfo::UnsignedInt;
John Thompson8e6065a2010-06-24 22:44:13 +0000345 this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
346 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
John Thompson3f6918a2009-11-19 17:18:50 +0000347 }
348};
349
350// FIXME: Need a real SPU target.
351// PS3 SPU Target
352template<typename Target>
353class PS3SPUTargetInfo : public OSTargetInfo<Target> {
354protected:
355 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000356 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000357 // PS3 PPU defines.
Benjamin Kramera9992772010-01-09 17:55:51 +0000358 Builder.defineMacro("__SPU__");
359 Builder.defineMacro("__ELF__");
John Thompson3f6918a2009-11-19 17:18:50 +0000360 }
361public:
362 PS3SPUTargetInfo(const std::string& triple)
363 : OSTargetInfo<Target>(triple) {
364 this->UserLabelPrefix = "";
365 }
366};
367
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000368// AuroraUX target
369template<typename Target>
370class AuroraUXTargetInfo : public OSTargetInfo<Target> {
371protected:
372 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000373 MacroBuilder &Builder) const {
374 DefineStd(Builder, "sun", Opts);
375 DefineStd(Builder, "unix", Opts);
376 Builder.defineMacro("__ELF__");
377 Builder.defineMacro("__svr4__");
378 Builder.defineMacro("__SVR4");
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000379 }
380public:
381 AuroraUXTargetInfo(const std::string& triple)
382 : OSTargetInfo<Target>(triple) {
383 this->UserLabelPrefix = "";
384 this->WCharType = this->SignedLong;
385 // FIXME: WIntType should be SignedLong
386 }
387};
388
Torok Edwin5f6c1942009-06-30 17:10:35 +0000389// Solaris target
390template<typename Target>
391class SolarisTargetInfo : public OSTargetInfo<Target> {
392protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000393 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000394 MacroBuilder &Builder) const {
395 DefineStd(Builder, "sun", Opts);
396 DefineStd(Builder, "unix", Opts);
397 Builder.defineMacro("__ELF__");
398 Builder.defineMacro("__svr4__");
399 Builder.defineMacro("__SVR4");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000400 }
401public:
Mike Stump1eb44332009-09-09 15:08:12 +0000402 SolarisTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000403 : OSTargetInfo<Target>(triple) {
404 this->UserLabelPrefix = "";
405 this->WCharType = this->SignedLong;
406 // FIXME: WIntType should be SignedLong
407 }
408};
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000409
410// Windows target
411template<typename Target>
412class WindowsTargetInfo : public OSTargetInfo<Target> {
413protected:
414 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
415 MacroBuilder &Builder) const {
Michael J. Spencera764e832010-10-21 08:22:51 +0000416 Builder.defineMacro("_WIN32");
417 }
418 void getVisualStudioDefines(const LangOptions &Opts,
419 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000420 if (Opts.CPlusPlus) {
421 if (Opts.RTTI)
422 Builder.defineMacro("_CPPRTTI");
423
424 if (Opts.Exceptions)
425 Builder.defineMacro("_CPPUNWIND");
426 }
427
428 if (!Opts.CharIsSigned)
429 Builder.defineMacro("_CHAR_UNSIGNED");
430
431 // FIXME: POSIXThreads isn't exactly the option this should be defined for,
432 // but it works for now.
433 if (Opts.POSIXThreads)
434 Builder.defineMacro("_MT");
Michael J. Spencera764e832010-10-21 08:22:51 +0000435
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000436 if (Opts.MSCVersion != 0)
437 Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
438
439 if (Opts.Microsoft) {
440 Builder.defineMacro("_MSC_EXTENSIONS");
441
442 if (Opts.CPlusPlus0x) {
443 Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
444 Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
445 Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
446 }
447 }
448
449 Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000450 }
451
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000452public:
453 WindowsTargetInfo(const std::string &triple)
454 : OSTargetInfo<Target>(triple) {}
455};
456
Mike Stump1eb44332009-09-09 15:08:12 +0000457} // end anonymous namespace.
Torok Edwin5f6c1942009-06-30 17:10:35 +0000458
Chris Lattnerd29b6302008-10-05 21:50:58 +0000459//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000460// Specific target implementations.
461//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000462
Eli Friedmane4277982008-08-20 23:11:40 +0000463namespace {
464// PPC abstract base class
465class PPCTargetInfo : public TargetInfo {
466 static const Builtin::Info BuiltinInfo[];
467 static const char * const GCCRegNames[];
468 static const TargetInfo::GCCRegAlias GCCRegAliases[];
469
470public:
Eli Friedman15b91762009-06-05 07:05:05 +0000471 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
472
Eli Friedmane4277982008-08-20 23:11:40 +0000473 virtual void getTargetBuiltins(const Builtin::Info *&Records,
474 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000475 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000476 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000477 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000478
Chris Lattner33328642009-03-20 15:52:06 +0000479 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000480 MacroBuilder &Builder) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000481
Eli Friedmane4277982008-08-20 23:11:40 +0000482 virtual const char *getVAListDeclaration() const {
Chris Lattnerd5998502008-10-27 01:11:29 +0000483 return "typedef char* __builtin_va_list;";
484 // This is the right definition for ABI/V4: System V.4/eabi.
485 /*return "typedef struct __va_list_tag {"
Eli Friedmane4277982008-08-20 23:11:40 +0000486 " unsigned char gpr;"
487 " unsigned char fpr;"
488 " unsigned short reserved;"
489 " void* overflow_arg_area;"
490 " void* reg_save_area;"
Chris Lattnerd5998502008-10-27 01:11:29 +0000491 "} __builtin_va_list[1];";*/
Anders Carlsson3346ae62007-11-24 23:38:12 +0000492 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000493 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000494 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000495 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000496 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000497 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000498 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000499 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000500 default: return false;
501 case 'O': // Zero
John Thompson8e6065a2010-06-24 22:44:13 +0000502 break;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000503 case 'b': // Base register
504 case 'f': // Floating point register
Chris Lattner44def072009-04-26 07:16:29 +0000505 Info.setAllowsRegister();
John Thompson8e6065a2010-06-24 22:44:13 +0000506 break;
507 // FIXME: The following are added to allow parsing.
508 // I just took a guess at what the actions should be.
509 // Also, is more specific checking needed? I.e. specific registers?
Michael J. Spencer20249a12010-10-21 03:16:25 +0000510 case 'd': // Floating point register (containing 64-bit value)
John Thompson8e6065a2010-06-24 22:44:13 +0000511 case 'v': // Altivec vector register
512 Info.setAllowsRegister();
513 break;
514 case 'w':
515 switch (Name[1]) {
Michael J. Spencer20249a12010-10-21 03:16:25 +0000516 case 'd':// VSX vector register to hold vector double data
517 case 'f':// VSX vector register to hold vector float data
518 case 's':// VSX vector register to hold scalar float data
519 case 'a':// Any VSX register
John Thompson8e6065a2010-06-24 22:44:13 +0000520 break;
521 default:
522 return false;
523 }
524 Info.setAllowsRegister();
525 Name++; // Skip over 'w'.
526 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000527 case 'h': // `MQ', `CTR', or `LINK' register
528 case 'q': // `MQ' register
529 case 'c': // `CTR' register
530 case 'l': // `LINK' register
531 case 'x': // `CR' register (condition register) number 0
532 case 'y': // `CR' register (condition register)
533 case 'z': // `XER[CA]' carry bit (part of the XER register)
John Thompson8e6065a2010-06-24 22:44:13 +0000534 Info.setAllowsRegister();
535 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000536 case 'I': // Signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000537 case 'J': // Unsigned 16-bit constant shifted left 16 bits
Michael J. Spencer20249a12010-10-21 03:16:25 +0000538 // (use `L' instead for SImode constants)
539 case 'K': // Unsigned 16-bit constant
540 case 'L': // Signed 16-bit constant shifted left 16 bits
541 case 'M': // Constant larger than 31
542 case 'N': // Exact power of 2
543 case 'P': // Constant whose negation is a signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000544 case 'G': // Floating point constant that can be loaded into a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000545 // register with one instruction per word
John Thompson8e6065a2010-06-24 22:44:13 +0000546 case 'H': // Integer/Floating point constant that can be loaded
Michael J. Spencer20249a12010-10-21 03:16:25 +0000547 // into a register using three instructions
John Thompson8e6065a2010-06-24 22:44:13 +0000548 break;
549 case 'm': // Memory operand. Note that on PowerPC targets, m can
550 // include addresses that update the base register. It
551 // is therefore only safe to use `m' in an asm statement
552 // if that asm statement accesses the operand exactly once.
553 // The asm statement must also use `%U<opno>' as a
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000554 // placeholder for the "update" flag in the corresponding
Michael J. Spencer20249a12010-10-21 03:16:25 +0000555 // load or store instruction. For example:
John Thompson8e6065a2010-06-24 22:44:13 +0000556 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
Michael J. Spencer20249a12010-10-21 03:16:25 +0000557 // is correct but:
John Thompson8e6065a2010-06-24 22:44:13 +0000558 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
559 // is not. Use es rather than m if you don't want the base
Michael J. Spencer20249a12010-10-21 03:16:25 +0000560 // register to be updated.
561 case 'e':
John Thompson56b6eca2010-06-25 00:02:05 +0000562 if (Name[1] != 's')
563 return false;
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000564 // es: A "stable" memory operand; that is, one which does not
John Thompson8e6065a2010-06-24 22:44:13 +0000565 // include any automodification of the base register. Unlike
566 // `m', this constraint can be used in asm statements that
567 // might access the operand several times, or that might not
John Thompson56b6eca2010-06-25 00:02:05 +0000568 // access it at all.
John Thompson8e6065a2010-06-24 22:44:13 +0000569 Info.setAllowsMemory();
John Thompson56b6eca2010-06-25 00:02:05 +0000570 Name++; // Skip over 'e'.
John Thompson8e6065a2010-06-24 22:44:13 +0000571 break;
572 case 'Q': // Memory operand that is an offset from a register (it is
Michael J. Spencer20249a12010-10-21 03:16:25 +0000573 // usually better to use `m' or `es' in asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000574 case 'Z': // Memory operand that is an indexed or indirect from a
575 // register (it is usually better to use `m' or `es' in
Michael J. Spencer20249a12010-10-21 03:16:25 +0000576 // asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000577 Info.setAllowsMemory();
578 Info.setAllowsRegister();
579 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000580 case 'R': // AIX TOC entry
John Thompson8e6065a2010-06-24 22:44:13 +0000581 case 'a': // Address operand that is an indexed or indirect from a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000582 // register (`p' is preferable for asm statements)
583 case 'S': // Constant suitable as a 64-bit mask operand
584 case 'T': // Constant suitable as a 32-bit mask operand
585 case 'U': // System V Release 4 small data area reference
John Thompson8e6065a2010-06-24 22:44:13 +0000586 case 't': // AND masks that can be performed by two rldic{l, r}
Michael J. Spencer20249a12010-10-21 03:16:25 +0000587 // instructions
588 case 'W': // Vector constant that does not require memory
589 case 'j': // Vector constant that is all zeros.
John Thompson8e6065a2010-06-24 22:44:13 +0000590 break;
591 // End FIXME.
Anders Carlssond04c6e22007-11-27 04:11:28 +0000592 }
John Thompson8e6065a2010-06-24 22:44:13 +0000593 return true;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000594 }
Eli Friedmane4277982008-08-20 23:11:40 +0000595 virtual const char *getClobbers() const {
596 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000597 }
Eli Friedmane4277982008-08-20 23:11:40 +0000598};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000599
Eli Friedmane4277982008-08-20 23:11:40 +0000600const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +0000601#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
602#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
603 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000604#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmane4277982008-08-20 23:11:40 +0000605};
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000606
607
Chris Lattnerc0f59212009-03-02 22:27:17 +0000608/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
609/// #defines that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000610void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000611 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000612 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +0000613 Builder.defineMacro("__ppc__");
614 Builder.defineMacro("_ARCH_PPC");
Chris Lattnere03ae302010-02-16 18:14:57 +0000615 Builder.defineMacro("__powerpc__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000616 Builder.defineMacro("__POWERPC__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000617 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000618 Builder.defineMacro("_ARCH_PPC64");
619 Builder.defineMacro("_LP64");
620 Builder.defineMacro("__LP64__");
Chris Lattnere03ae302010-02-16 18:14:57 +0000621 Builder.defineMacro("__powerpc64__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000622 Builder.defineMacro("__ppc64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000623 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +0000624 Builder.defineMacro("__ppc__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000625 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000626
Chris Lattnerc0f59212009-03-02 22:27:17 +0000627 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +0000628 Builder.defineMacro("_BIG_ENDIAN");
629 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000630
Chris Lattnerc0f59212009-03-02 22:27:17 +0000631 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +0000632 Builder.defineMacro("__NATURAL_ALIGNMENT__");
633 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000634
Chris Lattnerc0f59212009-03-02 22:27:17 +0000635 // FIXME: Should be controlled by command line option.
Benjamin Kramera9992772010-01-09 17:55:51 +0000636 Builder.defineMacro("__LONG_DOUBLE_128__");
Michael J. Spencer20249a12010-10-21 03:16:25 +0000637
John Thompson3f6918a2009-11-19 17:18:50 +0000638 if (Opts.AltiVec) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000639 Builder.defineMacro("__VEC__", "10206");
640 Builder.defineMacro("__ALTIVEC__");
John Thompson3f6918a2009-11-19 17:18:50 +0000641 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000642}
643
Chris Lattner393ff042008-04-21 18:56:49 +0000644
Eli Friedmane4277982008-08-20 23:11:40 +0000645const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnere94e0d42009-09-16 05:05:27 +0000646 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
647 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
648 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
649 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
650 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
651 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
652 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
653 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmane4277982008-08-20 23:11:40 +0000654 "mq", "lr", "ctr", "ap",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000655 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmane4277982008-08-20 23:11:40 +0000656 "xer",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000657 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
658 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
659 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
660 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmane4277982008-08-20 23:11:40 +0000661 "vrsave", "vscr",
662 "spe_acc", "spefscr",
663 "sfp"
664};
Reid Spencer5f016e22007-07-11 17:01:13 +0000665
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000666void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000667 unsigned &NumNames) const {
668 Names = GCCRegNames;
669 NumNames = llvm::array_lengthof(GCCRegNames);
670}
Reid Spencer5f016e22007-07-11 17:01:13 +0000671
Eli Friedmane4277982008-08-20 23:11:40 +0000672const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
673 // While some of these aliases do map to different registers
674 // they still share the same register name.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000675 { { "0" }, "r0" },
676 { { "1"}, "r1" },
677 { { "2" }, "r2" },
678 { { "3" }, "r3" },
679 { { "4" }, "r4" },
680 { { "5" }, "r5" },
681 { { "6" }, "r6" },
682 { { "7" }, "r7" },
683 { { "8" }, "r8" },
684 { { "9" }, "r9" },
685 { { "10" }, "r10" },
686 { { "11" }, "r11" },
687 { { "12" }, "r12" },
688 { { "13" }, "r13" },
689 { { "14" }, "r14" },
690 { { "15" }, "r15" },
691 { { "16" }, "r16" },
692 { { "17" }, "r17" },
693 { { "18" }, "r18" },
694 { { "19" }, "r19" },
695 { { "20" }, "r20" },
696 { { "21" }, "r21" },
697 { { "22" }, "r22" },
698 { { "23" }, "r23" },
699 { { "24" }, "r24" },
700 { { "25" }, "r25" },
701 { { "26" }, "r26" },
702 { { "27" }, "r27" },
703 { { "28" }, "r28" },
704 { { "29" }, "r29" },
705 { { "30" }, "r30" },
706 { { "31" }, "r31" },
707 { { "fr0" }, "f0" },
708 { { "fr1" }, "f1" },
709 { { "fr2" }, "f2" },
710 { { "fr3" }, "f3" },
711 { { "fr4" }, "f4" },
712 { { "fr5" }, "f5" },
713 { { "fr6" }, "f6" },
714 { { "fr7" }, "f7" },
715 { { "fr8" }, "f8" },
716 { { "fr9" }, "f9" },
Mike Stump10880392009-09-17 21:15:00 +0000717 { { "fr10" }, "f10" },
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000718 { { "fr11" }, "f11" },
719 { { "fr12" }, "f12" },
720 { { "fr13" }, "f13" },
721 { { "fr14" }, "f14" },
722 { { "fr15" }, "f15" },
723 { { "fr16" }, "f16" },
724 { { "fr17" }, "f17" },
725 { { "fr18" }, "f18" },
726 { { "fr19" }, "f19" },
727 { { "fr20" }, "f20" },
728 { { "fr21" }, "f21" },
729 { { "fr22" }, "f22" },
730 { { "fr23" }, "f23" },
731 { { "fr24" }, "f24" },
732 { { "fr25" }, "f25" },
733 { { "fr26" }, "f26" },
734 { { "fr27" }, "f27" },
735 { { "fr28" }, "f28" },
736 { { "fr29" }, "f29" },
737 { { "fr30" }, "f30" },
738 { { "fr31" }, "f31" },
739 { { "cc" }, "cr0" },
Eli Friedmane4277982008-08-20 23:11:40 +0000740};
741
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000742void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000743 unsigned &NumAliases) const {
744 Aliases = GCCRegAliases;
745 NumAliases = llvm::array_lengthof(GCCRegAliases);
746}
747} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000748
749namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000750class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000751public:
Chris Lattnere03ae302010-02-16 18:14:57 +0000752 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedmaned855cb2008-08-21 00:13:15 +0000753 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 +0000754 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnere03ae302010-02-16 18:14:57 +0000755
756 if (getTriple().getOS() == llvm::Triple::FreeBSD)
757 this->SizeType = TargetInfo::UnsignedInt;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000758 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000759};
760} // end anonymous namespace.
761
762namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000763class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000764public:
Eli Friedmane4277982008-08-20 23:11:40 +0000765 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000766 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman3c7b6e42009-07-01 03:36:11 +0000767 IntMaxType = SignedLong;
768 UIntMaxType = UnsignedLong;
769 Int64Type = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000770 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +0000771 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerf291b102008-05-09 06:17:04 +0000772 }
Eli Friedmane4277982008-08-20 23:11:40 +0000773};
774} // end anonymous namespace.
775
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000776
777namespace {
778class DarwinPPCTargetInfo :
779 public DarwinTargetInfo<PPCTargetInfo> {
780public:
781 DarwinPPCTargetInfo(const std::string& triple)
782 : DarwinTargetInfo<PPCTargetInfo>(triple) {
783 HasAlignMac68kSupport = true;
784 }
785};
786
787class DarwinPPC64TargetInfo :
788 public DarwinTargetInfo<PPC64TargetInfo> {
789public:
790 DarwinPPC64TargetInfo(const std::string& triple)
791 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
792 HasAlignMac68kSupport = true;
793 }
794};
795} // end anonymous namespace.
796
Reid Spencer5f016e22007-07-11 17:01:13 +0000797namespace {
Chris Lattner9cbeb632010-03-06 21:21:27 +0000798// MBlaze abstract base class
799class MBlazeTargetInfo : public TargetInfo {
800 static const char * const GCCRegNames[];
801 static const TargetInfo::GCCRegAlias GCCRegAliases[];
802
803public:
804 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
Wesley Pecka48fa4b2010-12-12 20:56:47 +0000805 DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
Chris Lattner9cbeb632010-03-06 21:21:27 +0000806 }
807
808 virtual void getTargetBuiltins(const Builtin::Info *&Records,
809 unsigned &NumRecords) const {
810 // FIXME: Implement.
811 Records = 0;
812 NumRecords = 0;
813 }
814
815 virtual void getTargetDefines(const LangOptions &Opts,
816 MacroBuilder &Builder) const;
817
818 virtual const char *getVAListDeclaration() const {
819 return "typedef char* __builtin_va_list;";
820 }
821 virtual const char *getTargetPrefix() const {
822 return "mblaze";
823 }
824 virtual void getGCCRegNames(const char * const *&Names,
825 unsigned &NumNames) const;
826 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
827 unsigned &NumAliases) const;
828 virtual bool validateAsmConstraint(const char *&Name,
829 TargetInfo::ConstraintInfo &Info) const {
830 switch (*Name) {
831 default: return false;
832 case 'O': // Zero
833 return true;
834 case 'b': // Base register
835 case 'f': // Floating point register
836 Info.setAllowsRegister();
837 return true;
838 }
839 }
840 virtual const char *getClobbers() const {
841 return "";
842 }
843};
844
845/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
846/// #defines that are not tied to a specific subtarget.
847void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
848 MacroBuilder &Builder) const {
849 // Target identification.
850 Builder.defineMacro("__microblaze__");
851 Builder.defineMacro("_ARCH_MICROBLAZE");
852 Builder.defineMacro("__MICROBLAZE__");
853
854 // Target properties.
855 Builder.defineMacro("_BIG_ENDIAN");
856 Builder.defineMacro("__BIG_ENDIAN__");
857
858 // Subtarget options.
859 Builder.defineMacro("__REGISTER_PREFIX__", "");
860}
861
862
863const char * const MBlazeTargetInfo::GCCRegNames[] = {
864 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
865 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
866 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
867 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
868 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
869 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
870 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
871 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
872 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
873 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
874};
875
876void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
877 unsigned &NumNames) const {
878 Names = GCCRegNames;
879 NumNames = llvm::array_lengthof(GCCRegNames);
880}
881
882const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
883 { {"f0"}, "r0" },
884 { {"f1"}, "r1" },
885 { {"f2"}, "r2" },
886 { {"f3"}, "r3" },
887 { {"f4"}, "r4" },
888 { {"f5"}, "r5" },
889 { {"f6"}, "r6" },
890 { {"f7"}, "r7" },
891 { {"f8"}, "r8" },
892 { {"f9"}, "r9" },
893 { {"f10"}, "r10" },
894 { {"f11"}, "r11" },
895 { {"f12"}, "r12" },
896 { {"f13"}, "r13" },
897 { {"f14"}, "r14" },
898 { {"f15"}, "r15" },
899 { {"f16"}, "r16" },
900 { {"f17"}, "r17" },
901 { {"f18"}, "r18" },
902 { {"f19"}, "r19" },
903 { {"f20"}, "r20" },
904 { {"f21"}, "r21" },
905 { {"f22"}, "r22" },
906 { {"f23"}, "r23" },
907 { {"f24"}, "r24" },
908 { {"f25"}, "r25" },
909 { {"f26"}, "r26" },
910 { {"f27"}, "r27" },
911 { {"f28"}, "r28" },
912 { {"f29"}, "r29" },
913 { {"f30"}, "r30" },
914 { {"f31"}, "r31" },
915};
916
917void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
918 unsigned &NumAliases) const {
919 Aliases = GCCRegAliases;
920 NumAliases = llvm::array_lengthof(GCCRegAliases);
921}
922} // end anonymous namespace.
923
924namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000925// Namespace for x86 abstract base class
926const Builtin::Info BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +0000927#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
928#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
929 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000930#include "clang/Basic/BuiltinsX86.def"
Eli Friedman618234a2008-08-20 02:34:37 +0000931};
Eli Friedman61538a72008-05-20 14:21:01 +0000932
Nuno Lopes2550d702009-12-23 17:49:57 +0000933static const char* const GCCRegNames[] = {
Eli Friedman618234a2008-08-20 02:34:37 +0000934 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
935 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
936 "argp", "flags", "fspr", "dirflag", "frame",
937 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
938 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
939 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
940 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
941};
942
943const TargetInfo::GCCRegAlias GCCRegAliases[] = {
944 { { "al", "ah", "eax", "rax" }, "ax" },
945 { { "bl", "bh", "ebx", "rbx" }, "bx" },
946 { { "cl", "ch", "ecx", "rcx" }, "cx" },
947 { { "dl", "dh", "edx", "rdx" }, "dx" },
948 { { "esi", "rsi" }, "si" },
949 { { "edi", "rdi" }, "di" },
950 { { "esp", "rsp" }, "sp" },
951 { { "ebp", "rbp" }, "bp" },
952};
953
954// X86 target abstract base class; x86-32 and x86-64 are very close, so
955// most of the implementation can be shared.
956class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +0000957 enum X86SSEEnum {
958 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
959 } SSELevel;
Anders Carlsson9b0fb622010-01-27 03:47:49 +0000960 enum AMD3DNowEnum {
961 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
962 } AMD3DNowLevel;
963
Eric Christophereea12d12010-04-02 23:50:19 +0000964 bool HasAES;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000965 bool HasAVX;
966
Eli Friedman618234a2008-08-20 02:34:37 +0000967public:
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000968 X86TargetInfo(const std::string& triple)
Eric Christophereea12d12010-04-02 23:50:19 +0000969 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +0000970 HasAES(false), HasAVX(false) {
Eli Friedman618234a2008-08-20 02:34:37 +0000971 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000972 }
973 virtual void getTargetBuiltins(const Builtin::Info *&Records,
974 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000975 Records = BuiltinInfo;
976 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000977 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000978 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000979 unsigned &NumNames) const {
980 Names = GCCRegNames;
981 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000982 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000983 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson3346ae62007-11-24 23:38:12 +0000984 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000985 Aliases = GCCRegAliases;
986 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000987 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000988 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000989 TargetInfo::ConstraintInfo &info) const;
Dale Johannesenf6e2c202010-10-29 23:12:32 +0000990 virtual const llvm::Type* adjustInlineAsmType(std::string& Constraint,
991 const llvm::Type* Ty,
992 llvm::LLVMContext& Context) const;
Eli Friedman618234a2008-08-20 02:34:37 +0000993 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000994 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000995 return "~{dirflag},~{fpsr},~{flags}";
996 }
Chris Lattner33328642009-03-20 15:52:06 +0000997 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000998 MacroBuilder &Builder) const;
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000999 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1000 const std::string &Name,
1001 bool Enabled) const;
Mike Stump1eb44332009-09-09 15:08:12 +00001002 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001003 llvm::StringMap<bool> &Features) const;
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001004 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Reid Spencer5f016e22007-07-11 17:01:13 +00001005};
Chris Lattner3daed522009-03-02 22:20:04 +00001006
Mike Stump1eb44332009-09-09 15:08:12 +00001007void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001008 llvm::StringMap<bool> &Features) const {
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001009 // FIXME: This should not be here.
1010 Features["3dnow"] = false;
1011 Features["3dnowa"] = false;
1012 Features["mmx"] = false;
1013 Features["sse"] = false;
1014 Features["sse2"] = false;
1015 Features["sse3"] = false;
1016 Features["ssse3"] = false;
1017 Features["sse41"] = false;
1018 Features["sse42"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001019 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001020 Features["avx"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001021
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001022 // LLVM does not currently recognize this.
1023 // Features["sse4a"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001024
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001025 // FIXME: This *really* should not be here.
1026
1027 // X86_64 always has SSE2.
1028 if (PointerWidth == 64)
1029 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
1030
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001031 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
1032 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
1033 ;
1034 else if (CPU == "pentium-mmx" || CPU == "pentium2")
1035 setFeatureEnabled(Features, "mmx", true);
1036 else if (CPU == "pentium3")
1037 setFeatureEnabled(Features, "sse", true);
1038 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
1039 setFeatureEnabled(Features, "sse2", true);
1040 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
1041 setFeatureEnabled(Features, "sse3", true);
1042 else if (CPU == "core2")
1043 setFeatureEnabled(Features, "ssse3", true);
1044 else if (CPU == "penryn") {
1045 setFeatureEnabled(Features, "sse4", true);
1046 Features["sse42"] = false;
1047 } else if (CPU == "atom")
1048 setFeatureEnabled(Features, "sse3", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001049 else if (CPU == "corei7") {
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001050 setFeatureEnabled(Features, "sse4", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001051 setFeatureEnabled(Features, "aes", true);
1052 }
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001053 else if (CPU == "k6" || CPU == "winchip-c6")
1054 setFeatureEnabled(Features, "mmx", true);
Mike Stump1eb44332009-09-09 15:08:12 +00001055 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001056 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
1057 setFeatureEnabled(Features, "mmx", true);
1058 setFeatureEnabled(Features, "3dnow", true);
1059 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
1060 setFeatureEnabled(Features, "sse", true);
1061 setFeatureEnabled(Features, "3dnowa", true);
1062 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
1063 CPU == "athlon-fx") {
Mike Stump1eb44332009-09-09 15:08:12 +00001064 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001065 setFeatureEnabled(Features, "3dnowa", true);
Roman Divackyc8b09a12010-12-29 13:28:29 +00001066 } else if (CPU == "k8-sse3") {
1067 setFeatureEnabled(Features, "sse3", true);
1068 setFeatureEnabled(Features, "3dnowa", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001069 } else if (CPU == "c3-2")
1070 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001071}
1072
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001073bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump1eb44332009-09-09 15:08:12 +00001074 const std::string &Name,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001075 bool Enabled) const {
Eric Christopherd39ebe22010-03-04 02:26:37 +00001076 // FIXME: This *really* should not be here. We need some way of translating
1077 // options into llvm subtarget features.
1078 if (!Features.count(Name) &&
1079 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001080 return false;
1081
1082 if (Enabled) {
1083 if (Name == "mmx")
1084 Features["mmx"] = true;
1085 else if (Name == "sse")
1086 Features["mmx"] = Features["sse"] = true;
1087 else if (Name == "sse2")
1088 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
1089 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001090 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001091 Features["sse3"] = true;
1092 else if (Name == "ssse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001093 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001094 Features["ssse3"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001095 else if (Name == "sse4" || Name == "sse4.2")
Mike Stump1eb44332009-09-09 15:08:12 +00001096 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001097 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001098 else if (Name == "sse4.1")
1099 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
1100 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001101 else if (Name == "3dnow")
1102 Features["3dnowa"] = true;
1103 else if (Name == "3dnowa")
1104 Features["3dnow"] = Features["3dnowa"] = true;
Eric Christophereea12d12010-04-02 23:50:19 +00001105 else if (Name == "aes")
1106 Features["aes"] = true;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001107 else if (Name == "avx")
1108 Features["avx"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001109 } else {
1110 if (Name == "mmx")
Mike Stump1eb44332009-09-09 15:08:12 +00001111 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001112 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1113 else if (Name == "sse")
Mike Stump1eb44332009-09-09 15:08:12 +00001114 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001115 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1116 else if (Name == "sse2")
Mike Stump1eb44332009-09-09 15:08:12 +00001117 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001118 Features["sse41"] = Features["sse42"] = false;
1119 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001120 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001121 Features["sse42"] = false;
1122 else if (Name == "ssse3")
1123 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
1124 else if (Name == "sse4")
1125 Features["sse41"] = Features["sse42"] = false;
Eric Christopherd41b4ec2010-03-04 02:31:44 +00001126 else if (Name == "sse4.2")
1127 Features["sse42"] = false;
1128 else if (Name == "sse4.1")
1129 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001130 else if (Name == "3dnow")
1131 Features["3dnow"] = Features["3dnowa"] = false;
1132 else if (Name == "3dnowa")
1133 Features["3dnowa"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001134 else if (Name == "aes")
1135 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001136 else if (Name == "avx")
1137 Features["avx"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001138 }
1139
1140 return true;
1141}
1142
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001143/// HandleTargetOptions - Perform initialization based on the user
1144/// configured set of features.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001145void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001146 // Remember the maximum enabled sselevel.
1147 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
1148 // Ignore disabled features.
1149 if (Features[i][0] == '-')
1150 continue;
1151
Eric Christophereea12d12010-04-02 23:50:19 +00001152 if (Features[i].substr(1) == "aes") {
1153 HasAES = true;
1154 continue;
1155 }
1156
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001157 // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
1158 // For now let it be enabled together with other SSE levels.
1159 if (Features[i].substr(1) == "avx") {
1160 HasAVX = true;
1161 continue;
1162 }
1163
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001164 assert(Features[i][0] == '+' && "Invalid target feature!");
1165 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
1166 .Case("sse42", SSE42)
1167 .Case("sse41", SSE41)
1168 .Case("ssse3", SSSE3)
Nuno Lopes33d3bca2010-03-12 10:20:09 +00001169 .Case("sse3", SSE3)
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001170 .Case("sse2", SSE2)
1171 .Case("sse", SSE1)
1172 .Case("mmx", MMX)
1173 .Default(NoMMXSSE);
1174 SSELevel = std::max(SSELevel, Level);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001175
1176 AMD3DNowEnum ThreeDNowLevel =
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001177 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
1178 .Case("3dnowa", AMD3DNowAthlon)
1179 .Case("3dnow", AMD3DNow)
1180 .Default(NoAMD3DNow);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001181
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001182 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001183 }
Chris Lattner3daed522009-03-02 22:20:04 +00001184}
Chris Lattnerc0f59212009-03-02 22:27:17 +00001185
1186/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
1187/// that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +00001188void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001189 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001190 // Target identification.
1191 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001192 Builder.defineMacro("_LP64");
1193 Builder.defineMacro("__LP64__");
1194 Builder.defineMacro("__amd64__");
1195 Builder.defineMacro("__amd64");
1196 Builder.defineMacro("__x86_64");
1197 Builder.defineMacro("__x86_64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +00001198 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +00001199 DefineStd(Builder, "i386", Opts);
Chris Lattnerc0f59212009-03-02 22:27:17 +00001200 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001201
Eric Christophereea12d12010-04-02 23:50:19 +00001202 if (HasAES)
1203 Builder.defineMacro("__AES__");
1204
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001205 if (HasAVX)
1206 Builder.defineMacro("__AVX__");
1207
Chris Lattnerc0f59212009-03-02 22:27:17 +00001208 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001209 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001210
Chris Lattnerc0f59212009-03-02 22:27:17 +00001211 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +00001212 Builder.defineMacro("__nocona");
1213 Builder.defineMacro("__nocona__");
1214 Builder.defineMacro("__tune_nocona__");
1215 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001216
Chris Lattner54175442009-04-19 17:32:33 +00001217 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
1218 // functions in glibc header files that use FP Stack inline asm which the
1219 // backend can't deal with (PR879).
Benjamin Kramera9992772010-01-09 17:55:51 +00001220 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001221
Chris Lattner84f0ea82009-03-02 22:40:39 +00001222 // Each case falls through to the previous one here.
1223 switch (SSELevel) {
1224 case SSE42:
Benjamin Kramera9992772010-01-09 17:55:51 +00001225 Builder.defineMacro("__SSE4_2__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001226 case SSE41:
Benjamin Kramera9992772010-01-09 17:55:51 +00001227 Builder.defineMacro("__SSE4_1__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001228 case SSSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001229 Builder.defineMacro("__SSSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001230 case SSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001231 Builder.defineMacro("__SSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001232 case SSE2:
Benjamin Kramera9992772010-01-09 17:55:51 +00001233 Builder.defineMacro("__SSE2__");
1234 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001235 case SSE1:
Benjamin Kramera9992772010-01-09 17:55:51 +00001236 Builder.defineMacro("__SSE__");
1237 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001238 case MMX:
Benjamin Kramera9992772010-01-09 17:55:51 +00001239 Builder.defineMacro("__MMX__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001240 case NoMMXSSE:
1241 break;
1242 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001243
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001244 if (Opts.Microsoft && PointerWidth == 32) {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001245 switch (SSELevel) {
Michael J. Spencera764e832010-10-21 08:22:51 +00001246 case SSE42:
1247 case SSE41:
1248 case SSSE3:
1249 case SSE3:
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001250 case SSE2:
1251 Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
1252 break;
1253 case SSE1:
1254 Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
1255 break;
1256 default:
1257 Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
1258 }
1259 }
1260
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001261 // Each case falls through to the previous one here.
1262 switch (AMD3DNowLevel) {
1263 case AMD3DNowAthlon:
1264 Builder.defineMacro("__3dNOW_A__");
1265 case AMD3DNow:
1266 Builder.defineMacro("__3dNOW__");
1267 case NoAMD3DNow:
1268 break;
1269 }
Chris Lattnerc0f59212009-03-02 22:27:17 +00001270}
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001271
1272
Eli Friedman618234a2008-08-20 02:34:37 +00001273bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001274X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001275 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001276 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +00001277 default: return false;
Dale Johannesen545be512010-08-24 22:33:12 +00001278 case 'Y': // first letter of a pair:
1279 switch (*(Name+1)) {
1280 default: return false;
1281 case '0': // First SSE register.
1282 case 't': // Any SSE register, when SSE2 is enabled.
1283 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1284 case 'm': // any MMX register, when inter-unit moves enabled.
1285 break; // falls through to setAllowsRegister.
1286 }
Eli Friedman618234a2008-08-20 02:34:37 +00001287 case 'a': // eax.
1288 case 'b': // ebx.
1289 case 'c': // ecx.
1290 case 'd': // edx.
1291 case 'S': // esi.
1292 case 'D': // edi.
1293 case 'A': // edx:eax.
Dale Johannesen545be512010-08-24 22:33:12 +00001294 case 'f': // any x87 floating point stack register.
Eli Friedman618234a2008-08-20 02:34:37 +00001295 case 't': // top of floating point stack.
1296 case 'u': // second from top of floating point stack.
1297 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +00001298 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +00001299 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +00001300 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Dale Johannesen545be512010-08-24 22:33:12 +00001301 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1302 case 'l': // "Index" registers: any general register that can be used as an
1303 // index in a base+index memory access.
1304 Info.setAllowsRegister();
1305 return true;
1306 case 'C': // SSE floating point constant.
1307 case 'G': // x87 floating point constant.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001308 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001309 // x86_64 instructions.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001310 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001311 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +00001312 return true;
1313 }
Dale Johannesen545be512010-08-24 22:33:12 +00001314 return false;
Eli Friedman618234a2008-08-20 02:34:37 +00001315}
1316
Dale Johannesenf6e2c202010-10-29 23:12:32 +00001317const llvm::Type*
1318X86TargetInfo::adjustInlineAsmType(std::string& Constraint,
1319 const llvm::Type* Ty,
1320 llvm::LLVMContext &Context) const {
1321 if (Constraint=="y" && Ty->isVectorTy())
1322 return llvm::Type::getX86_MMXTy(Context);
1323 return Ty;
1324}
1325
1326
Eli Friedman618234a2008-08-20 02:34:37 +00001327std::string
1328X86TargetInfo::convertConstraint(const char Constraint) const {
1329 switch (Constraint) {
1330 case 'a': return std::string("{ax}");
1331 case 'b': return std::string("{bx}");
1332 case 'c': return std::string("{cx}");
1333 case 'd': return std::string("{dx}");
1334 case 'S': return std::string("{si}");
1335 case 'D': return std::string("{di}");
Dale Johannesencee55012010-10-22 21:07:10 +00001336 case 'p': // address
1337 return std::string("im");
Eli Friedman618234a2008-08-20 02:34:37 +00001338 case 't': // top of floating point stack.
1339 return std::string("{st}");
1340 case 'u': // second from top of floating point stack.
1341 return std::string("{st(1)}"); // second from top of floating point stack.
1342 default:
1343 return std::string(1, Constraint);
1344 }
1345}
Eli Friedman618234a2008-08-20 02:34:37 +00001346} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +00001347
1348namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001349// X86-32 generic target
1350class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +00001351public:
Eli Friedman618234a2008-08-20 02:34:37 +00001352 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
1353 DoubleAlign = LongLongAlign = 32;
1354 LongDoubleWidth = 96;
1355 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001356 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1357 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001358 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman1afabd92009-03-29 20:31:09 +00001359 SizeType = UnsignedInt;
1360 PtrDiffType = SignedInt;
1361 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001362 RegParmMax = 3;
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001363
1364 // Use fpret for all types.
1365 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
1366 (1 << TargetInfo::Double) |
1367 (1 << TargetInfo::LongDouble));
Eli Friedman618234a2008-08-20 02:34:37 +00001368 }
1369 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001370 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +00001371 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001372
Chris Lattner21fb98e2009-09-23 06:06:36 +00001373 int getEHDataRegisterNumber(unsigned RegNo) const {
1374 if (RegNo == 0) return 0;
1375 if (RegNo == 1) return 2;
1376 return -1;
1377 }
Eli Friedman618234a2008-08-20 02:34:37 +00001378};
1379} // end anonymous namespace
1380
1381namespace {
Eli Friedman624c1462009-07-05 18:47:56 +00001382class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
1383public:
1384 OpenBSDI386TargetInfo(const std::string& triple) :
1385 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
1386 SizeType = UnsignedLong;
1387 IntPtrType = SignedLong;
Eli Friedman6036ebe2009-07-05 22:31:18 +00001388 PtrDiffType = SignedLong;
Eli Friedman624c1462009-07-05 18:47:56 +00001389 }
1390};
1391} // end anonymous namespace
1392
1393namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +00001394class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman618234a2008-08-20 02:34:37 +00001395public:
Torok Edwin5f6c1942009-06-30 17:10:35 +00001396 DarwinI386TargetInfo(const std::string& triple) :
1397 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman618234a2008-08-20 02:34:37 +00001398 LongDoubleWidth = 128;
1399 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +00001400 SizeType = UnsignedLong;
1401 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001402 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1403 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001404 "a0:0:64-f80:128:128-n8:16:32";
Daniel Dunbar613fd672010-05-27 00:35:16 +00001405 HasAlignMac68kSupport = true;
Torok Edwinb0a5b242009-06-30 17:00:25 +00001406 }
1407
Eli Friedman618234a2008-08-20 02:34:37 +00001408};
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001409} // end anonymous namespace
1410
1411namespace {
Eli Friedman29a30502008-08-21 01:40:19 +00001412// x86-32 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001413class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
Eli Friedman29a30502008-08-21 01:40:19 +00001414public:
1415 WindowsX86_32TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001416 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +00001417 TLSSupported = false;
Chris Lattner85de9e72009-06-24 17:12:15 +00001418 WCharType = UnsignedShort;
Eli Friedman9c2f84e2009-06-08 21:16:17 +00001419 DoubleAlign = LongLongAlign = 64;
1420 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 +00001421 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1422 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedman29a30502008-08-21 01:40:19 +00001423 }
Michael J. Spencera764e832010-10-21 08:22:51 +00001424 virtual void getTargetDefines(const LangOptions &Opts,
1425 MacroBuilder &Builder) const {
1426 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
1427 }
1428};
1429} // end anonymous namespace
1430
1431namespace {
1432
1433// x86-32 Windows Visual Studio target
1434class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1435public:
1436 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1437 : WindowsX86_32TargetInfo(triple) {
1438 LongDoubleWidth = 64;
1439 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1440 }
1441 virtual void getTargetDefines(const LangOptions &Opts,
1442 MacroBuilder &Builder) const {
1443 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1444 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
1445 // The value of the following reflects processor type.
1446 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1447 // We lost the original triple, so we use the default.
1448 Builder.defineMacro("_M_IX86", "600");
1449 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001450};
1451} // end anonymous namespace
1452
1453namespace {
1454// x86-32 MinGW target
1455class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1456public:
1457 MinGWX86_32TargetInfo(const std::string& triple)
1458 : WindowsX86_32TargetInfo(triple) {
1459 }
1460 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001461 MacroBuilder &Builder) const {
1462 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001463 DefineStd(Builder, "WIN32", Opts);
1464 DefineStd(Builder, "WINNT", Opts);
1465 Builder.defineMacro("_X86_");
Benjamin Kramera9992772010-01-09 17:55:51 +00001466 Builder.defineMacro("__MSVCRT__");
1467 Builder.defineMacro("__MINGW32__");
1468 Builder.defineMacro("__declspec", "__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001469 }
1470};
1471} // end anonymous namespace
1472
1473namespace {
1474// x86-32 Cygwin target
1475class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1476public:
1477 CygwinX86_32TargetInfo(const std::string& triple)
1478 : X86_32TargetInfo(triple) {
1479 TLSSupported = false;
1480 WCharType = UnsignedShort;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001481 DoubleAlign = LongLongAlign = 64;
1482 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1483 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001484 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001485 }
1486 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001487 MacroBuilder &Builder) const {
1488 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1489 Builder.defineMacro("__CYGWIN__");
1490 Builder.defineMacro("__CYGWIN32__");
1491 DefineStd(Builder, "unix", Opts);
Douglas Gregor2b003fd2010-04-21 05:52:38 +00001492 if (Opts.CPlusPlus)
1493 Builder.defineMacro("_GNU_SOURCE");
Eli Friedmanabc4e322009-06-08 06:11:14 +00001494 }
Eli Friedman29a30502008-08-21 01:40:19 +00001495};
1496} // end anonymous namespace
1497
1498namespace {
Chris Lattner86ed3a32010-04-11 19:29:39 +00001499// x86-32 Haiku target
1500class HaikuX86_32TargetInfo : public X86_32TargetInfo {
1501public:
1502 HaikuX86_32TargetInfo(const std::string& triple)
1503 : X86_32TargetInfo(triple) {
1504 SizeType = UnsignedLong;
Chris Lattnerfe1ea7b2010-04-22 17:48:00 +00001505 IntPtrType = SignedLong;
1506 PtrDiffType = SignedLong;
Rafael Espindola19ddda82010-11-09 16:41:02 +00001507 this->UserLabelPrefix = "";
Eli Friedmana7e68452010-08-22 01:00:03 +00001508 }
Chris Lattner86ed3a32010-04-11 19:29:39 +00001509 virtual void getTargetDefines(const LangOptions &Opts,
1510 MacroBuilder &Builder) const {
1511 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1512 Builder.defineMacro("__INTEL__");
1513 Builder.defineMacro("__HAIKU__");
1514 }
1515};
1516} // end anonymous namespace
1517
1518namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001519// x86-64 generic target
1520class X86_64TargetInfo : public X86TargetInfo {
1521public:
Chris Lattner33328642009-03-20 15:52:06 +00001522 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +00001523 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +00001524 LongDoubleWidth = 128;
1525 LongDoubleAlign = 128;
Rafael Espindola6deecb02010-06-04 23:15:27 +00001526 LargeArrayMinWidth = 128;
1527 LargeArrayAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +00001528 IntMaxType = SignedLong;
1529 UIntMaxType = UnsignedLong;
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001530 Int64Type = SignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001531 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +00001532
Eli Friedmaned855cb2008-08-21 00:13:15 +00001533 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1534 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001535 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001536
1537 // Use fpret only for long double.
1538 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
Reid Spencer5f016e22007-07-11 17:01:13 +00001539 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +00001540 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001541 return "typedef struct __va_list_tag {"
1542 " unsigned gp_offset;"
1543 " unsigned fp_offset;"
1544 " void* overflow_arg_area;"
1545 " void* reg_save_area;"
John McCall2b7baf02010-05-28 18:25:28 +00001546 "} __va_list_tag;"
Eli Friedmandc043162009-07-03 00:45:06 +00001547 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +00001548 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001549
Chris Lattner21fb98e2009-09-23 06:06:36 +00001550 int getEHDataRegisterNumber(unsigned RegNo) const {
1551 if (RegNo == 0) return 0;
1552 if (RegNo == 1) return 1;
1553 return -1;
1554 }
Eli Friedman618234a2008-08-20 02:34:37 +00001555};
1556} // end anonymous namespace
1557
1558namespace {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001559// x86-64 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001560class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001561public:
1562 WindowsX86_64TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001563 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001564 TLSSupported = false;
1565 WCharType = UnsignedShort;
Mike Stumpa55cce82009-10-08 23:00:00 +00001566 LongWidth = LongAlign = 32;
Michael J. Spencer237cf582010-10-18 07:10:59 +00001567 DoubleAlign = LongLongAlign = 64;
Nate Begemandbf8ea42010-07-21 02:02:56 +00001568 IntMaxType = SignedLongLong;
1569 UIntMaxType = UnsignedLongLong;
1570 Int64Type = SignedLongLong;
Cameron Esfahani1484e0d2010-09-15 00:28:12 +00001571 SizeType = UnsignedLongLong;
1572 PtrDiffType = SignedLongLong;
1573 IntPtrType = SignedLongLong;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001574 }
1575 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001576 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001577 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001578 Builder.defineMacro("_WIN64");
Michael J. Spencera764e832010-10-21 08:22:51 +00001579 }
1580};
1581} // end anonymous namespace
1582
1583namespace {
1584// x86-64 Windows Visual Studio target
1585class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1586public:
1587 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1588 : WindowsX86_64TargetInfo(triple) {
1589 }
1590 virtual void getTargetDefines(const LangOptions &Opts,
1591 MacroBuilder &Builder) const {
1592 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1593 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
Benjamin Kramera9992772010-01-09 17:55:51 +00001594 Builder.defineMacro("_M_X64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001595 Builder.defineMacro("_M_AMD64");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001596 }
Chris Lattnerf13721d2010-08-31 16:44:54 +00001597 virtual const char *getVAListDeclaration() const {
1598 return "typedef char* __builtin_va_list;";
1599 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001600};
1601} // end anonymous namespace
1602
1603namespace {
1604// x86-64 MinGW target
1605class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1606public:
1607 MinGWX86_64TargetInfo(const std::string& triple)
1608 : WindowsX86_64TargetInfo(triple) {
1609 }
1610 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001611 MacroBuilder &Builder) const {
1612 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001613 DefineStd(Builder, "WIN64", Opts);
Benjamin Kramera9992772010-01-09 17:55:51 +00001614 Builder.defineMacro("__MSVCRT__");
1615 Builder.defineMacro("__MINGW64__");
1616 Builder.defineMacro("__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001617 }
1618};
1619} // end anonymous namespace
1620
1621namespace {
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001622class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1623public:
Mike Stump1eb44332009-09-09 15:08:12 +00001624 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001625 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1626 Int64Type = SignedLongLong;
1627 }
1628};
1629} // end anonymous namespace
1630
1631namespace {
Eli Friedman6036ebe2009-07-05 22:31:18 +00001632class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1633public:
Mike Stump1eb44332009-09-09 15:08:12 +00001634 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman6036ebe2009-07-05 22:31:18 +00001635 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1636 IntMaxType = SignedLongLong;
1637 UIntMaxType = UnsignedLongLong;
1638 Int64Type = SignedLongLong;
1639 }
1640};
1641} // end anonymous namespace
1642
1643namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +00001644class ARMTargetInfo : public TargetInfo {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001645 // Possible FPU choices.
1646 enum FPUMode {
1647 NoFPU,
1648 VFP2FPU,
1649 VFP3FPU,
1650 NeonFPU
1651 };
1652
1653 static bool FPUModeIsVFP(FPUMode Mode) {
1654 return Mode >= VFP2FPU && Mode <= NeonFPU;
1655 }
1656
1657 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1658 static const char * const GCCRegNames[];
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001659
Daniel Dunbareac7c532009-12-18 18:42:37 +00001660 std::string ABI, CPU;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001661
1662 unsigned FPU : 3;
1663
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001664 unsigned IsThumb : 1;
1665
1666 // Initialized via features.
1667 unsigned SoftFloat : 1;
1668 unsigned SoftFloatABI : 1;
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001669
Chris Lattner2752c012010-03-03 19:03:45 +00001670 static const Builtin::Info BuiltinInfo[];
1671
Chris Lattner393ff042008-04-21 18:56:49 +00001672public:
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001673 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbareac7c532009-12-18 18:42:37 +00001674 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001675 {
Daniel Dunbara2a41612009-09-14 00:02:24 +00001676 SizeType = UnsignedInt;
1677 PtrDiffType = SignedInt;
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001678
Chris Lattner9bffb072010-04-23 16:29:58 +00001679 // {} in inline assembly are neon specifiers, not assembly variant
1680 // specifiers.
1681 NoAsmVariants = true;
Michael J. Spencer20249a12010-10-21 03:16:25 +00001682
Daniel Dunbareac7c532009-12-18 18:42:37 +00001683 // FIXME: Should we just treat this as a feature?
Daniel Dunbar0791aa52009-12-18 19:57:13 +00001684 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001685 if (IsThumb) {
1686 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1687 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001688 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001689 } else {
1690 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1691 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001692 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001693 }
John McCallee79a4c2010-08-21 22:46:04 +00001694
1695 // ARM targets default to using the ARM C++ ABI.
1696 CXXABI = CXXABI_ARM;
Eli Friedman61538a72008-05-20 14:21:01 +00001697 }
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001698 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbara2a41612009-09-14 00:02:24 +00001699 virtual bool setABI(const std::string &Name) {
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001700 ABI = Name;
1701
Daniel Dunbara2a41612009-09-14 00:02:24 +00001702 // The defaults (above) are for AAPCS, check if we need to change them.
1703 //
1704 // FIXME: We need support for -meabi... we could just mangle it into the
1705 // name.
1706 if (Name == "apcs-gnu") {
Daniel Dunbard410fa22010-01-27 20:23:08 +00001707 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbara2a41612009-09-14 00:02:24 +00001708 SizeType = UnsignedLong;
1709
Daniel Dunbar684de632010-04-22 16:14:54 +00001710 // Do not respect the alignment of bit-field types when laying out
1711 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
1712 UseBitFieldTypeAlignment = false;
1713
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001714 if (IsThumb) {
1715 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1716 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001717 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001718 } else {
1719 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1720 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001721 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001722 }
1723
Daniel Dunbara2a41612009-09-14 00:02:24 +00001724 // FIXME: Override "preferred align" for double and long long.
1725 } else if (Name == "aapcs") {
1726 // FIXME: Enumerated types are variable width in straight AAPCS.
1727 } else if (Name == "aapcs-linux") {
1728 ;
1729 } else
1730 return false;
1731
1732 return true;
1733 }
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001734
Daniel Dunbara91320b2009-12-21 23:28:17 +00001735 void getDefaultFeatures(const std::string &CPU,
1736 llvm::StringMap<bool> &Features) const {
1737 // FIXME: This should not be here.
1738 Features["vfp2"] = false;
1739 Features["vfp3"] = false;
1740 Features["neon"] = false;
1741
1742 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1743 Features["vfp2"] = true;
1744 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1745 Features["neon"] = true;
1746 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001747
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001748 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1749 const std::string &Name,
1750 bool Enabled) const {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001751 if (Name == "soft-float" || Name == "soft-float-abi") {
1752 Features[Name] = Enabled;
1753 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1754 // These effectively are a single option, reset them when any is enabled.
1755 if (Enabled)
1756 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1757 Features[Name] = Enabled;
1758 } else
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001759 return false;
1760
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001761 return true;
1762 }
1763
1764 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001765 FPU = NoFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001766 SoftFloat = SoftFloatABI = false;
1767 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1768 if (Features[i] == "+soft-float")
1769 SoftFloat = true;
1770 else if (Features[i] == "+soft-float-abi")
1771 SoftFloatABI = true;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001772 else if (Features[i] == "+vfp2")
1773 FPU = VFP2FPU;
1774 else if (Features[i] == "+vfp3")
1775 FPU = VFP3FPU;
1776 else if (Features[i] == "+neon")
1777 FPU = NeonFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001778 }
1779
1780 // Remove front-end specific options which the backend handles differently.
1781 std::vector<std::string>::iterator it;
1782 it = std::find(Features.begin(), Features.end(), "+soft-float");
1783 if (it != Features.end())
1784 Features.erase(it);
1785 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1786 if (it != Features.end())
1787 Features.erase(it);
1788 }
1789
Daniel Dunbareac7c532009-12-18 18:42:37 +00001790 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1791 return llvm::StringSwitch<const char*>(Name)
1792 .Cases("arm8", "arm810", "4")
1793 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1794 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1795 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1796 .Case("ep9312", "4T")
1797 .Cases("arm10tdmi", "arm1020t", "5T")
1798 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1799 .Case("arm926ej-s", "5TEJ")
1800 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1801 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001802 .Case("arm1136j-s", "6J")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001803 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001804 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001805 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1806 .Cases("cortex-a8", "cortex-a9", "7A")
1807 .Default(0);
1808 }
1809 virtual bool setCPU(const std::string &Name) {
1810 if (!getCPUDefineSuffix(Name))
1811 return false;
1812
1813 CPU = Name;
1814 return true;
1815 }
Chris Lattner33328642009-03-20 15:52:06 +00001816 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001817 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001818 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +00001819 Builder.defineMacro("__arm");
1820 Builder.defineMacro("__arm__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001821
Chris Lattnerc0f59212009-03-02 22:27:17 +00001822 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001823 Builder.defineMacro("__ARMEL__");
1824 Builder.defineMacro("__LITTLE_ENDIAN__");
1825 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001826
1827 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramera9992772010-01-09 17:55:51 +00001828 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001829
Mike Stump437bb4b2009-04-08 02:07:04 +00001830 // Subtarget options.
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001831
Daniel Dunbareac7c532009-12-18 18:42:37 +00001832 // FIXME: It's more complicated than this and we don't really support
1833 // interworking.
1834 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramera9992772010-01-09 17:55:51 +00001835 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001836
Daniel Dunbareac7c532009-12-18 18:42:37 +00001837 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramera9992772010-01-09 17:55:51 +00001838 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001839
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001840 if (SoftFloat)
Benjamin Kramera9992772010-01-09 17:55:51 +00001841 Builder.defineMacro("__SOFTFP__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001842
1843 if (CPU == "xscale")
Benjamin Kramera9992772010-01-09 17:55:51 +00001844 Builder.defineMacro("__XSCALE__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001845
Daniel Dunbara91320b2009-12-21 23:28:17 +00001846 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001847 if (IsThumb) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001848 Builder.defineMacro("__THUMBEL__");
1849 Builder.defineMacro("__thumb__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001850 if (IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001851 Builder.defineMacro("__thumb2__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001852 }
1853
1854 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramera9992772010-01-09 17:55:51 +00001855 Builder.defineMacro("__APCS_32__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001856
1857 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramera9992772010-01-09 17:55:51 +00001858 Builder.defineMacro("__VFP_FP__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001859
1860 // This only gets set when Neon instructions are actually available, unlike
1861 // the VFP define, hence the soft float and arch check. This is subtly
1862 // different from gcc, we follow the intent which was that it should be set
1863 // when Neon instructions are actually available.
1864 if (FPU == NeonFPU && !SoftFloat && IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001865 Builder.defineMacro("__ARM_NEON__");
Chris Lattner393ff042008-04-21 18:56:49 +00001866 }
1867 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1868 unsigned &NumRecords) const {
Chris Lattner2752c012010-03-03 19:03:45 +00001869 Records = BuiltinInfo;
1870 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner393ff042008-04-21 18:56:49 +00001871 }
1872 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001873 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +00001874 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001875 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001876 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001877 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001878 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001879 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001880 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001881 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001882 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +00001883 default:
Nate Begemanad487f42008-04-22 05:03:19 +00001884 case 'l': // r0-r7
1885 case 'h': // r8-r15
1886 case 'w': // VFP Floating point register single precision
1887 case 'P': // VFP Floating point register double precision
Chris Lattner44def072009-04-26 07:16:29 +00001888 Info.setAllowsRegister();
Nate Begemanad487f42008-04-22 05:03:19 +00001889 return true;
1890 }
Chris Lattner393ff042008-04-21 18:56:49 +00001891 return false;
1892 }
1893 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001894 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +00001895 return "";
1896 }
1897};
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001898
1899const char * const ARMTargetInfo::GCCRegNames[] = {
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001900 // Integer registers
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001901 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001902 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
1903
1904 // Float registers
1905 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1906 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
1907 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001908 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00001909
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001910 // Double registers
1911 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
1912 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
Dale Johannesend1455352010-10-28 01:05:37 +00001913 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
1914 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001915
1916 // Quad registers
Dale Johannesend1455352010-10-28 01:05:37 +00001917 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
1918 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001919};
1920
1921void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001922 unsigned &NumNames) const {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001923 Names = GCCRegNames;
1924 NumNames = llvm::array_lengthof(GCCRegNames);
1925}
1926
1927const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001928 { { "a1" }, "r0" },
1929 { { "a2" }, "r1" },
1930 { { "a3" }, "r2" },
1931 { { "a4" }, "r3" },
1932 { { "v1" }, "r4" },
1933 { { "v2" }, "r5" },
1934 { { "v3" }, "r6" },
1935 { { "v4" }, "r7" },
1936 { { "v5" }, "r8" },
1937 { { "v6", "rfp" }, "r9" },
1938 { { "sl" }, "r10" },
1939 { { "fp" }, "r11" },
1940 { { "ip" }, "r12" },
Daniel Dunbar1fd71712010-08-11 02:17:11 +00001941 { { "r13" }, "sp" },
1942 { { "r14" }, "lr" },
1943 { { "r15" }, "pc" },
Dale Johannesen20eb49b2010-10-27 23:34:42 +00001944 // The S, D and Q registers overlap, but aren't really aliases; we
1945 // don't want to substitute one of these for a different-sized one.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001946};
1947
1948void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1949 unsigned &NumAliases) const {
1950 Aliases = GCCRegAliases;
1951 NumAliases = llvm::array_lengthof(GCCRegAliases);
1952}
Chris Lattner2752c012010-03-03 19:03:45 +00001953
1954const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +00001955#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
1956#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1957 ALL_LANGUAGES, false },
Chris Lattner2752c012010-03-03 19:03:45 +00001958#include "clang/Basic/BuiltinsARM.def"
1959};
Chris Lattner393ff042008-04-21 18:56:49 +00001960} // end anonymous namespace.
1961
Eli Friedmana9f54962008-08-20 07:44:10 +00001962
1963namespace {
Mike Stump1eb44332009-09-09 15:08:12 +00001964class DarwinARMTargetInfo :
Torok Edwin5f6c1942009-06-30 17:10:35 +00001965 public DarwinTargetInfo<ARMTargetInfo> {
1966protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +00001967 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +00001968 MacroBuilder &Builder) const {
Daniel Dunbar21ae3192010-01-26 01:44:04 +00001969 getDarwinDefines(Builder, Opts, Triple);
Eli Friedmanb030f022009-04-19 21:38:35 +00001970 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001971
Torok Edwin5f6c1942009-06-30 17:10:35 +00001972public:
Mike Stump1eb44332009-09-09 15:08:12 +00001973 DarwinARMTargetInfo(const std::string& triple)
Daniel Dunbar350b9f32010-05-27 07:00:26 +00001974 : DarwinTargetInfo<ARMTargetInfo>(triple) {
1975 HasAlignMac68kSupport = true;
1976 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001977};
1978} // end anonymous namespace.
1979
Reid Spencer5f016e22007-07-11 17:01:13 +00001980namespace {
Eli Friedman01b86682008-08-20 07:28:14 +00001981class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +00001982 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1983 static const char * const GCCRegNames[];
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00001984 bool SoftFloat;
Gabor Greif26658672008-02-21 16:29:08 +00001985public:
Eli Friedman01b86682008-08-20 07:28:14 +00001986 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1987 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +00001988 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 +00001989 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedman01b86682008-08-20 07:28:14 +00001990 }
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00001991 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1992 const std::string &Name,
1993 bool Enabled) const {
1994 if (Name == "soft-float")
1995 Features[Name] = Enabled;
1996 else
1997 return false;
1998
1999 return true;
2000 }
2001 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
2002 SoftFloat = false;
2003 for (unsigned i = 0, e = Features.size(); i != e; ++i)
2004 if (Features[i] == "+soft-float")
2005 SoftFloat = true;
2006 }
Chris Lattner33328642009-03-20 15:52:06 +00002007 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002008 MacroBuilder &Builder) const {
2009 DefineStd(Builder, "sparc", Opts);
2010 Builder.defineMacro("__sparcv8");
2011 Builder.defineMacro("__REGISTER_PREFIX__", "");
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002012
2013 if (SoftFloat)
2014 Builder.defineMacro("SOFT_FLOAT", "1");
Gabor Greif26658672008-02-21 16:29:08 +00002015 }
2016 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2017 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002018 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +00002019 }
2020 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002021 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +00002022 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002023 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002024 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002025 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002026 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00002027 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +00002028 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002029 // FIXME: Implement!
2030 return false;
Gabor Greif26658672008-02-21 16:29:08 +00002031 }
2032 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002033 // FIXME: Implement!
2034 return "";
Gabor Greif26658672008-02-21 16:29:08 +00002035 }
2036};
2037
Chris Lattnere957f532009-01-27 01:58:38 +00002038const char * const SparcV8TargetInfo::GCCRegNames[] = {
2039 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2040 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2041 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2042 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
2043};
2044
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002045void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002046 unsigned &NumNames) const {
2047 Names = GCCRegNames;
2048 NumNames = llvm::array_lengthof(GCCRegNames);
2049}
2050
2051const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002052 { { "g0" }, "r0" },
2053 { { "g1" }, "r1" },
2054 { { "g2" }, "r2" },
2055 { { "g3" }, "r3" },
2056 { { "g4" }, "r4" },
2057 { { "g5" }, "r5" },
2058 { { "g6" }, "r6" },
2059 { { "g7" }, "r7" },
2060 { { "o0" }, "r8" },
2061 { { "o1" }, "r9" },
2062 { { "o2" }, "r10" },
2063 { { "o3" }, "r11" },
2064 { { "o4" }, "r12" },
2065 { { "o5" }, "r13" },
2066 { { "o6", "sp" }, "r14" },
2067 { { "o7" }, "r15" },
2068 { { "l0" }, "r16" },
2069 { { "l1" }, "r17" },
2070 { { "l2" }, "r18" },
2071 { { "l3" }, "r19" },
2072 { { "l4" }, "r20" },
2073 { { "l5" }, "r21" },
2074 { { "l6" }, "r22" },
2075 { { "l7" }, "r23" },
2076 { { "i0" }, "r24" },
2077 { { "i1" }, "r25" },
2078 { { "i2" }, "r26" },
2079 { { "i3" }, "r27" },
2080 { { "i4" }, "r28" },
2081 { { "i5" }, "r29" },
2082 { { "i6", "fp" }, "r30" },
2083 { { "i7" }, "r31" },
Chris Lattnere957f532009-01-27 01:58:38 +00002084};
2085
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002086void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002087 unsigned &NumAliases) const {
2088 Aliases = GCCRegAliases;
2089 NumAliases = llvm::array_lengthof(GCCRegAliases);
2090}
Gabor Greif26658672008-02-21 16:29:08 +00002091} // end anonymous namespace.
2092
Eli Friedman01b86682008-08-20 07:28:14 +00002093namespace {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002094class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
2095public:
2096 AuroraUXSparcV8TargetInfo(const std::string& triple) :
2097 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
2098 SizeType = UnsignedInt;
2099 PtrDiffType = SignedInt;
2100 }
2101};
Torok Edwin5f6c1942009-06-30 17:10:35 +00002102class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedman01b86682008-08-20 07:28:14 +00002103public:
2104 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwin5f6c1942009-06-30 17:10:35 +00002105 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmanf509d732008-11-02 02:43:55 +00002106 SizeType = UnsignedInt;
2107 PtrDiffType = SignedInt;
Eli Friedman01b86682008-08-20 07:28:14 +00002108 }
2109};
2110} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00002111
Chris Lattner2621fd12008-05-08 05:58:21 +00002112namespace {
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002113 class MSP430TargetInfo : public TargetInfo {
2114 static const char * const GCCRegNames[];
2115 public:
2116 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
2117 TLSSupported = false;
Anton Korobeynikov09f52a62010-01-30 12:55:11 +00002118 IntWidth = 16; IntAlign = 16;
2119 LongWidth = 32; LongLongWidth = 64;
2120 LongAlign = LongLongAlign = 16;
2121 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002122 SizeType = UnsignedInt;
2123 IntMaxType = SignedLong;
2124 UIntMaxType = UnsignedLong;
2125 IntPtrType = SignedShort;
2126 PtrDiffType = SignedInt;
Edward O'Callaghan9cf910e2009-11-21 00:49:54 +00002127 SigAtomicType = SignedLong;
Anton Korobeynikov5d7c2512009-12-19 01:32:37 +00002128 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002129 }
2130 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002131 MacroBuilder &Builder) const {
2132 Builder.defineMacro("MSP430");
2133 Builder.defineMacro("__MSP430__");
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002134 // FIXME: defines for different 'flavours' of MCU
2135 }
2136 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2137 unsigned &NumRecords) const {
2138 // FIXME: Implement.
2139 Records = 0;
2140 NumRecords = 0;
2141 }
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002142 virtual void getGCCRegNames(const char * const *&Names,
2143 unsigned &NumNames) const;
2144 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2145 unsigned &NumAliases) const {
2146 // No aliases.
2147 Aliases = 0;
2148 NumAliases = 0;
2149 }
2150 virtual bool validateAsmConstraint(const char *&Name,
2151 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov03265b62009-10-15 23:17:13 +00002152 // No target constraints for now.
2153 return false;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002154 }
2155 virtual const char *getClobbers() const {
2156 // FIXME: Is this really right?
2157 return "";
2158 }
2159 virtual const char *getVAListDeclaration() const {
2160 // FIXME: implement
Anton Korobeynikoveb716852009-05-08 18:24:57 +00002161 return "typedef char* __builtin_va_list;";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002162 }
2163 };
2164
2165 const char * const MSP430TargetInfo::GCCRegNames[] = {
2166 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2167 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2168 };
2169
2170 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
2171 unsigned &NumNames) const {
2172 Names = GCCRegNames;
2173 NumNames = llvm::array_lengthof(GCCRegNames);
2174 }
2175}
2176
2177
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002178namespace {
2179 class SystemZTargetInfo : public TargetInfo {
2180 static const char * const GCCRegNames[];
2181 public:
2182 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
2183 TLSSupported = false;
2184 IntWidth = IntAlign = 32;
2185 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
2186 PointerWidth = PointerAlign = 64;
Chris Lattner1932e122009-11-07 18:59:41 +00002187 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
2188 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002189 }
2190 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002191 MacroBuilder &Builder) const {
2192 Builder.defineMacro("__s390__");
2193 Builder.defineMacro("__s390x__");
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002194 }
2195 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2196 unsigned &NumRecords) const {
2197 // FIXME: Implement.
2198 Records = 0;
2199 NumRecords = 0;
2200 }
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002201
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002202 virtual void getGCCRegNames(const char * const *&Names,
2203 unsigned &NumNames) const;
2204 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2205 unsigned &NumAliases) const {
2206 // No aliases.
2207 Aliases = 0;
2208 NumAliases = 0;
2209 }
2210 virtual bool validateAsmConstraint(const char *&Name,
2211 TargetInfo::ConstraintInfo &info) const {
2212 // FIXME: implement
2213 return true;
2214 }
2215 virtual const char *getClobbers() const {
2216 // FIXME: Is this really right?
2217 return "";
2218 }
2219 virtual const char *getVAListDeclaration() const {
2220 // FIXME: implement
2221 return "typedef char* __builtin_va_list;";
2222 }
2223 };
2224
2225 const char * const SystemZTargetInfo::GCCRegNames[] = {
2226 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2227 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2228 };
2229
2230 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
2231 unsigned &NumNames) const {
2232 Names = GCCRegNames;
2233 NumNames = llvm::array_lengthof(GCCRegNames);
2234 }
2235}
2236
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002237namespace {
2238 class BlackfinTargetInfo : public TargetInfo {
2239 static const char * const GCCRegNames[];
2240 public:
2241 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
2242 TLSSupported = false;
2243 DoubleAlign = 32;
2244 LongLongAlign = 32;
2245 LongDoubleAlign = 32;
Chris Lattner1932e122009-11-07 18:59:41 +00002246 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002247 }
2248
2249 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002250 MacroBuilder &Builder) const {
2251 DefineStd(Builder, "bfin", Opts);
2252 DefineStd(Builder, "BFIN", Opts);
2253 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002254 // FIXME: This one is really dependent on -mcpu
Benjamin Kramera9992772010-01-09 17:55:51 +00002255 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002256 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
2257 }
2258
2259 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2260 unsigned &NumRecords) const {
2261 // FIXME: Implement.
2262 Records = 0;
2263 NumRecords = 0;
2264 }
2265
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002266 virtual void getGCCRegNames(const char * const *&Names,
2267 unsigned &NumNames) const;
2268
2269 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2270 unsigned &NumAliases) const {
2271 // No aliases.
2272 Aliases = 0;
2273 NumAliases = 0;
2274 }
2275
2276 virtual bool validateAsmConstraint(const char *&Name,
2277 TargetInfo::ConstraintInfo &Info) const {
2278 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
2279 Info.setAllowsRegister();
2280 return true;
2281 }
2282 return false;
2283 }
2284
2285 virtual const char *getClobbers() const {
2286 return "";
2287 }
2288
2289 virtual const char *getVAListDeclaration() const {
2290 return "typedef char* __builtin_va_list;";
2291 }
2292 };
2293
2294 const char * const BlackfinTargetInfo::GCCRegNames[] = {
2295 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2296 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
2297 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
2298 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
2299 "a0", "a1", "cc",
2300 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
2301 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
2302 };
2303
2304 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
2305 unsigned &NumNames) const {
2306 Names = GCCRegNames;
2307 NumNames = llvm::array_lengthof(GCCRegNames);
2308 }
2309}
2310
Eli Friedmanb63decf2009-08-19 20:47:07 +00002311namespace {
2312
Mike Stump1eb44332009-09-09 15:08:12 +00002313 // LLVM and Clang cannot be used directly to output native binaries for
2314 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmanb63decf2009-08-19 20:47:07 +00002315 // type and alignment information.
Mike Stump1eb44332009-09-09 15:08:12 +00002316 //
2317 // TCE uses the llvm bitcode as input and uses it for generating customized
2318 // target processor and program binary. TCE co-design environment is
Eli Friedmanb63decf2009-08-19 20:47:07 +00002319 // publicly available in http://tce.cs.tut.fi
2320
2321 class TCETargetInfo : public TargetInfo{
2322 public:
2323 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
2324 TLSSupported = false;
2325 IntWidth = 32;
2326 LongWidth = LongLongWidth = 32;
Eli Friedmanb63decf2009-08-19 20:47:07 +00002327 PointerWidth = 32;
2328 IntAlign = 32;
2329 LongAlign = LongLongAlign = 32;
2330 PointerAlign = 32;
2331 SizeType = UnsignedInt;
2332 IntMaxType = SignedLong;
2333 UIntMaxType = UnsignedLong;
2334 IntPtrType = SignedInt;
2335 PtrDiffType = SignedInt;
2336 FloatWidth = 32;
2337 FloatAlign = 32;
2338 DoubleWidth = 32;
2339 DoubleAlign = 32;
2340 LongDoubleWidth = 32;
2341 LongDoubleAlign = 32;
2342 FloatFormat = &llvm::APFloat::IEEEsingle;
2343 DoubleFormat = &llvm::APFloat::IEEEsingle;
2344 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner3a47c4e2010-03-04 21:07:38 +00002345 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
2346 "i16:16:32-i32:32:32-i64:32:32-"
2347 "f32:32:32-f64:64:64-v64:64:64-"
2348 "v128:128:128-a0:0:64-n32";
Eli Friedmanb63decf2009-08-19 20:47:07 +00002349 }
2350
2351 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002352 MacroBuilder &Builder) const {
2353 DefineStd(Builder, "tce", Opts);
2354 Builder.defineMacro("__TCE__");
2355 Builder.defineMacro("__TCE_V1__");
Eli Friedmanb63decf2009-08-19 20:47:07 +00002356 }
2357 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2358 unsigned &NumRecords) const {}
Daniel Dunbar55cc2ed2009-08-24 09:54:37 +00002359 virtual const char *getClobbers() const {
2360 return "";
2361 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002362 virtual const char *getVAListDeclaration() const {
2363 return "typedef void* __builtin_va_list;";
2364 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002365 virtual void getGCCRegNames(const char * const *&Names,
2366 unsigned &NumNames) const {}
2367 virtual bool validateAsmConstraint(const char *&Name,
2368 TargetInfo::ConstraintInfo &info) const {
2369 return true;
2370 }
2371 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2372 unsigned &NumAliases) const {}
2373 };
2374}
2375
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002376namespace {
2377class MipsTargetInfo : public TargetInfo {
Eric Christophered734732010-03-02 02:41:08 +00002378 std::string ABI, CPU;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002379 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2380 static const char * const GCCRegNames[];
2381public:
Eric Christophered734732010-03-02 02:41:08 +00002382 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002383 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2384 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2385 }
Eric Christophered734732010-03-02 02:41:08 +00002386 virtual const char *getABI() const { return ABI.c_str(); }
2387 virtual bool setABI(const std::string &Name) {
2388
2389 if ((Name == "o32") || (Name == "eabi")) {
2390 ABI = Name;
2391 return true;
2392 } else
2393 return false;
2394 }
2395 virtual bool setCPU(const std::string &Name) {
2396 CPU = Name;
2397 return true;
2398 }
2399 void getDefaultFeatures(const std::string &CPU,
2400 llvm::StringMap<bool> &Features) const {
2401 Features[ABI] = true;
2402 Features[CPU] = true;
2403 }
2404 virtual void getArchDefines(const LangOptions &Opts,
2405 MacroBuilder &Builder) const {
2406 if (ABI == "o32")
2407 Builder.defineMacro("__mips_o32");
2408 else if (ABI == "eabi")
2409 Builder.defineMacro("__mips_eabi");
2410 }
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002411 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002412 MacroBuilder &Builder) const {
2413 DefineStd(Builder, "mips", Opts);
2414 Builder.defineMacro("_mips");
2415 DefineStd(Builder, "MIPSEB", Opts);
2416 Builder.defineMacro("_MIPSEB");
2417 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002418 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002419 }
2420 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2421 unsigned &NumRecords) const {
2422 // FIXME: Implement!
2423 }
2424 virtual const char *getVAListDeclaration() const {
2425 return "typedef void* __builtin_va_list;";
2426 }
2427 virtual void getGCCRegNames(const char * const *&Names,
2428 unsigned &NumNames) const;
2429 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2430 unsigned &NumAliases) const;
2431 virtual bool validateAsmConstraint(const char *&Name,
2432 TargetInfo::ConstraintInfo &Info) const {
2433 switch (*Name) {
2434 default:
2435 case 'r': // CPU registers.
2436 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2437 case 'y': // Equivalent to "r", backwards compatibility only.
2438 case 'f': // floating-point registers.
2439 Info.setAllowsRegister();
2440 return true;
2441 }
2442 return false;
2443 }
2444
2445 virtual const char *getClobbers() const {
2446 // FIXME: Implement!
2447 return "";
2448 }
2449};
2450
2451const char * const MipsTargetInfo::GCCRegNames[] = {
Michael J. Spencer20249a12010-10-21 03:16:25 +00002452 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002453 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2454 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2455 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2456 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2457 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2458 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2459 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2460 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2461 "$fcc5","$fcc6","$fcc7"
2462};
2463
2464void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2465 unsigned &NumNames) const {
2466 Names = GCCRegNames;
2467 NumNames = llvm::array_lengthof(GCCRegNames);
2468}
2469
2470const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2471 { { "at" }, "$1" },
2472 { { "v0" }, "$2" },
2473 { { "v1" }, "$3" },
2474 { { "a0" }, "$4" },
2475 { { "a1" }, "$5" },
2476 { { "a2" }, "$6" },
2477 { { "a3" }, "$7" },
2478 { { "t0" }, "$8" },
2479 { { "t1" }, "$9" },
2480 { { "t2" }, "$10" },
2481 { { "t3" }, "$11" },
2482 { { "t4" }, "$12" },
2483 { { "t5" }, "$13" },
2484 { { "t6" }, "$14" },
2485 { { "t7" }, "$15" },
2486 { { "s0" }, "$16" },
2487 { { "s1" }, "$17" },
2488 { { "s2" }, "$18" },
2489 { { "s3" }, "$19" },
2490 { { "s4" }, "$20" },
2491 { { "s5" }, "$21" },
2492 { { "s6" }, "$22" },
2493 { { "s7" }, "$23" },
2494 { { "t8" }, "$24" },
2495 { { "t9" }, "$25" },
2496 { { "k0" }, "$26" },
2497 { { "k1" }, "$27" },
2498 { { "gp" }, "$28" },
2499 { { "sp" }, "$29" },
2500 { { "fp" }, "$30" },
2501 { { "ra" }, "$31" }
2502};
2503
2504void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2505 unsigned &NumAliases) const {
2506 Aliases = GCCRegAliases;
2507 NumAliases = llvm::array_lengthof(GCCRegAliases);
2508}
2509} // end anonymous namespace.
2510
2511namespace {
2512class MipselTargetInfo : public MipsTargetInfo {
2513public:
2514 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2515 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2516 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2517 }
2518
2519 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002520 MacroBuilder &Builder) const;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002521};
2522
2523void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002524 MacroBuilder &Builder) const {
2525 DefineStd(Builder, "mips", Opts);
2526 Builder.defineMacro("_mips");
2527 DefineStd(Builder, "MIPSEL", Opts);
2528 Builder.defineMacro("_MIPSEL");
2529 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002530 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002531}
2532} // end anonymous namespace.
2533
Reid Spencer5f016e22007-07-11 17:01:13 +00002534//===----------------------------------------------------------------------===//
2535// Driver code
2536//===----------------------------------------------------------------------===//
2537
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002538static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002539 llvm::Triple Triple(T);
2540 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman61538a72008-05-20 14:21:01 +00002541
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002542 switch (Triple.getArch()) {
2543 default:
2544 return NULL;
Eli Friedman61538a72008-05-20 14:21:01 +00002545
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002546 case llvm::Triple::arm:
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +00002547 case llvm::Triple::thumb:
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002548 switch (os) {
Rafael Espindola022a8a52010-06-10 00:46:51 +00002549 case llvm::Triple::Linux:
2550 return new LinuxTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002551 case llvm::Triple::Darwin:
Eli Friedmaned855cb2008-08-21 00:13:15 +00002552 return new DarwinARMTargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002553 case llvm::Triple::FreeBSD:
Torok Edwin5f6c1942009-06-30 17:10:35 +00002554 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002555 default:
2556 return new ARMTargetInfo(T);
2557 }
Eli Friedman61538a72008-05-20 14:21:01 +00002558
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002559 case llvm::Triple::bfin:
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002560 return new BlackfinTargetInfo(T);
2561
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002562 case llvm::Triple::msp430:
2563 return new MSP430TargetInfo(T);
Eli Friedman61538a72008-05-20 14:21:01 +00002564
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002565 case llvm::Triple::mips:
2566 if (os == llvm::Triple::Psp)
2567 return new PSPTargetInfo<MipsTargetInfo>(T);
2568 if (os == llvm::Triple::Linux)
2569 return new LinuxTargetInfo<MipsTargetInfo>(T);
2570 return new MipsTargetInfo(T);
2571
2572 case llvm::Triple::mipsel:
2573 if (os == llvm::Triple::Psp)
2574 return new PSPTargetInfo<MipselTargetInfo>(T);
2575 if (os == llvm::Triple::Linux)
2576 return new LinuxTargetInfo<MipselTargetInfo>(T);
2577 return new MipselTargetInfo(T);
2578
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002579 case llvm::Triple::ppc:
2580 if (os == llvm::Triple::Darwin)
Daniel Dunbar4c6a2262010-05-30 00:07:30 +00002581 return new DarwinPPCTargetInfo(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002582 else if (os == llvm::Triple::FreeBSD)
2583 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002584 return new PPC32TargetInfo(T);
2585
2586 case llvm::Triple::ppc64:
2587 if (os == llvm::Triple::Darwin)
Daniel Dunbar4c6a2262010-05-30 00:07:30 +00002588 return new DarwinPPC64TargetInfo(T);
John Thompson3f6918a2009-11-19 17:18:50 +00002589 else if (os == llvm::Triple::Lv2)
2590 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002591 else if (os == llvm::Triple::FreeBSD)
2592 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002593 return new PPC64TargetInfo(T);
2594
Chris Lattner9cbeb632010-03-06 21:21:27 +00002595 case llvm::Triple::mblaze:
2596 return new MBlazeTargetInfo(T);
2597
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002598 case llvm::Triple::sparc:
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002599 if (os == llvm::Triple::AuroraUX)
2600 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002601 if (os == llvm::Triple::Solaris)
2602 return new SolarisSparcV8TargetInfo(T);
2603 return new SparcV8TargetInfo(T);
2604
John Thompson3f6918a2009-11-19 17:18:50 +00002605 // FIXME: Need a real SPU target.
2606 case llvm::Triple::cellspu:
2607 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2608
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002609 case llvm::Triple::systemz:
2610 return new SystemZTargetInfo(T);
2611
Eli Friedmanb63decf2009-08-19 20:47:07 +00002612 case llvm::Triple::tce:
2613 return new TCETargetInfo(T);
2614
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002615 case llvm::Triple::x86:
2616 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002617 case llvm::Triple::AuroraUX:
2618 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002619 case llvm::Triple::Darwin:
2620 return new DarwinI386TargetInfo(T);
2621 case llvm::Triple::Linux:
2622 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2623 case llvm::Triple::DragonFly:
2624 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2625 case llvm::Triple::NetBSD:
2626 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2627 case llvm::Triple::OpenBSD:
2628 return new OpenBSDI386TargetInfo(T);
2629 case llvm::Triple::FreeBSD:
2630 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
Chris Lattner38e317d2010-07-07 16:01:42 +00002631 case llvm::Triple::Minix:
2632 return new MinixTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002633 case llvm::Triple::Solaris:
2634 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2635 case llvm::Triple::Cygwin:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002636 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002637 case llvm::Triple::MinGW32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002638 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002639 case llvm::Triple::Win32:
Michael J. Spencera764e832010-10-21 08:22:51 +00002640 return new VisualStudioWindowsX86_32TargetInfo(T);
Chris Lattner86ed3a32010-04-11 19:29:39 +00002641 case llvm::Triple::Haiku:
2642 return new HaikuX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002643 default:
2644 return new X86_32TargetInfo(T);
2645 }
2646
2647 case llvm::Triple::x86_64:
2648 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002649 case llvm::Triple::AuroraUX:
2650 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002651 case llvm::Triple::Darwin:
2652 return new DarwinX86_64TargetInfo(T);
2653 case llvm::Triple::Linux:
2654 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner7a7ca282010-01-09 05:41:14 +00002655 case llvm::Triple::DragonFly:
2656 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002657 case llvm::Triple::NetBSD:
2658 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2659 case llvm::Triple::OpenBSD:
2660 return new OpenBSDX86_64TargetInfo(T);
2661 case llvm::Triple::FreeBSD:
2662 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2663 case llvm::Triple::Solaris:
2664 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002665 case llvm::Triple::MinGW64:
2666 return new MinGWX86_64TargetInfo(T);
2667 case llvm::Triple::Win32: // This is what Triple.h supports now.
Michael J. Spencera764e832010-10-21 08:22:51 +00002668 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002669 default:
2670 return new X86_64TargetInfo(T);
2671 }
2672 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002673}
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002674
2675/// CreateTargetInfo - Return the target info object for the specified target
2676/// triple.
2677TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002678 TargetOptions &Opts) {
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002679 llvm::Triple Triple(Opts.Triple);
2680
2681 // Construct the target
2682 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2683 if (!Target) {
2684 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2685 return 0;
2686 }
2687
Daniel Dunbareac7c532009-12-18 18:42:37 +00002688 // Set the target CPU if specified.
2689 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2690 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2691 return 0;
2692 }
2693
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002694 // Set the target ABI if specified.
2695 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2696 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2697 return 0;
2698 }
2699
Charles Davis98b7c5c2010-06-11 01:06:47 +00002700 // Set the target C++ ABI.
John McCallee79a4c2010-08-21 22:46:04 +00002701 if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Charles Davis98b7c5c2010-06-11 01:06:47 +00002702 Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
2703 return 0;
2704 }
2705
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002706 // Compute the default target features, we need the target to handle this
2707 // because features may have dependencies on one another.
2708 llvm::StringMap<bool> Features;
2709 Target->getDefaultFeatures(Opts.CPU, Features);
2710
2711 // Apply the user specified deltas.
2712 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2713 ie = Opts.Features.end(); it != ie; ++it) {
2714 const char *Name = it->c_str();
2715
2716 // Apply the feature via the target.
2717 if ((Name[0] != '-' && Name[0] != '+') ||
2718 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2719 Diags.Report(diag::err_target_invalid_feature) << Name;
2720 return 0;
2721 }
2722 }
2723
2724 // Add the features to the compile options.
2725 //
2726 // FIXME: If we are completely confident that we have the right set, we only
2727 // need to pass the minuses.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002728 Opts.Features.clear();
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002729 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2730 ie = Features.end(); it != ie; ++it)
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002731 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2732 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002733
2734 return Target.take();
2735}