blob: ea076ae0bbfc0d0f6e961fd7b431b6edcb775c2f [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"
Benjamin Kramer48725082010-01-09 18:20:57 +000029#include <algorithm>
Reid Spencer5f016e22007-07-11 17:01:13 +000030using namespace clang;
31
Reid Spencer5f016e22007-07-11 17:01:13 +000032//===----------------------------------------------------------------------===//
33// Common code shared among targets.
34//===----------------------------------------------------------------------===//
35
Chris Lattnerca45cff2009-03-20 16:06:38 +000036/// DefineStd - Define a macro name and standard variants. For example if
37/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
38/// when in GNU mode.
Benjamin Kramera9992772010-01-09 17:55:51 +000039static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
Chris Lattnerca45cff2009-03-20 16:06:38 +000040 const LangOptions &Opts) {
41 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000042
Chris Lattnerca45cff2009-03-20 16:06:38 +000043 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
44 // in the user's namespace.
45 if (Opts.GNUMode)
Benjamin Kramera9992772010-01-09 17:55:51 +000046 Builder.defineMacro(MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000047
Chris Lattnerca45cff2009-03-20 16:06:38 +000048 // Define __unix.
Benjamin Kramera9992772010-01-09 17:55:51 +000049 Builder.defineMacro("__" + MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000050
Chris Lattnerca45cff2009-03-20 16:06:38 +000051 // Define __unix__.
Benjamin Kramera9992772010-01-09 17:55:51 +000052 Builder.defineMacro("__" + MacroName + "__");
Chris Lattnerca45cff2009-03-20 16:06:38 +000053}
54
Chris Lattnerd29b6302008-10-05 21:50:58 +000055//===----------------------------------------------------------------------===//
56// Defines specific to certain operating systems.
57//===----------------------------------------------------------------------===//
Chris Lattner797c3c42009-08-10 19:03:04 +000058
Torok Edwin5f6c1942009-06-30 17:10:35 +000059namespace {
Douglas Gregora3844922009-07-01 15:12:53 +000060template<typename TgtInfo>
61class OSTargetInfo : public TgtInfo {
Torok Edwin5f6c1942009-06-30 17:10:35 +000062protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +000063 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +000064 MacroBuilder &Builder) const=0;
Torok Edwin5f6c1942009-06-30 17:10:35 +000065public:
Douglas Gregora3844922009-07-01 15:12:53 +000066 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwin5f6c1942009-06-30 17:10:35 +000067 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +000068 MacroBuilder &Builder) const {
69 TgtInfo::getTargetDefines(Opts, Builder);
70 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
Torok Edwinb0a5b242009-06-30 17:00:25 +000071 }
Torok Edwin5f6c1942009-06-30 17:10:35 +000072
73};
Chris Lattner4c28b1c2009-08-12 06:24:27 +000074} // end anonymous namespace
Torok Edwinb0a5b242009-06-30 17:00:25 +000075
Chris Lattner797c3c42009-08-10 19:03:04 +000076
Benjamin Kramera9992772010-01-09 17:55:51 +000077static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts) {
78 Builder.defineMacro("__APPLE_CC__", "5621");
79 Builder.defineMacro("__APPLE__");
80 Builder.defineMacro("__MACH__");
81 Builder.defineMacro("OBJC_NEW_PROPERTIES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000082
Chris Lattner10d24272009-04-07 16:50:40 +000083 // __weak is always defined, for use in blocks and with objc pointers.
Benjamin Kramera9992772010-01-09 17:55:51 +000084 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000085
Chris Lattner10d24272009-04-07 16:50:40 +000086 // Darwin defines __strong even in C mode (just to nothing).
87 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Benjamin Kramera9992772010-01-09 17:55:51 +000088 Builder.defineMacro("__strong", "");
Chris Lattner10d24272009-04-07 16:50:40 +000089 else
Benjamin Kramera9992772010-01-09 17:55:51 +000090 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
Eli Friedman2de4fee2009-06-04 23:00:29 +000091
92 if (Opts.Static)
Benjamin Kramera9992772010-01-09 17:55:51 +000093 Builder.defineMacro("__STATIC__");
Eli Friedman2de4fee2009-06-04 23:00:29 +000094 else
Benjamin Kramera9992772010-01-09 17:55:51 +000095 Builder.defineMacro("__DYNAMIC__");
Daniel Dunbar5345c392009-09-03 04:54:28 +000096
97 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +000098 Builder.defineMacro("_REENTRANT");
Daniel Dunbar8d33cd72009-04-10 19:52:24 +000099}
100
Benjamin Kramera9992772010-01-09 17:55:51 +0000101static void getDarwinOSXDefines(MacroBuilder &Builder,
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000102 const llvm::Triple &Triple) {
103 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner4c28b1c2009-08-12 06:24:27 +0000104 return;
Mike Stump1eb44332009-09-09 15:08:12 +0000105
Chris Lattner8b30c412008-09-30 01:00:25 +0000106 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000107 unsigned Maj, Min, Rev;
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000108 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump1eb44332009-09-09 15:08:12 +0000109
Chris Lattner4c28b1c2009-08-12 06:24:27 +0000110 char MacOSXStr[] = "1000";
111 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
112 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
113 MacOSXStr[2] = '0' + Maj-4;
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000114 }
Chris Lattner4c28b1c2009-08-12 06:24:27 +0000115
116 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
117 // Cap 10.4.11 -> darwin8.11 -> "1049"
118 MacOSXStr[3] = std::min(Min, 9U)+'0';
Benjamin Kramera9992772010-01-09 17:55:51 +0000119 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
120 MacOSXStr);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000121}
122
Benjamin Kramera9992772010-01-09 17:55:51 +0000123static void getDarwinIPhoneOSDefines(MacroBuilder &Builder,
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000124 const llvm::Triple &Triple) {
125 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner4c28b1c2009-08-12 06:24:27 +0000126 return;
Mike Stump1eb44332009-09-09 15:08:12 +0000127
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000128 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
129 unsigned Maj, Min, Rev;
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000130 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump1eb44332009-09-09 15:08:12 +0000131
Chris Lattner4c28b1c2009-08-12 06:24:27 +0000132 // When targetting iPhone OS, interpret the minor version and
133 // revision as the iPhone OS version
134 char iPhoneOSStr[] = "10000";
135 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
136 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
137 iPhoneOSStr[0] = '0' + Min;
Chris Lattner8b30c412008-09-30 01:00:25 +0000138 }
Chris Lattner4c28b1c2009-08-12 06:24:27 +0000139
140 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
141 iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
Benjamin Kramera9992772010-01-09 17:55:51 +0000142 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
143 iPhoneOSStr);
Eli Friedman618234a2008-08-20 02:34:37 +0000144}
Reid Spencer5f016e22007-07-11 17:01:13 +0000145
Chris Lattner797c3c42009-08-10 19:03:04 +0000146namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000147template<typename Target>
148class DarwinTargetInfo : public OSTargetInfo<Target> {
149protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000150 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000151 MacroBuilder &Builder) const {
152 getDarwinDefines(Builder, Opts);
153 getDarwinOSXDefines(Builder, Triple);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000154 }
Mike Stump1eb44332009-09-09 15:08:12 +0000155
Torok Edwin5f6c1942009-06-30 17:10:35 +0000156public:
157 DarwinTargetInfo(const std::string& triple) :
158 OSTargetInfo<Target>(triple) {
159 this->TLSSupported = false;
160 }
161
Torok Edwin5f6c1942009-06-30 17:10:35 +0000162 virtual const char *getUnicodeStringSection() const {
163 return "__TEXT,__ustring";
164 }
Mike Stump1eb44332009-09-09 15:08:12 +0000165
Chris Lattner797c3c42009-08-10 19:03:04 +0000166 virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
167 // Let MCSectionMachO validate this.
168 llvm::StringRef Segment, Section;
169 unsigned TAA, StubSize;
170 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
171 TAA, StubSize);
172 }
Torok Edwin5f6c1942009-06-30 17:10:35 +0000173};
174
Chris Lattner797c3c42009-08-10 19:03:04 +0000175
Torok Edwin5f6c1942009-06-30 17:10:35 +0000176// DragonFlyBSD Target
177template<typename Target>
178class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
179protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000180 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000181 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000182 // DragonFly defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000183 Builder.defineMacro("__DragonFly__");
184 Builder.defineMacro("__DragonFly_cc_version", "100001");
185 Builder.defineMacro("__ELF__");
186 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
187 Builder.defineMacro("__tune_i386__");
188 DefineStd(Builder, "unix", Opts);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000189 }
190public:
Mike Stump1eb44332009-09-09 15:08:12 +0000191 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000192 : OSTargetInfo<Target>(triple) {}
193};
194
195// FreeBSD Target
196template<typename Target>
197class FreeBSDTargetInfo : public OSTargetInfo<Target> {
198protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000199 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000200 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000201 // FreeBSD defines; list based off of gcc output
202
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000203 // FIXME: Move version number handling to llvm::Triple.
204 const char *FreeBSD = strstr(Triple.getTriple().c_str(),
205 "-freebsd");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000206 FreeBSD += strlen("-freebsd");
207 char release[] = "X";
208 release[0] = FreeBSD[0];
209 char version[] = "X00001";
210 version[0] = FreeBSD[0];
211
Benjamin Kramera9992772010-01-09 17:55:51 +0000212 Builder.defineMacro("__FreeBSD__", release);
213 Builder.defineMacro("__FreeBSD_cc_version", version);
214 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
215 DefineStd(Builder, "unix", Opts);
216 Builder.defineMacro("__ELF__");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000217 }
218public:
Mike Stump1eb44332009-09-09 15:08:12 +0000219 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands1e90faf2009-07-08 13:55:08 +0000220 : OSTargetInfo<Target>(triple) {
221 this->UserLabelPrefix = "";
222 }
Torok Edwin5f6c1942009-06-30 17:10:35 +0000223};
224
225// Linux target
226template<typename Target>
227class LinuxTargetInfo : public OSTargetInfo<Target> {
228protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000229 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000230 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000231 // Linux defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000232 DefineStd(Builder, "unix", Opts);
233 DefineStd(Builder, "linux", Opts);
234 Builder.defineMacro("__gnu_linux__");
235 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000236 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000237 Builder.defineMacro("_REENTRANT");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000238 }
239public:
Mike Stump1eb44332009-09-09 15:08:12 +0000240 LinuxTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000241 : OSTargetInfo<Target>(triple) {
242 this->UserLabelPrefix = "";
243 }
244};
245
Chris Lattnerb62bb282009-07-13 20:29:08 +0000246// NetBSD Target
247template<typename Target>
248class NetBSDTargetInfo : public OSTargetInfo<Target> {
249protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000250 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000251 MacroBuilder &Builder) const {
Chris Lattnerb62bb282009-07-13 20:29:08 +0000252 // NetBSD defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000253 Builder.defineMacro("__NetBSD__");
254 Builder.defineMacro("__unix__");
255 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000256 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000257 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerb62bb282009-07-13 20:29:08 +0000258 }
259public:
Mike Stump1eb44332009-09-09 15:08:12 +0000260 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerb62bb282009-07-13 20:29:08 +0000261 : OSTargetInfo<Target>(triple) {
262 this->UserLabelPrefix = "";
263 }
264};
265
Torok Edwin5f6c1942009-06-30 17:10:35 +0000266// OpenBSD Target
267template<typename Target>
268class OpenBSDTargetInfo : public OSTargetInfo<Target> {
269protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000270 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000271 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000272 // OpenBSD defines; list based off of gcc output
273
Benjamin Kramera9992772010-01-09 17:55:51 +0000274 Builder.defineMacro("__OpenBSD__");
275 DefineStd(Builder, "unix", Opts);
276 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000277 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000278 Builder.defineMacro("_POSIX_THREADS");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000279 }
280public:
Mike Stump1eb44332009-09-09 15:08:12 +0000281 OpenBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000282 : OSTargetInfo<Target>(triple) {}
283};
284
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000285// PSP Target
286template<typename Target>
287class PSPTargetInfo : public OSTargetInfo<Target> {
288protected:
289 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000290 MacroBuilder &Builder) const {
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000291 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramera9992772010-01-09 17:55:51 +0000292 Builder.defineMacro("PSP");
293 Builder.defineMacro("_PSP");
294 Builder.defineMacro("__psp__");
295 Builder.defineMacro("__ELF__");
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000296 }
297public:
298 PSPTargetInfo(const std::string& triple)
299 : OSTargetInfo<Target>(triple) {
300 this->UserLabelPrefix = "";
301 }
302};
303
John Thompson3f6918a2009-11-19 17:18:50 +0000304// PS3 PPU Target
305template<typename Target>
306class PS3PPUTargetInfo : public OSTargetInfo<Target> {
307protected:
308 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000309 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000310 // PS3 PPU defines.
Benjamin Kramera9992772010-01-09 17:55:51 +0000311 Builder.defineMacro("__PPU__");
312 Builder.defineMacro("__CELLOS_LV2__");
313 Builder.defineMacro("__ELF__");
314 Builder.defineMacro("__LP32__");
John Thompson3f6918a2009-11-19 17:18:50 +0000315 }
316public:
317 PS3PPUTargetInfo(const std::string& triple)
318 : OSTargetInfo<Target>(triple) {
319 this->UserLabelPrefix = "";
John Thompsonec387af2009-12-18 14:21:08 +0000320 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
321 this->SizeType = TargetInfo::UnsignedInt;
John Thompson3f6918a2009-11-19 17:18:50 +0000322 }
323};
324
325// FIXME: Need a real SPU target.
326// PS3 SPU Target
327template<typename Target>
328class PS3SPUTargetInfo : public OSTargetInfo<Target> {
329protected:
330 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000331 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000332 // PS3 PPU defines.
Benjamin Kramera9992772010-01-09 17:55:51 +0000333 Builder.defineMacro("__SPU__");
334 Builder.defineMacro("__ELF__");
John Thompson3f6918a2009-11-19 17:18:50 +0000335 }
336public:
337 PS3SPUTargetInfo(const std::string& triple)
338 : OSTargetInfo<Target>(triple) {
339 this->UserLabelPrefix = "";
340 }
341};
342
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000343// AuroraUX target
344template<typename Target>
345class AuroraUXTargetInfo : public OSTargetInfo<Target> {
346protected:
347 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000348 MacroBuilder &Builder) const {
349 DefineStd(Builder, "sun", Opts);
350 DefineStd(Builder, "unix", Opts);
351 Builder.defineMacro("__ELF__");
352 Builder.defineMacro("__svr4__");
353 Builder.defineMacro("__SVR4");
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000354 }
355public:
356 AuroraUXTargetInfo(const std::string& triple)
357 : OSTargetInfo<Target>(triple) {
358 this->UserLabelPrefix = "";
359 this->WCharType = this->SignedLong;
360 // FIXME: WIntType should be SignedLong
361 }
362};
363
Torok Edwin5f6c1942009-06-30 17:10:35 +0000364// Solaris target
365template<typename Target>
366class SolarisTargetInfo : public OSTargetInfo<Target> {
367protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000368 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000369 MacroBuilder &Builder) const {
370 DefineStd(Builder, "sun", Opts);
371 DefineStd(Builder, "unix", Opts);
372 Builder.defineMacro("__ELF__");
373 Builder.defineMacro("__svr4__");
374 Builder.defineMacro("__SVR4");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000375 }
376public:
Mike Stump1eb44332009-09-09 15:08:12 +0000377 SolarisTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000378 : OSTargetInfo<Target>(triple) {
379 this->UserLabelPrefix = "";
380 this->WCharType = this->SignedLong;
381 // FIXME: WIntType should be SignedLong
382 }
383};
Mike Stump1eb44332009-09-09 15:08:12 +0000384} // end anonymous namespace.
Torok Edwin5f6c1942009-06-30 17:10:35 +0000385
Chris Lattnerd29b6302008-10-05 21:50:58 +0000386//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000387// Specific target implementations.
388//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000389
Eli Friedmane4277982008-08-20 23:11:40 +0000390namespace {
391// PPC abstract base class
392class PPCTargetInfo : public TargetInfo {
393 static const Builtin::Info BuiltinInfo[];
394 static const char * const GCCRegNames[];
395 static const TargetInfo::GCCRegAlias GCCRegAliases[];
396
397public:
Eli Friedman15b91762009-06-05 07:05:05 +0000398 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
399
Eli Friedmane4277982008-08-20 23:11:40 +0000400 virtual void getTargetBuiltins(const Builtin::Info *&Records,
401 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000402 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000403 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000404 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000405
Chris Lattner33328642009-03-20 15:52:06 +0000406 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000407 MacroBuilder &Builder) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000408
Eli Friedmane4277982008-08-20 23:11:40 +0000409 virtual const char *getVAListDeclaration() const {
Chris Lattnerd5998502008-10-27 01:11:29 +0000410 return "typedef char* __builtin_va_list;";
411 // This is the right definition for ABI/V4: System V.4/eabi.
412 /*return "typedef struct __va_list_tag {"
Eli Friedmane4277982008-08-20 23:11:40 +0000413 " unsigned char gpr;"
414 " unsigned char fpr;"
415 " unsigned short reserved;"
416 " void* overflow_arg_area;"
417 " void* reg_save_area;"
Chris Lattnerd5998502008-10-27 01:11:29 +0000418 "} __builtin_va_list[1];";*/
Anders Carlsson3346ae62007-11-24 23:38:12 +0000419 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000420 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000421 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000422 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000423 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000424 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000425 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000426 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000427 default: return false;
428 case 'O': // Zero
429 return true;
430 case 'b': // Base register
431 case 'f': // Floating point register
Chris Lattner44def072009-04-26 07:16:29 +0000432 Info.setAllowsRegister();
Anders Carlssond04c6e22007-11-27 04:11:28 +0000433 return true;
434 }
435 }
Eli Friedmane4277982008-08-20 23:11:40 +0000436 virtual const char *getClobbers() const {
437 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000438 }
Eli Friedmane4277982008-08-20 23:11:40 +0000439};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000440
Eli Friedmane4277982008-08-20 23:11:40 +0000441const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000442#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
443#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000444#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmane4277982008-08-20 23:11:40 +0000445};
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000446
447
Chris Lattnerc0f59212009-03-02 22:27:17 +0000448/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
449/// #defines that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000450void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000451 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000452 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +0000453 Builder.defineMacro("__ppc__");
454 Builder.defineMacro("_ARCH_PPC");
455 Builder.defineMacro("__POWERPC__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000456 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000457 Builder.defineMacro("_ARCH_PPC64");
458 Builder.defineMacro("_LP64");
459 Builder.defineMacro("__LP64__");
460 Builder.defineMacro("__ppc64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000461 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +0000462 Builder.defineMacro("__ppc__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000463 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000464
Chris Lattnerc0f59212009-03-02 22:27:17 +0000465 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +0000466 Builder.defineMacro("_BIG_ENDIAN");
467 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000468
Chris Lattnerc0f59212009-03-02 22:27:17 +0000469 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +0000470 Builder.defineMacro("__NATURAL_ALIGNMENT__");
471 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000472
Chris Lattnerc0f59212009-03-02 22:27:17 +0000473 // FIXME: Should be controlled by command line option.
Benjamin Kramera9992772010-01-09 17:55:51 +0000474 Builder.defineMacro("__LONG_DOUBLE_128__");
John Thompson3f6918a2009-11-19 17:18:50 +0000475
476 if (Opts.AltiVec) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000477 Builder.defineMacro("__VEC__", "10206");
478 Builder.defineMacro("__ALTIVEC__");
John Thompson3f6918a2009-11-19 17:18:50 +0000479 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000480}
481
Chris Lattner393ff042008-04-21 18:56:49 +0000482
Eli Friedmane4277982008-08-20 23:11:40 +0000483const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnere94e0d42009-09-16 05:05:27 +0000484 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
485 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
486 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
487 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
488 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
489 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
490 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
491 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmane4277982008-08-20 23:11:40 +0000492 "mq", "lr", "ctr", "ap",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000493 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmane4277982008-08-20 23:11:40 +0000494 "xer",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000495 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
496 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
497 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
498 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmane4277982008-08-20 23:11:40 +0000499 "vrsave", "vscr",
500 "spe_acc", "spefscr",
501 "sfp"
502};
Reid Spencer5f016e22007-07-11 17:01:13 +0000503
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000504void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000505 unsigned &NumNames) const {
506 Names = GCCRegNames;
507 NumNames = llvm::array_lengthof(GCCRegNames);
508}
Reid Spencer5f016e22007-07-11 17:01:13 +0000509
Eli Friedmane4277982008-08-20 23:11:40 +0000510const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
511 // While some of these aliases do map to different registers
512 // they still share the same register name.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000513 { { "0" }, "r0" },
514 { { "1"}, "r1" },
515 { { "2" }, "r2" },
516 { { "3" }, "r3" },
517 { { "4" }, "r4" },
518 { { "5" }, "r5" },
519 { { "6" }, "r6" },
520 { { "7" }, "r7" },
521 { { "8" }, "r8" },
522 { { "9" }, "r9" },
523 { { "10" }, "r10" },
524 { { "11" }, "r11" },
525 { { "12" }, "r12" },
526 { { "13" }, "r13" },
527 { { "14" }, "r14" },
528 { { "15" }, "r15" },
529 { { "16" }, "r16" },
530 { { "17" }, "r17" },
531 { { "18" }, "r18" },
532 { { "19" }, "r19" },
533 { { "20" }, "r20" },
534 { { "21" }, "r21" },
535 { { "22" }, "r22" },
536 { { "23" }, "r23" },
537 { { "24" }, "r24" },
538 { { "25" }, "r25" },
539 { { "26" }, "r26" },
540 { { "27" }, "r27" },
541 { { "28" }, "r28" },
542 { { "29" }, "r29" },
543 { { "30" }, "r30" },
544 { { "31" }, "r31" },
545 { { "fr0" }, "f0" },
546 { { "fr1" }, "f1" },
547 { { "fr2" }, "f2" },
548 { { "fr3" }, "f3" },
549 { { "fr4" }, "f4" },
550 { { "fr5" }, "f5" },
551 { { "fr6" }, "f6" },
552 { { "fr7" }, "f7" },
553 { { "fr8" }, "f8" },
554 { { "fr9" }, "f9" },
Mike Stump10880392009-09-17 21:15:00 +0000555 { { "fr10" }, "f10" },
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000556 { { "fr11" }, "f11" },
557 { { "fr12" }, "f12" },
558 { { "fr13" }, "f13" },
559 { { "fr14" }, "f14" },
560 { { "fr15" }, "f15" },
561 { { "fr16" }, "f16" },
562 { { "fr17" }, "f17" },
563 { { "fr18" }, "f18" },
564 { { "fr19" }, "f19" },
565 { { "fr20" }, "f20" },
566 { { "fr21" }, "f21" },
567 { { "fr22" }, "f22" },
568 { { "fr23" }, "f23" },
569 { { "fr24" }, "f24" },
570 { { "fr25" }, "f25" },
571 { { "fr26" }, "f26" },
572 { { "fr27" }, "f27" },
573 { { "fr28" }, "f28" },
574 { { "fr29" }, "f29" },
575 { { "fr30" }, "f30" },
576 { { "fr31" }, "f31" },
577 { { "cc" }, "cr0" },
Eli Friedmane4277982008-08-20 23:11:40 +0000578};
579
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000580void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000581 unsigned &NumAliases) const {
582 Aliases = GCCRegAliases;
583 NumAliases = llvm::array_lengthof(GCCRegAliases);
584}
585} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000586
587namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000588class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000589public:
Eli Friedmaned855cb2008-08-21 00:13:15 +0000590 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
591 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 +0000592 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Eli Friedmaned855cb2008-08-21 00:13:15 +0000593 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000594};
595} // end anonymous namespace.
596
597namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000598class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000599public:
Eli Friedmane4277982008-08-20 23:11:40 +0000600 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000601 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman3c7b6e42009-07-01 03:36:11 +0000602 IntMaxType = SignedLong;
603 UIntMaxType = UnsignedLong;
604 Int64Type = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000605 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 +0000606 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerf291b102008-05-09 06:17:04 +0000607 }
Eli Friedmane4277982008-08-20 23:11:40 +0000608};
609} // end anonymous namespace.
610
Reid Spencer5f016e22007-07-11 17:01:13 +0000611namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000612// Namespace for x86 abstract base class
613const Builtin::Info BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000614#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
615#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000616#include "clang/Basic/BuiltinsX86.def"
Eli Friedman618234a2008-08-20 02:34:37 +0000617};
Eli Friedman61538a72008-05-20 14:21:01 +0000618
Nuno Lopes2550d702009-12-23 17:49:57 +0000619static const char* const GCCRegNames[] = {
Eli Friedman618234a2008-08-20 02:34:37 +0000620 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
621 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
622 "argp", "flags", "fspr", "dirflag", "frame",
623 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
624 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
625 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
626 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
627};
628
629const TargetInfo::GCCRegAlias GCCRegAliases[] = {
630 { { "al", "ah", "eax", "rax" }, "ax" },
631 { { "bl", "bh", "ebx", "rbx" }, "bx" },
632 { { "cl", "ch", "ecx", "rcx" }, "cx" },
633 { { "dl", "dh", "edx", "rdx" }, "dx" },
634 { { "esi", "rsi" }, "si" },
635 { { "edi", "rdi" }, "di" },
636 { { "esp", "rsp" }, "sp" },
637 { { "ebp", "rbp" }, "bp" },
638};
639
640// X86 target abstract base class; x86-32 and x86-64 are very close, so
641// most of the implementation can be shared.
642class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +0000643 enum X86SSEEnum {
644 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
645 } SSELevel;
Eli Friedman618234a2008-08-20 02:34:37 +0000646public:
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000647 X86TargetInfo(const std::string& triple)
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000648 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman618234a2008-08-20 02:34:37 +0000649 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000650 }
651 virtual void getTargetBuiltins(const Builtin::Info *&Records,
652 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000653 Records = BuiltinInfo;
654 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000655 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000656 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000657 unsigned &NumNames) const {
658 Names = GCCRegNames;
659 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000660 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000661 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson3346ae62007-11-24 23:38:12 +0000662 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000663 Aliases = GCCRegAliases;
664 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000665 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000666 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000667 TargetInfo::ConstraintInfo &info) const;
668 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000669 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000670 return "~{dirflag},~{fpsr},~{flags}";
671 }
Chris Lattner33328642009-03-20 15:52:06 +0000672 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000673 MacroBuilder &Builder) const;
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000674 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
675 const std::string &Name,
676 bool Enabled) const;
Mike Stump1eb44332009-09-09 15:08:12 +0000677 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000678 llvm::StringMap<bool> &Features) const;
Daniel Dunbarb93292a2009-12-19 03:30:57 +0000679 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Reid Spencer5f016e22007-07-11 17:01:13 +0000680};
Chris Lattner3daed522009-03-02 22:20:04 +0000681
Mike Stump1eb44332009-09-09 15:08:12 +0000682void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000683 llvm::StringMap<bool> &Features) const {
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000684 // FIXME: This should not be here.
685 Features["3dnow"] = false;
686 Features["3dnowa"] = false;
687 Features["mmx"] = false;
688 Features["sse"] = false;
689 Features["sse2"] = false;
690 Features["sse3"] = false;
691 Features["ssse3"] = false;
692 Features["sse41"] = false;
693 Features["sse42"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000694
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000695 // LLVM does not currently recognize this.
696 // Features["sse4a"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000697
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000698 // FIXME: This *really* should not be here.
699
700 // X86_64 always has SSE2.
701 if (PointerWidth == 64)
702 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
703
Daniel Dunbar3ac79042009-05-06 21:56:32 +0000704 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
705 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
706 ;
707 else if (CPU == "pentium-mmx" || CPU == "pentium2")
708 setFeatureEnabled(Features, "mmx", true);
709 else if (CPU == "pentium3")
710 setFeatureEnabled(Features, "sse", true);
711 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
712 setFeatureEnabled(Features, "sse2", true);
713 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
714 setFeatureEnabled(Features, "sse3", true);
715 else if (CPU == "core2")
716 setFeatureEnabled(Features, "ssse3", true);
717 else if (CPU == "penryn") {
718 setFeatureEnabled(Features, "sse4", true);
719 Features["sse42"] = false;
720 } else if (CPU == "atom")
721 setFeatureEnabled(Features, "sse3", true);
722 else if (CPU == "corei7")
723 setFeatureEnabled(Features, "sse4", true);
724 else if (CPU == "k6" || CPU == "winchip-c6")
725 setFeatureEnabled(Features, "mmx", true);
Mike Stump1eb44332009-09-09 15:08:12 +0000726 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbar3ac79042009-05-06 21:56:32 +0000727 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
728 setFeatureEnabled(Features, "mmx", true);
729 setFeatureEnabled(Features, "3dnow", true);
730 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
731 setFeatureEnabled(Features, "sse", true);
732 setFeatureEnabled(Features, "3dnowa", true);
733 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
734 CPU == "athlon-fx") {
Mike Stump1eb44332009-09-09 15:08:12 +0000735 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +0000736 setFeatureEnabled(Features, "3dnowa", true);
737 } else if (CPU == "c3-2")
738 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000739}
740
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000741bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump1eb44332009-09-09 15:08:12 +0000742 const std::string &Name,
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000743 bool Enabled) const {
744 // FIXME: This *really* should not be here.
745 if (!Features.count(Name) && Name != "sse4")
746 return false;
747
748 if (Enabled) {
749 if (Name == "mmx")
750 Features["mmx"] = true;
751 else if (Name == "sse")
752 Features["mmx"] = Features["sse"] = true;
753 else if (Name == "sse2")
754 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
755 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +0000756 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000757 Features["sse3"] = true;
758 else if (Name == "ssse3")
Mike Stump1eb44332009-09-09 15:08:12 +0000759 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000760 Features["ssse3"] = true;
761 else if (Name == "sse4")
Mike Stump1eb44332009-09-09 15:08:12 +0000762 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000763 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
764 else if (Name == "3dnow")
765 Features["3dnowa"] = true;
766 else if (Name == "3dnowa")
767 Features["3dnow"] = Features["3dnowa"] = true;
768 } else {
769 if (Name == "mmx")
Mike Stump1eb44332009-09-09 15:08:12 +0000770 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000771 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
772 else if (Name == "sse")
Mike Stump1eb44332009-09-09 15:08:12 +0000773 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000774 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
775 else if (Name == "sse2")
Mike Stump1eb44332009-09-09 15:08:12 +0000776 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000777 Features["sse41"] = Features["sse42"] = false;
778 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +0000779 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000780 Features["sse42"] = false;
781 else if (Name == "ssse3")
782 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
783 else if (Name == "sse4")
784 Features["sse41"] = Features["sse42"] = false;
785 else if (Name == "3dnow")
786 Features["3dnow"] = Features["3dnowa"] = false;
787 else if (Name == "3dnowa")
788 Features["3dnowa"] = false;
789 }
790
791 return true;
792}
793
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000794/// HandleTargetOptions - Perform initialization based on the user
795/// configured set of features.
Daniel Dunbarb93292a2009-12-19 03:30:57 +0000796void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar29a790b2009-11-11 09:38:56 +0000797 // Remember the maximum enabled sselevel.
798 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
799 // Ignore disabled features.
800 if (Features[i][0] == '-')
801 continue;
802
803 assert(Features[i][0] == '+' && "Invalid target feature!");
804 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
805 .Case("sse42", SSE42)
806 .Case("sse41", SSE41)
807 .Case("ssse3", SSSE3)
808 .Case("sse2", SSE2)
809 .Case("sse", SSE1)
810 .Case("mmx", MMX)
811 .Default(NoMMXSSE);
812 SSELevel = std::max(SSELevel, Level);
813 }
Chris Lattner3daed522009-03-02 22:20:04 +0000814}
Chris Lattnerc0f59212009-03-02 22:27:17 +0000815
816/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
817/// that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000818void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000819 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000820 // Target identification.
821 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000822 Builder.defineMacro("_LP64");
823 Builder.defineMacro("__LP64__");
824 Builder.defineMacro("__amd64__");
825 Builder.defineMacro("__amd64");
826 Builder.defineMacro("__x86_64");
827 Builder.defineMacro("__x86_64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000828 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +0000829 DefineStd(Builder, "i386", Opts);
Chris Lattnerc0f59212009-03-02 22:27:17 +0000830 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000831
Chris Lattnerc0f59212009-03-02 22:27:17 +0000832 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +0000833 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000834
Chris Lattnerc0f59212009-03-02 22:27:17 +0000835 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +0000836 Builder.defineMacro("__nocona");
837 Builder.defineMacro("__nocona__");
838 Builder.defineMacro("__tune_nocona__");
839 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000840
Chris Lattner54175442009-04-19 17:32:33 +0000841 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
842 // functions in glibc header files that use FP Stack inline asm which the
843 // backend can't deal with (PR879).
Benjamin Kramera9992772010-01-09 17:55:51 +0000844 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000845
Chris Lattner84f0ea82009-03-02 22:40:39 +0000846 // Each case falls through to the previous one here.
847 switch (SSELevel) {
848 case SSE42:
Benjamin Kramera9992772010-01-09 17:55:51 +0000849 Builder.defineMacro("__SSE4_2__");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000850 case SSE41:
Benjamin Kramera9992772010-01-09 17:55:51 +0000851 Builder.defineMacro("__SSE4_1__");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000852 case SSSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +0000853 Builder.defineMacro("__SSSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000854 case SSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +0000855 Builder.defineMacro("__SSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000856 case SSE2:
Benjamin Kramera9992772010-01-09 17:55:51 +0000857 Builder.defineMacro("__SSE2__");
858 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +0000859 case SSE1:
Benjamin Kramera9992772010-01-09 17:55:51 +0000860 Builder.defineMacro("__SSE__");
861 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +0000862 case MMX:
Benjamin Kramera9992772010-01-09 17:55:51 +0000863 Builder.defineMacro("__MMX__");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000864 case NoMMXSSE:
865 break;
866 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000867}
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000868
869
Eli Friedman618234a2008-08-20 02:34:37 +0000870bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000871X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000872 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000873 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +0000874 default: return false;
875 case 'a': // eax.
876 case 'b': // ebx.
877 case 'c': // ecx.
878 case 'd': // edx.
879 case 'S': // esi.
880 case 'D': // edi.
881 case 'A': // edx:eax.
882 case 't': // top of floating point stack.
883 case 'u': // second from top of floating point stack.
884 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +0000885 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +0000886 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +0000887 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000888 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +0000889 // x86_64 instructions.
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000890 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +0000891 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +0000892 case 'N': // unsigned 8-bit integer constant for use with in and out
893 // instructions.
Eli Friedman12b2da02009-06-08 20:45:44 +0000894 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
Chris Lattner44def072009-04-26 07:16:29 +0000895 Info.setAllowsRegister();
Eli Friedman618234a2008-08-20 02:34:37 +0000896 return true;
897 }
898}
899
900std::string
901X86TargetInfo::convertConstraint(const char Constraint) const {
902 switch (Constraint) {
903 case 'a': return std::string("{ax}");
904 case 'b': return std::string("{bx}");
905 case 'c': return std::string("{cx}");
906 case 'd': return std::string("{dx}");
907 case 'S': return std::string("{si}");
908 case 'D': return std::string("{di}");
909 case 't': // top of floating point stack.
910 return std::string("{st}");
911 case 'u': // second from top of floating point stack.
912 return std::string("{st(1)}"); // second from top of floating point stack.
913 default:
914 return std::string(1, Constraint);
915 }
916}
Eli Friedman618234a2008-08-20 02:34:37 +0000917} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000918
919namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000920// X86-32 generic target
921class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000922public:
Eli Friedman618234a2008-08-20 02:34:37 +0000923 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
924 DoubleAlign = LongLongAlign = 32;
925 LongDoubleWidth = 96;
926 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000927 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
928 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +0000929 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman1afabd92009-03-29 20:31:09 +0000930 SizeType = UnsignedInt;
931 PtrDiffType = SignedInt;
932 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +0000933 RegParmMax = 3;
Eli Friedman618234a2008-08-20 02:34:37 +0000934 }
935 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000936 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +0000937 }
Chris Lattner21fb98e2009-09-23 06:06:36 +0000938
939 int getEHDataRegisterNumber(unsigned RegNo) const {
940 if (RegNo == 0) return 0;
941 if (RegNo == 1) return 2;
942 return -1;
943 }
Eli Friedman618234a2008-08-20 02:34:37 +0000944};
945} // end anonymous namespace
946
947namespace {
Eli Friedman624c1462009-07-05 18:47:56 +0000948class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
949public:
950 OpenBSDI386TargetInfo(const std::string& triple) :
951 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
952 SizeType = UnsignedLong;
953 IntPtrType = SignedLong;
Eli Friedman6036ebe2009-07-05 22:31:18 +0000954 PtrDiffType = SignedLong;
Eli Friedman624c1462009-07-05 18:47:56 +0000955 }
956};
957} // end anonymous namespace
958
959namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000960class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman618234a2008-08-20 02:34:37 +0000961public:
Torok Edwin5f6c1942009-06-30 17:10:35 +0000962 DarwinI386TargetInfo(const std::string& triple) :
963 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman618234a2008-08-20 02:34:37 +0000964 LongDoubleWidth = 128;
965 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +0000966 SizeType = UnsignedLong;
967 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000968 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
969 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +0000970 "a0:0:64-f80:128:128-n8:16:32";
Torok Edwinb0a5b242009-06-30 17:00:25 +0000971 }
972
Eli Friedman618234a2008-08-20 02:34:37 +0000973};
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +0000974} // end anonymous namespace
975
976namespace {
Eli Friedman29a30502008-08-21 01:40:19 +0000977// x86-32 Windows target
978class WindowsX86_32TargetInfo : public X86_32TargetInfo {
979public:
980 WindowsX86_32TargetInfo(const std::string& triple)
981 : X86_32TargetInfo(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +0000982 TLSSupported = false;
Chris Lattner85de9e72009-06-24 17:12:15 +0000983 WCharType = UnsignedShort;
Eli Friedman9c2f84e2009-06-08 21:16:17 +0000984 DoubleAlign = LongLongAlign = 64;
985 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 +0000986 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
987 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedman29a30502008-08-21 01:40:19 +0000988 }
Chris Lattner33328642009-03-20 15:52:06 +0000989 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000990 MacroBuilder &Builder) const {
991 X86_32TargetInfo::getTargetDefines(Opts, Builder);
Eli Friedman29a30502008-08-21 01:40:19 +0000992 // This list is based off of the the list of things MingW defines
Benjamin Kramera9992772010-01-09 17:55:51 +0000993 Builder.defineMacro("_WIN32");
994 DefineStd(Builder, "WIN32", Opts);
995 DefineStd(Builder, "WINNT", Opts);
996 Builder.defineMacro("_X86_");
Eli Friedman29a30502008-08-21 01:40:19 +0000997 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +0000998};
999} // end anonymous namespace
Eli Friedmanabc4e322009-06-08 06:11:14 +00001000
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001001namespace {
1002
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001003// x86-32 Windows Visual Studio target
1004class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1005public:
1006 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1007 : WindowsX86_32TargetInfo(triple) {
1008 }
1009 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001010 MacroBuilder &Builder) const {
1011 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001012 // The value of the following reflects processor type.
1013 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1014 // We lost the original triple, so we use the default.
Benjamin Kramera9992772010-01-09 17:55:51 +00001015 Builder.defineMacro("_M_IX86", "600");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001016 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001017};
1018} // end anonymous namespace
1019
1020namespace {
1021// x86-32 MinGW target
1022class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1023public:
1024 MinGWX86_32TargetInfo(const std::string& triple)
1025 : WindowsX86_32TargetInfo(triple) {
1026 }
1027 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001028 MacroBuilder &Builder) const {
1029 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1030 Builder.defineMacro("__MSVCRT__");
1031 Builder.defineMacro("__MINGW32__");
1032 Builder.defineMacro("__declspec", "__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001033 }
1034};
1035} // end anonymous namespace
1036
1037namespace {
1038// x86-32 Cygwin target
1039class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1040public:
1041 CygwinX86_32TargetInfo(const std::string& triple)
1042 : X86_32TargetInfo(triple) {
1043 TLSSupported = false;
1044 WCharType = UnsignedShort;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001045 DoubleAlign = LongLongAlign = 64;
1046 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1047 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001048 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001049 }
1050 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001051 MacroBuilder &Builder) const {
1052 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1053 Builder.defineMacro("__CYGWIN__");
1054 Builder.defineMacro("__CYGWIN32__");
1055 DefineStd(Builder, "unix", Opts);
Eli Friedmanabc4e322009-06-08 06:11:14 +00001056 }
Eli Friedman29a30502008-08-21 01:40:19 +00001057};
1058} // end anonymous namespace
1059
1060namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001061// x86-64 generic target
1062class X86_64TargetInfo : public X86TargetInfo {
1063public:
Chris Lattner33328642009-03-20 15:52:06 +00001064 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +00001065 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +00001066 LongDoubleWidth = 128;
1067 LongDoubleAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +00001068 IntMaxType = SignedLong;
1069 UIntMaxType = UnsignedLong;
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001070 Int64Type = SignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001071 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +00001072
Eli Friedmaned855cb2008-08-21 00:13:15 +00001073 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1074 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001075 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Reid Spencer5f016e22007-07-11 17:01:13 +00001076 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +00001077 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001078 return "typedef struct __va_list_tag {"
1079 " unsigned gp_offset;"
1080 " unsigned fp_offset;"
1081 " void* overflow_arg_area;"
1082 " void* reg_save_area;"
Eli Friedmandc043162009-07-03 00:45:06 +00001083 "} __va_list_tag;"
1084 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +00001085 }
Chris Lattner21fb98e2009-09-23 06:06:36 +00001086
1087 int getEHDataRegisterNumber(unsigned RegNo) const {
1088 if (RegNo == 0) return 0;
1089 if (RegNo == 1) return 1;
1090 return -1;
1091 }
Eli Friedman618234a2008-08-20 02:34:37 +00001092};
1093} // end anonymous namespace
1094
1095namespace {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001096// x86-64 Windows target
1097class WindowsX86_64TargetInfo : public X86_64TargetInfo {
1098public:
1099 WindowsX86_64TargetInfo(const std::string& triple)
1100 : X86_64TargetInfo(triple) {
1101 TLSSupported = false;
1102 WCharType = UnsignedShort;
Mike Stumpa55cce82009-10-08 23:00:00 +00001103 LongWidth = LongAlign = 32;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001104 DoubleAlign = LongLongAlign = 64;
1105 }
1106 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001107 MacroBuilder &Builder) const {
1108 X86_64TargetInfo::getTargetDefines(Opts, Builder);
1109 Builder.defineMacro("_WIN64");
1110 DefineStd(Builder, "WIN64", Opts);
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001111 }
1112};
1113} // end anonymous namespace
1114
1115namespace {
1116// x86-64 Windows Visual Studio target
1117class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1118public:
1119 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1120 : WindowsX86_64TargetInfo(triple) {
1121 }
1122 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001123 MacroBuilder &Builder) const {
1124 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1125 Builder.defineMacro("_M_X64");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001126 }
1127 virtual const char *getVAListDeclaration() const {
1128 return "typedef char* va_list;";
1129 }
1130};
1131} // end anonymous namespace
1132
1133namespace {
1134// x86-64 MinGW target
1135class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1136public:
1137 MinGWX86_64TargetInfo(const std::string& triple)
1138 : WindowsX86_64TargetInfo(triple) {
1139 }
1140 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001141 MacroBuilder &Builder) const {
1142 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1143 Builder.defineMacro("__MSVCRT__");
1144 Builder.defineMacro("__MINGW64__");
1145 Builder.defineMacro("__declspec");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001146 }
1147};
1148} // end anonymous namespace
1149
1150namespace {
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001151class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1152public:
Mike Stump1eb44332009-09-09 15:08:12 +00001153 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001154 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1155 Int64Type = SignedLongLong;
1156 }
1157};
1158} // end anonymous namespace
1159
1160namespace {
Eli Friedman6036ebe2009-07-05 22:31:18 +00001161class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1162public:
Mike Stump1eb44332009-09-09 15:08:12 +00001163 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman6036ebe2009-07-05 22:31:18 +00001164 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1165 IntMaxType = SignedLongLong;
1166 UIntMaxType = UnsignedLongLong;
1167 Int64Type = SignedLongLong;
1168 }
1169};
1170} // end anonymous namespace
1171
1172namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +00001173class ARMTargetInfo : public TargetInfo {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001174 // Possible FPU choices.
1175 enum FPUMode {
1176 NoFPU,
1177 VFP2FPU,
1178 VFP3FPU,
1179 NeonFPU
1180 };
1181
1182 static bool FPUModeIsVFP(FPUMode Mode) {
1183 return Mode >= VFP2FPU && Mode <= NeonFPU;
1184 }
1185
1186 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1187 static const char * const GCCRegNames[];
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001188
Daniel Dunbareac7c532009-12-18 18:42:37 +00001189 std::string ABI, CPU;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001190
1191 unsigned FPU : 3;
1192
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001193 unsigned IsThumb : 1;
1194
1195 // Initialized via features.
1196 unsigned SoftFloat : 1;
1197 unsigned SoftFloatABI : 1;
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001198
Chris Lattner393ff042008-04-21 18:56:49 +00001199public:
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001200 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbareac7c532009-12-18 18:42:37 +00001201 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001202 {
Daniel Dunbara2a41612009-09-14 00:02:24 +00001203 SizeType = UnsignedInt;
1204 PtrDiffType = SignedInt;
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001205
Daniel Dunbareac7c532009-12-18 18:42:37 +00001206 // FIXME: Should we just treat this as a feature?
Daniel Dunbar0791aa52009-12-18 19:57:13 +00001207 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001208 if (IsThumb) {
1209 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1210 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001211 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001212 } else {
1213 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1214 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner1932e122009-11-07 18:59:41 +00001215 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001216 }
Eli Friedman61538a72008-05-20 14:21:01 +00001217 }
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001218 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbara2a41612009-09-14 00:02:24 +00001219 virtual bool setABI(const std::string &Name) {
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001220 ABI = Name;
1221
Daniel Dunbara2a41612009-09-14 00:02:24 +00001222 // The defaults (above) are for AAPCS, check if we need to change them.
1223 //
1224 // FIXME: We need support for -meabi... we could just mangle it into the
1225 // name.
1226 if (Name == "apcs-gnu") {
1227 DoubleAlign = LongLongAlign = 32;
1228 SizeType = UnsignedLong;
1229
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001230 if (IsThumb) {
1231 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1232 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001233 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001234 } else {
1235 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1236 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00001237 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001238 }
1239
Daniel Dunbara2a41612009-09-14 00:02:24 +00001240 // FIXME: Override "preferred align" for double and long long.
1241 } else if (Name == "aapcs") {
1242 // FIXME: Enumerated types are variable width in straight AAPCS.
1243 } else if (Name == "aapcs-linux") {
1244 ;
1245 } else
1246 return false;
1247
1248 return true;
1249 }
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001250
Daniel Dunbara91320b2009-12-21 23:28:17 +00001251 void getDefaultFeatures(const std::string &CPU,
1252 llvm::StringMap<bool> &Features) const {
1253 // FIXME: This should not be here.
1254 Features["vfp2"] = false;
1255 Features["vfp3"] = false;
1256 Features["neon"] = false;
1257
1258 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1259 Features["vfp2"] = true;
1260 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1261 Features["neon"] = true;
1262 }
1263
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001264 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1265 const std::string &Name,
1266 bool Enabled) const {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001267 if (Name == "soft-float" || Name == "soft-float-abi") {
1268 Features[Name] = Enabled;
1269 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1270 // These effectively are a single option, reset them when any is enabled.
1271 if (Enabled)
1272 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1273 Features[Name] = Enabled;
1274 } else
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001275 return false;
1276
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001277 return true;
1278 }
1279
1280 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001281 FPU = NoFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001282 SoftFloat = SoftFloatABI = false;
1283 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1284 if (Features[i] == "+soft-float")
1285 SoftFloat = true;
1286 else if (Features[i] == "+soft-float-abi")
1287 SoftFloatABI = true;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001288 else if (Features[i] == "+vfp2")
1289 FPU = VFP2FPU;
1290 else if (Features[i] == "+vfp3")
1291 FPU = VFP3FPU;
1292 else if (Features[i] == "+neon")
1293 FPU = NeonFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001294 }
1295
1296 // Remove front-end specific options which the backend handles differently.
1297 std::vector<std::string>::iterator it;
1298 it = std::find(Features.begin(), Features.end(), "+soft-float");
1299 if (it != Features.end())
1300 Features.erase(it);
1301 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1302 if (it != Features.end())
1303 Features.erase(it);
1304 }
1305
Daniel Dunbareac7c532009-12-18 18:42:37 +00001306 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1307 return llvm::StringSwitch<const char*>(Name)
1308 .Cases("arm8", "arm810", "4")
1309 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1310 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1311 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1312 .Case("ep9312", "4T")
1313 .Cases("arm10tdmi", "arm1020t", "5T")
1314 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1315 .Case("arm926ej-s", "5TEJ")
1316 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1317 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001318 .Case("arm1136j-s", "6J")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001319 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbara91320b2009-12-21 23:28:17 +00001320 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbareac7c532009-12-18 18:42:37 +00001321 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1322 .Cases("cortex-a8", "cortex-a9", "7A")
1323 .Default(0);
1324 }
1325 virtual bool setCPU(const std::string &Name) {
1326 if (!getCPUDefineSuffix(Name))
1327 return false;
1328
1329 CPU = Name;
1330 return true;
1331 }
Chris Lattner33328642009-03-20 15:52:06 +00001332 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001333 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001334 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +00001335 Builder.defineMacro("__arm");
1336 Builder.defineMacro("__arm__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001337
Chris Lattnerc0f59212009-03-02 22:27:17 +00001338 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001339 Builder.defineMacro("__ARMEL__");
1340 Builder.defineMacro("__LITTLE_ENDIAN__");
1341 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001342
1343 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramera9992772010-01-09 17:55:51 +00001344 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001345
Mike Stump437bb4b2009-04-08 02:07:04 +00001346 // Subtarget options.
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001347
Daniel Dunbareac7c532009-12-18 18:42:37 +00001348 // FIXME: It's more complicated than this and we don't really support
1349 // interworking.
1350 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramera9992772010-01-09 17:55:51 +00001351 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001352
Daniel Dunbareac7c532009-12-18 18:42:37 +00001353 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramera9992772010-01-09 17:55:51 +00001354 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001355
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001356 if (SoftFloat)
Benjamin Kramera9992772010-01-09 17:55:51 +00001357 Builder.defineMacro("__SOFTFP__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00001358
1359 if (CPU == "xscale")
Benjamin Kramera9992772010-01-09 17:55:51 +00001360 Builder.defineMacro("__XSCALE__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001361
Daniel Dunbara91320b2009-12-21 23:28:17 +00001362 bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001363 if (IsThumb) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001364 Builder.defineMacro("__THUMBEL__");
1365 Builder.defineMacro("__thumb__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001366 if (IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001367 Builder.defineMacro("__thumb2__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001368 }
1369
1370 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramera9992772010-01-09 17:55:51 +00001371 Builder.defineMacro("__APCS_32__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001372
1373 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramera9992772010-01-09 17:55:51 +00001374 Builder.defineMacro("__VFP_FP__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00001375
1376 // This only gets set when Neon instructions are actually available, unlike
1377 // the VFP define, hence the soft float and arch check. This is subtly
1378 // different from gcc, we follow the intent which was that it should be set
1379 // when Neon instructions are actually available.
1380 if (FPU == NeonFPU && !SoftFloat && IsThumb2)
Benjamin Kramera9992772010-01-09 17:55:51 +00001381 Builder.defineMacro("__ARM_NEON__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001382
Daniel Dunbar0791aa52009-12-18 19:57:13 +00001383 if (getTriple().getOS() == llvm::Triple::Darwin)
Benjamin Kramera9992772010-01-09 17:55:51 +00001384 Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
Chris Lattner393ff042008-04-21 18:56:49 +00001385 }
1386 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1387 unsigned &NumRecords) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001388 // FIXME: Implement.
1389 Records = 0;
Chris Lattner393ff042008-04-21 18:56:49 +00001390 NumRecords = 0;
1391 }
1392 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001393 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +00001394 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001395 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001396 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001397 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001398 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001399 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001400 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001401 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001402 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +00001403 default:
Nate Begemanad487f42008-04-22 05:03:19 +00001404 case 'l': // r0-r7
1405 case 'h': // r8-r15
1406 case 'w': // VFP Floating point register single precision
1407 case 'P': // VFP Floating point register double precision
Chris Lattner44def072009-04-26 07:16:29 +00001408 Info.setAllowsRegister();
Nate Begemanad487f42008-04-22 05:03:19 +00001409 return true;
1410 }
Chris Lattner393ff042008-04-21 18:56:49 +00001411 return false;
1412 }
1413 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001414 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +00001415 return "";
1416 }
1417};
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001418
1419const char * const ARMTargetInfo::GCCRegNames[] = {
1420 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1421 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1422};
1423
1424void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
1425 unsigned &NumNames) const {
1426 Names = GCCRegNames;
1427 NumNames = llvm::array_lengthof(GCCRegNames);
1428}
1429
1430const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1431
1432 { { "a1" }, "r0" },
1433 { { "a2" }, "r1" },
1434 { { "a3" }, "r2" },
1435 { { "a4" }, "r3" },
1436 { { "v1" }, "r4" },
1437 { { "v2" }, "r5" },
1438 { { "v3" }, "r6" },
1439 { { "v4" }, "r7" },
1440 { { "v5" }, "r8" },
1441 { { "v6", "rfp" }, "r9" },
1442 { { "sl" }, "r10" },
1443 { { "fp" }, "r11" },
1444 { { "ip" }, "r12" },
1445 { { "sp" }, "r13" },
1446 { { "lr" }, "r14" },
1447 { { "pc" }, "r15" },
1448};
1449
1450void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1451 unsigned &NumAliases) const {
1452 Aliases = GCCRegAliases;
1453 NumAliases = llvm::array_lengthof(GCCRegAliases);
1454}
Chris Lattner393ff042008-04-21 18:56:49 +00001455} // end anonymous namespace.
1456
Eli Friedmana9f54962008-08-20 07:44:10 +00001457
1458namespace {
Mike Stump1eb44332009-09-09 15:08:12 +00001459class DarwinARMTargetInfo :
Torok Edwin5f6c1942009-06-30 17:10:35 +00001460 public DarwinTargetInfo<ARMTargetInfo> {
1461protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +00001462 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +00001463 MacroBuilder &Builder) const {
1464 getDarwinDefines(Builder, Opts);
1465 getDarwinIPhoneOSDefines(Builder, Triple);
Eli Friedmanb030f022009-04-19 21:38:35 +00001466 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001467
Torok Edwin5f6c1942009-06-30 17:10:35 +00001468public:
Mike Stump1eb44332009-09-09 15:08:12 +00001469 DarwinARMTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +00001470 : DarwinTargetInfo<ARMTargetInfo>(triple) {}
Eli Friedmana9f54962008-08-20 07:44:10 +00001471};
1472} // end anonymous namespace.
1473
Reid Spencer5f016e22007-07-11 17:01:13 +00001474namespace {
Eli Friedman01b86682008-08-20 07:28:14 +00001475class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +00001476 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1477 static const char * const GCCRegNames[];
Gabor Greif26658672008-02-21 16:29:08 +00001478public:
Eli Friedman01b86682008-08-20 07:28:14 +00001479 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1480 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +00001481 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 +00001482 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedman01b86682008-08-20 07:28:14 +00001483 }
Chris Lattner33328642009-03-20 15:52:06 +00001484 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001485 MacroBuilder &Builder) const {
1486 DefineStd(Builder, "sparc", Opts);
1487 Builder.defineMacro("__sparcv8");
1488 Builder.defineMacro("__REGISTER_PREFIX__", "");
Gabor Greif26658672008-02-21 16:29:08 +00001489 }
1490 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1491 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +00001492 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +00001493 }
1494 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001495 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +00001496 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001497 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00001498 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001499 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00001500 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001501 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +00001502 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +00001503 // FIXME: Implement!
1504 return false;
Gabor Greif26658672008-02-21 16:29:08 +00001505 }
1506 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001507 // FIXME: Implement!
1508 return "";
Gabor Greif26658672008-02-21 16:29:08 +00001509 }
1510};
1511
Chris Lattnere957f532009-01-27 01:58:38 +00001512const char * const SparcV8TargetInfo::GCCRegNames[] = {
1513 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1514 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1515 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1516 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1517};
1518
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001519void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00001520 unsigned &NumNames) const {
1521 Names = GCCRegNames;
1522 NumNames = llvm::array_lengthof(GCCRegNames);
1523}
1524
1525const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001526 { { "g0" }, "r0" },
1527 { { "g1" }, "r1" },
1528 { { "g2" }, "r2" },
1529 { { "g3" }, "r3" },
1530 { { "g4" }, "r4" },
1531 { { "g5" }, "r5" },
1532 { { "g6" }, "r6" },
1533 { { "g7" }, "r7" },
1534 { { "o0" }, "r8" },
1535 { { "o1" }, "r9" },
1536 { { "o2" }, "r10" },
1537 { { "o3" }, "r11" },
1538 { { "o4" }, "r12" },
1539 { { "o5" }, "r13" },
1540 { { "o6", "sp" }, "r14" },
1541 { { "o7" }, "r15" },
1542 { { "l0" }, "r16" },
1543 { { "l1" }, "r17" },
1544 { { "l2" }, "r18" },
1545 { { "l3" }, "r19" },
1546 { { "l4" }, "r20" },
1547 { { "l5" }, "r21" },
1548 { { "l6" }, "r22" },
1549 { { "l7" }, "r23" },
1550 { { "i0" }, "r24" },
1551 { { "i1" }, "r25" },
1552 { { "i2" }, "r26" },
1553 { { "i3" }, "r27" },
1554 { { "i4" }, "r28" },
1555 { { "i5" }, "r29" },
1556 { { "i6", "fp" }, "r30" },
1557 { { "i7" }, "r31" },
Chris Lattnere957f532009-01-27 01:58:38 +00001558};
1559
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001560void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00001561 unsigned &NumAliases) const {
1562 Aliases = GCCRegAliases;
1563 NumAliases = llvm::array_lengthof(GCCRegAliases);
1564}
Gabor Greif26658672008-02-21 16:29:08 +00001565} // end anonymous namespace.
1566
Eli Friedman01b86682008-08-20 07:28:14 +00001567namespace {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00001568class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
1569public:
1570 AuroraUXSparcV8TargetInfo(const std::string& triple) :
1571 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
1572 SizeType = UnsignedInt;
1573 PtrDiffType = SignedInt;
1574 }
1575};
Torok Edwin5f6c1942009-06-30 17:10:35 +00001576class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedman01b86682008-08-20 07:28:14 +00001577public:
1578 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwin5f6c1942009-06-30 17:10:35 +00001579 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmanf509d732008-11-02 02:43:55 +00001580 SizeType = UnsignedInt;
1581 PtrDiffType = SignedInt;
Eli Friedman01b86682008-08-20 07:28:14 +00001582 }
1583};
1584} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00001585
Chris Lattner2621fd12008-05-08 05:58:21 +00001586namespace {
1587 class PIC16TargetInfo : public TargetInfo{
1588 public:
1589 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +00001590 TLSSupported = false;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +00001591 IntWidth = 16;
1592 LongWidth = LongLongWidth = 32;
1593 PointerWidth = 16;
1594 IntAlign = 8;
1595 LongAlign = LongLongAlign = 8;
Eli Friedman61538a72008-05-20 14:21:01 +00001596 PointerAlign = 8;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +00001597 SizeType = UnsignedInt;
1598 IntMaxType = SignedLong;
1599 UIntMaxType = UnsignedLong;
Chris Lattner6ad474f2009-02-13 22:28:55 +00001600 IntPtrType = SignedShort;
Eli Friedmanf509d732008-11-02 02:43:55 +00001601 PtrDiffType = SignedInt;
Edward O'Callaghan9cf910e2009-11-21 00:49:54 +00001602 SigAtomicType = SignedLong;
Sanjiv Gupta9eb4cef2009-06-02 04:43:46 +00001603 FloatWidth = 32;
1604 FloatAlign = 32;
1605 DoubleWidth = 32;
1606 DoubleAlign = 32;
1607 LongDoubleWidth = 32;
1608 LongDoubleAlign = 32;
1609 FloatFormat = &llvm::APFloat::IEEEsingle;
1610 DoubleFormat = &llvm::APFloat::IEEEsingle;
1611 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner1932e122009-11-07 18:59:41 +00001612 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8";
Sanjiv Gupta9eb4cef2009-06-02 04:43:46 +00001613
Chris Lattner2621fd12008-05-08 05:58:21 +00001614 }
Chris Lattner927686f2008-05-09 06:08:39 +00001615 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1616 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner33328642009-03-20 15:52:06 +00001617 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001618 MacroBuilder &Builder) const {
1619 Builder.defineMacro("__pic16");
1620 Builder.defineMacro("rom", "__attribute__((address_space(1)))");
1621 Builder.defineMacro("ram", "__attribute__((address_space(0)))");
1622 Builder.defineMacro("_section(SectName)",
Sanjiv Guptada3e03e2009-08-20 17:48:52 +00001623 "__attribute__((section(SectName)))");
Benjamin Kramera9992772010-01-09 17:55:51 +00001624 Builder.defineMacro("near",
Sanjiv Gupta7de70092009-10-24 18:08:20 +00001625 "__attribute__((section(\"Address=NEAR\")))");
Benjamin Kramera9992772010-01-09 17:55:51 +00001626 Builder.defineMacro("_address(Addr)",
Sanjiv Guptada3e03e2009-08-20 17:48:52 +00001627 "__attribute__((section(\"Address=\"#Addr)))");
Benjamin Kramera9992772010-01-09 17:55:51 +00001628 Builder.defineMacro("_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
1629 Builder.defineMacro("_interrupt",
Sanjiv Guptada3e03e2009-08-20 17:48:52 +00001630 "__attribute__((section(\"interrupt=0x4\"))) \
1631 __attribute__((used))");
Chris Lattner2621fd12008-05-08 05:58:21 +00001632 }
1633 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1634 unsigned &NumRecords) const {}
Mike Stump1eb44332009-09-09 15:08:12 +00001635 virtual const char *getVAListDeclaration() const {
Daniel Dunbar55cc2ed2009-08-24 09:54:37 +00001636 return "";
1637 }
1638 virtual const char *getClobbers() const {
1639 return "";
1640 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001641 virtual void getGCCRegNames(const char * const *&Names,
1642 unsigned &NumNames) const {}
1643 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner2621fd12008-05-08 05:58:21 +00001644 TargetInfo::ConstraintInfo &info) const {
1645 return true;
1646 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001647 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner2621fd12008-05-08 05:58:21 +00001648 unsigned &NumAliases) const {}
1649 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1650 };
1651}
1652
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001653namespace {
1654 class MSP430TargetInfo : public TargetInfo {
1655 static const char * const GCCRegNames[];
1656 public:
1657 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1658 TLSSupported = false;
1659 IntWidth = 16;
Anton Korobeynikov26d18c12010-01-14 20:22:45 +00001660 LongWidth = 32;
1661 LongLongWidth = 64;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001662 PointerWidth = 16;
1663 IntAlign = 8;
1664 LongAlign = LongLongAlign = 8;
1665 PointerAlign = 8;
1666 SizeType = UnsignedInt;
1667 IntMaxType = SignedLong;
1668 UIntMaxType = UnsignedLong;
1669 IntPtrType = SignedShort;
1670 PtrDiffType = SignedInt;
Edward O'Callaghan9cf910e2009-11-21 00:49:54 +00001671 SigAtomicType = SignedLong;
Anton Korobeynikov5d7c2512009-12-19 01:32:37 +00001672 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001673 }
1674 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001675 MacroBuilder &Builder) const {
1676 Builder.defineMacro("MSP430");
1677 Builder.defineMacro("__MSP430__");
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001678 // FIXME: defines for different 'flavours' of MCU
1679 }
1680 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1681 unsigned &NumRecords) const {
1682 // FIXME: Implement.
1683 Records = 0;
1684 NumRecords = 0;
1685 }
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001686 virtual void getGCCRegNames(const char * const *&Names,
1687 unsigned &NumNames) const;
1688 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1689 unsigned &NumAliases) const {
1690 // No aliases.
1691 Aliases = 0;
1692 NumAliases = 0;
1693 }
1694 virtual bool validateAsmConstraint(const char *&Name,
1695 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov03265b62009-10-15 23:17:13 +00001696 // No target constraints for now.
1697 return false;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001698 }
1699 virtual const char *getClobbers() const {
1700 // FIXME: Is this really right?
1701 return "";
1702 }
1703 virtual const char *getVAListDeclaration() const {
1704 // FIXME: implement
Anton Korobeynikoveb716852009-05-08 18:24:57 +00001705 return "typedef char* __builtin_va_list;";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001706 }
1707 };
1708
1709 const char * const MSP430TargetInfo::GCCRegNames[] = {
1710 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1711 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1712 };
1713
1714 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1715 unsigned &NumNames) const {
1716 Names = GCCRegNames;
1717 NumNames = llvm::array_lengthof(GCCRegNames);
1718 }
1719}
1720
1721
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00001722namespace {
1723 class SystemZTargetInfo : public TargetInfo {
1724 static const char * const GCCRegNames[];
1725 public:
1726 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
1727 TLSSupported = false;
1728 IntWidth = IntAlign = 32;
1729 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
1730 PointerWidth = PointerAlign = 64;
Chris Lattner1932e122009-11-07 18:59:41 +00001731 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
1732 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00001733 }
1734 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001735 MacroBuilder &Builder) const {
1736 Builder.defineMacro("__s390__");
1737 Builder.defineMacro("__s390x__");
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00001738 }
1739 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1740 unsigned &NumRecords) const {
1741 // FIXME: Implement.
1742 Records = 0;
1743 NumRecords = 0;
1744 }
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00001745
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00001746 virtual void getGCCRegNames(const char * const *&Names,
1747 unsigned &NumNames) const;
1748 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1749 unsigned &NumAliases) const {
1750 // No aliases.
1751 Aliases = 0;
1752 NumAliases = 0;
1753 }
1754 virtual bool validateAsmConstraint(const char *&Name,
1755 TargetInfo::ConstraintInfo &info) const {
1756 // FIXME: implement
1757 return true;
1758 }
1759 virtual const char *getClobbers() const {
1760 // FIXME: Is this really right?
1761 return "";
1762 }
1763 virtual const char *getVAListDeclaration() const {
1764 // FIXME: implement
1765 return "typedef char* __builtin_va_list;";
1766 }
1767 };
1768
1769 const char * const SystemZTargetInfo::GCCRegNames[] = {
1770 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1771 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1772 };
1773
1774 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
1775 unsigned &NumNames) const {
1776 Names = GCCRegNames;
1777 NumNames = llvm::array_lengthof(GCCRegNames);
1778 }
1779}
1780
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00001781namespace {
1782 class BlackfinTargetInfo : public TargetInfo {
1783 static const char * const GCCRegNames[];
1784 public:
1785 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
1786 TLSSupported = false;
1787 DoubleAlign = 32;
1788 LongLongAlign = 32;
1789 LongDoubleAlign = 32;
Chris Lattner1932e122009-11-07 18:59:41 +00001790 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00001791 }
1792
1793 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001794 MacroBuilder &Builder) const {
1795 DefineStd(Builder, "bfin", Opts);
1796 DefineStd(Builder, "BFIN", Opts);
1797 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00001798 // FIXME: This one is really dependent on -mcpu
Benjamin Kramera9992772010-01-09 17:55:51 +00001799 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00001800 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
1801 }
1802
1803 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1804 unsigned &NumRecords) const {
1805 // FIXME: Implement.
1806 Records = 0;
1807 NumRecords = 0;
1808 }
1809
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00001810 virtual void getGCCRegNames(const char * const *&Names,
1811 unsigned &NumNames) const;
1812
1813 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1814 unsigned &NumAliases) const {
1815 // No aliases.
1816 Aliases = 0;
1817 NumAliases = 0;
1818 }
1819
1820 virtual bool validateAsmConstraint(const char *&Name,
1821 TargetInfo::ConstraintInfo &Info) const {
1822 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
1823 Info.setAllowsRegister();
1824 return true;
1825 }
1826 return false;
1827 }
1828
1829 virtual const char *getClobbers() const {
1830 return "";
1831 }
1832
1833 virtual const char *getVAListDeclaration() const {
1834 return "typedef char* __builtin_va_list;";
1835 }
1836 };
1837
1838 const char * const BlackfinTargetInfo::GCCRegNames[] = {
1839 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1840 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
1841 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
1842 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
1843 "a0", "a1", "cc",
1844 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
1845 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
1846 };
1847
1848 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
1849 unsigned &NumNames) const {
1850 Names = GCCRegNames;
1851 NumNames = llvm::array_lengthof(GCCRegNames);
1852 }
1853}
1854
Eli Friedmanb63decf2009-08-19 20:47:07 +00001855namespace {
1856
Mike Stump1eb44332009-09-09 15:08:12 +00001857 // LLVM and Clang cannot be used directly to output native binaries for
1858 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmanb63decf2009-08-19 20:47:07 +00001859 // type and alignment information.
Mike Stump1eb44332009-09-09 15:08:12 +00001860 //
1861 // TCE uses the llvm bitcode as input and uses it for generating customized
1862 // target processor and program binary. TCE co-design environment is
Eli Friedmanb63decf2009-08-19 20:47:07 +00001863 // publicly available in http://tce.cs.tut.fi
1864
1865 class TCETargetInfo : public TargetInfo{
1866 public:
1867 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
1868 TLSSupported = false;
1869 IntWidth = 32;
1870 LongWidth = LongLongWidth = 32;
Eli Friedmanb63decf2009-08-19 20:47:07 +00001871 PointerWidth = 32;
1872 IntAlign = 32;
1873 LongAlign = LongLongAlign = 32;
1874 PointerAlign = 32;
1875 SizeType = UnsignedInt;
1876 IntMaxType = SignedLong;
1877 UIntMaxType = UnsignedLong;
1878 IntPtrType = SignedInt;
1879 PtrDiffType = SignedInt;
1880 FloatWidth = 32;
1881 FloatAlign = 32;
1882 DoubleWidth = 32;
1883 DoubleAlign = 32;
1884 LongDoubleWidth = 32;
1885 LongDoubleAlign = 32;
1886 FloatFormat = &llvm::APFloat::IEEEsingle;
1887 DoubleFormat = &llvm::APFloat::IEEEsingle;
1888 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1889 DescriptionString = "E-p:32:32:32-a0:32:32"
1890 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64"
Chris Lattner1932e122009-11-07 18:59:41 +00001891 "-f32:32:32-f64:32:64-n32";
Eli Friedmanb63decf2009-08-19 20:47:07 +00001892 }
1893
1894 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001895 MacroBuilder &Builder) const {
1896 DefineStd(Builder, "tce", Opts);
1897 Builder.defineMacro("__TCE__");
1898 Builder.defineMacro("__TCE_V1__");
Eli Friedmanb63decf2009-08-19 20:47:07 +00001899 }
1900 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1901 unsigned &NumRecords) const {}
Daniel Dunbar55cc2ed2009-08-24 09:54:37 +00001902 virtual const char *getClobbers() const {
1903 return "";
1904 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00001905 virtual const char *getVAListDeclaration() const {
1906 return "typedef void* __builtin_va_list;";
1907 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00001908 virtual void getGCCRegNames(const char * const *&Names,
1909 unsigned &NumNames) const {}
1910 virtual bool validateAsmConstraint(const char *&Name,
1911 TargetInfo::ConstraintInfo &info) const {
1912 return true;
1913 }
1914 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1915 unsigned &NumAliases) const {}
1916 };
1917}
1918
Edward O'Callaghan84423a82009-11-15 10:22:07 +00001919namespace {
1920class MipsTargetInfo : public TargetInfo {
1921 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1922 static const char * const GCCRegNames[];
1923public:
1924 MipsTargetInfo(const std::string& triple) : TargetInfo(triple) {
1925 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
1926 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
1927 }
1928 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001929 MacroBuilder &Builder) const {
1930 DefineStd(Builder, "mips", Opts);
1931 Builder.defineMacro("_mips");
1932 DefineStd(Builder, "MIPSEB", Opts);
1933 Builder.defineMacro("_MIPSEB");
1934 Builder.defineMacro("__REGISTER_PREFIX__", "");
Edward O'Callaghan84423a82009-11-15 10:22:07 +00001935 }
1936 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1937 unsigned &NumRecords) const {
1938 // FIXME: Implement!
1939 }
1940 virtual const char *getVAListDeclaration() const {
1941 return "typedef void* __builtin_va_list;";
1942 }
1943 virtual void getGCCRegNames(const char * const *&Names,
1944 unsigned &NumNames) const;
1945 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1946 unsigned &NumAliases) const;
1947 virtual bool validateAsmConstraint(const char *&Name,
1948 TargetInfo::ConstraintInfo &Info) const {
1949 switch (*Name) {
1950 default:
1951 case 'r': // CPU registers.
1952 case 'd': // Equivalent to "r" unless generating MIPS16 code.
1953 case 'y': // Equivalent to "r", backwards compatibility only.
1954 case 'f': // floating-point registers.
1955 Info.setAllowsRegister();
1956 return true;
1957 }
1958 return false;
1959 }
1960
1961 virtual const char *getClobbers() const {
1962 // FIXME: Implement!
1963 return "";
1964 }
1965};
1966
1967const char * const MipsTargetInfo::GCCRegNames[] = {
1968 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
1969 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
1970 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
1971 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
1972 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
1973 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
1974 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
1975 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
1976 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
1977 "$fcc5","$fcc6","$fcc7"
1978};
1979
1980void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
1981 unsigned &NumNames) const {
1982 Names = GCCRegNames;
1983 NumNames = llvm::array_lengthof(GCCRegNames);
1984}
1985
1986const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
1987 { { "at" }, "$1" },
1988 { { "v0" }, "$2" },
1989 { { "v1" }, "$3" },
1990 { { "a0" }, "$4" },
1991 { { "a1" }, "$5" },
1992 { { "a2" }, "$6" },
1993 { { "a3" }, "$7" },
1994 { { "t0" }, "$8" },
1995 { { "t1" }, "$9" },
1996 { { "t2" }, "$10" },
1997 { { "t3" }, "$11" },
1998 { { "t4" }, "$12" },
1999 { { "t5" }, "$13" },
2000 { { "t6" }, "$14" },
2001 { { "t7" }, "$15" },
2002 { { "s0" }, "$16" },
2003 { { "s1" }, "$17" },
2004 { { "s2" }, "$18" },
2005 { { "s3" }, "$19" },
2006 { { "s4" }, "$20" },
2007 { { "s5" }, "$21" },
2008 { { "s6" }, "$22" },
2009 { { "s7" }, "$23" },
2010 { { "t8" }, "$24" },
2011 { { "t9" }, "$25" },
2012 { { "k0" }, "$26" },
2013 { { "k1" }, "$27" },
2014 { { "gp" }, "$28" },
2015 { { "sp" }, "$29" },
2016 { { "fp" }, "$30" },
2017 { { "ra" }, "$31" }
2018};
2019
2020void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2021 unsigned &NumAliases) const {
2022 Aliases = GCCRegAliases;
2023 NumAliases = llvm::array_lengthof(GCCRegAliases);
2024}
2025} // end anonymous namespace.
2026
2027namespace {
2028class MipselTargetInfo : public MipsTargetInfo {
2029public:
2030 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2031 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
2032 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
2033 }
2034
2035 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002036 MacroBuilder &Builder) const;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002037};
2038
2039void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002040 MacroBuilder &Builder) const {
2041 DefineStd(Builder, "mips", Opts);
2042 Builder.defineMacro("_mips");
2043 DefineStd(Builder, "MIPSEL", Opts);
2044 Builder.defineMacro("_MIPSEL");
2045 Builder.defineMacro("__REGISTER_PREFIX__", "");
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002046}
2047} // end anonymous namespace.
2048
Reid Spencer5f016e22007-07-11 17:01:13 +00002049//===----------------------------------------------------------------------===//
2050// Driver code
2051//===----------------------------------------------------------------------===//
2052
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002053static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002054 llvm::Triple Triple(T);
2055 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman61538a72008-05-20 14:21:01 +00002056
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002057 switch (Triple.getArch()) {
2058 default:
2059 return NULL;
Eli Friedman61538a72008-05-20 14:21:01 +00002060
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002061 case llvm::Triple::arm:
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +00002062 case llvm::Triple::thumb:
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002063 switch (os) {
2064 case llvm::Triple::Darwin:
Eli Friedmaned855cb2008-08-21 00:13:15 +00002065 return new DarwinARMTargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002066 case llvm::Triple::FreeBSD:
Torok Edwin5f6c1942009-06-30 17:10:35 +00002067 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002068 default:
2069 return new ARMTargetInfo(T);
2070 }
Eli Friedman61538a72008-05-20 14:21:01 +00002071
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002072 case llvm::Triple::bfin:
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002073 return new BlackfinTargetInfo(T);
2074
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002075 case llvm::Triple::msp430:
2076 return new MSP430TargetInfo(T);
Eli Friedman61538a72008-05-20 14:21:01 +00002077
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002078 case llvm::Triple::mips:
2079 if (os == llvm::Triple::Psp)
2080 return new PSPTargetInfo<MipsTargetInfo>(T);
2081 if (os == llvm::Triple::Linux)
2082 return new LinuxTargetInfo<MipsTargetInfo>(T);
2083 return new MipsTargetInfo(T);
2084
2085 case llvm::Triple::mipsel:
2086 if (os == llvm::Triple::Psp)
2087 return new PSPTargetInfo<MipselTargetInfo>(T);
2088 if (os == llvm::Triple::Linux)
2089 return new LinuxTargetInfo<MipselTargetInfo>(T);
2090 return new MipselTargetInfo(T);
2091
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002092 case llvm::Triple::pic16:
2093 return new PIC16TargetInfo(T);
2094
2095 case llvm::Triple::ppc:
2096 if (os == llvm::Triple::Darwin)
2097 return new DarwinTargetInfo<PPCTargetInfo>(T);
2098 return new PPC32TargetInfo(T);
2099
2100 case llvm::Triple::ppc64:
2101 if (os == llvm::Triple::Darwin)
2102 return new DarwinTargetInfo<PPC64TargetInfo>(T);
John Thompson3f6918a2009-11-19 17:18:50 +00002103 else if (os == llvm::Triple::Lv2)
2104 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002105 return new PPC64TargetInfo(T);
2106
2107 case llvm::Triple::sparc:
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002108 if (os == llvm::Triple::AuroraUX)
2109 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002110 if (os == llvm::Triple::Solaris)
2111 return new SolarisSparcV8TargetInfo(T);
2112 return new SparcV8TargetInfo(T);
2113
John Thompson3f6918a2009-11-19 17:18:50 +00002114 // FIXME: Need a real SPU target.
2115 case llvm::Triple::cellspu:
2116 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2117
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002118 case llvm::Triple::systemz:
2119 return new SystemZTargetInfo(T);
2120
Eli Friedmanb63decf2009-08-19 20:47:07 +00002121 case llvm::Triple::tce:
2122 return new TCETargetInfo(T);
2123
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002124 case llvm::Triple::x86:
2125 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002126 case llvm::Triple::AuroraUX:
2127 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002128 case llvm::Triple::Darwin:
2129 return new DarwinI386TargetInfo(T);
2130 case llvm::Triple::Linux:
2131 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2132 case llvm::Triple::DragonFly:
2133 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2134 case llvm::Triple::NetBSD:
2135 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2136 case llvm::Triple::OpenBSD:
2137 return new OpenBSDI386TargetInfo(T);
2138 case llvm::Triple::FreeBSD:
2139 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
2140 case llvm::Triple::Solaris:
2141 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2142 case llvm::Triple::Cygwin:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002143 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002144 case llvm::Triple::MinGW32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002145 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002146 case llvm::Triple::Win32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002147 return new VisualStudioWindowsX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002148 default:
2149 return new X86_32TargetInfo(T);
2150 }
2151
2152 case llvm::Triple::x86_64:
2153 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002154 case llvm::Triple::AuroraUX:
2155 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002156 case llvm::Triple::Darwin:
2157 return new DarwinX86_64TargetInfo(T);
2158 case llvm::Triple::Linux:
2159 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner7a7ca282010-01-09 05:41:14 +00002160 case llvm::Triple::DragonFly:
2161 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002162 case llvm::Triple::NetBSD:
2163 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2164 case llvm::Triple::OpenBSD:
2165 return new OpenBSDX86_64TargetInfo(T);
2166 case llvm::Triple::FreeBSD:
2167 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2168 case llvm::Triple::Solaris:
2169 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002170 case llvm::Triple::MinGW64:
2171 return new MinGWX86_64TargetInfo(T);
2172 case llvm::Triple::Win32: // This is what Triple.h supports now.
2173 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002174 default:
2175 return new X86_64TargetInfo(T);
2176 }
2177 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002178}
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002179
2180/// CreateTargetInfo - Return the target info object for the specified target
2181/// triple.
2182TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002183 TargetOptions &Opts) {
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002184 llvm::Triple Triple(Opts.Triple);
2185
2186 // Construct the target
2187 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2188 if (!Target) {
2189 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2190 return 0;
2191 }
2192
Daniel Dunbareac7c532009-12-18 18:42:37 +00002193 // Set the target CPU if specified.
2194 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2195 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2196 return 0;
2197 }
2198
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002199 // Set the target ABI if specified.
2200 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2201 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2202 return 0;
2203 }
2204
2205 // Compute the default target features, we need the target to handle this
2206 // because features may have dependencies on one another.
2207 llvm::StringMap<bool> Features;
2208 Target->getDefaultFeatures(Opts.CPU, Features);
2209
2210 // Apply the user specified deltas.
2211 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2212 ie = Opts.Features.end(); it != ie; ++it) {
2213 const char *Name = it->c_str();
2214
2215 // Apply the feature via the target.
2216 if ((Name[0] != '-' && Name[0] != '+') ||
2217 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2218 Diags.Report(diag::err_target_invalid_feature) << Name;
2219 return 0;
2220 }
2221 }
2222
2223 // Add the features to the compile options.
2224 //
2225 // FIXME: If we are completely confident that we have the right set, we only
2226 // need to pass the minuses.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002227 Opts.Features.clear();
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002228 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2229 ie = Features.end(); it != ie; ++it)
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002230 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2231 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002232
2233 return Target.take();
2234}