blob: 541a1ed59545117e4864200c16cad05d4d0e2bba [file] [log] [blame]
Chris Lattner5ba61f02006-10-14 07:39:34 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner5ba61f02006-10-14 07:39:34 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenek6f6ff372007-12-12 18:05:32 +000011// target triple.
Chris Lattner5ba61f02006-10-14 07:39:34 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner5ba61f02006-10-14 07:39:34 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000016#include "clang/Basic/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
Chris Lattnerc7c6dd42008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Chandler Carruth26b29a02010-01-20 06:13:02 +000019#include "clang/Basic/MacroBuilder.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000020#include "clang/Basic/TargetBuiltins.h"
21#include "clang/Basic/TargetOptions.h"
Eli Friedman7cef49e2008-05-20 14:27:34 +000022#include "llvm/ADT/APFloat.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000023#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000024#include "llvm/ADT/STLExtras.h"
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000025#include "llvm/ADT/StringRef.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000026#include "llvm/ADT/StringSwitch.h"
Chris Lattner859c37a2009-08-12 06:24:27 +000027#include "llvm/ADT/Triple.h"
Chris Lattner30ba6742009-08-10 19:03:04 +000028#include "llvm/MC/MCSectionMachO.h"
Dale Johannesen182addf2010-10-29 23:24:33 +000029#include "llvm/Type.h"
Benjamin Kramerdc2f0062010-01-09 18:20:57 +000030#include <algorithm>
Chris Lattner5ba61f02006-10-14 07:39:34 +000031using namespace clang;
32
Chris Lattner5ba61f02006-10-14 07:39:34 +000033//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000034// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000035//===----------------------------------------------------------------------===//
36
Chris Lattner1e1c0b92009-03-20 16:06:38 +000037/// DefineStd - Define a macro name and standard variants. For example if
38/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
39/// when in GNU mode.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000040static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
Chris Lattner1e1c0b92009-03-20 16:06:38 +000041 const LangOptions &Opts) {
42 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000043
Chris Lattner1e1c0b92009-03-20 16:06:38 +000044 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
45 // in the user's namespace.
46 if (Opts.GNUMode)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000047 Builder.defineMacro(MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000048
Chris Lattner1e1c0b92009-03-20 16:06:38 +000049 // Define __unix.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000050 Builder.defineMacro("__" + MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000051
Chris Lattner1e1c0b92009-03-20 16:06:38 +000052 // Define __unix__.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000053 Builder.defineMacro("__" + MacroName + "__");
Chris Lattner1e1c0b92009-03-20 16:06:38 +000054}
55
Chris Lattner09d98f52008-10-05 21:50:58 +000056//===----------------------------------------------------------------------===//
57// Defines specific to certain operating systems.
58//===----------------------------------------------------------------------===//
Chris Lattner30ba6742009-08-10 19:03:04 +000059
Torok Edwinb2b37c62009-06-30 17:10:35 +000060namespace {
Douglas Gregorc05d2a12009-07-01 15:12:53 +000061template<typename TgtInfo>
62class OSTargetInfo : public TgtInfo {
Torok Edwinb2b37c62009-06-30 17:10:35 +000063protected:
Daniel Dunbar40165182009-08-24 09:10:05 +000064 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000065 MacroBuilder &Builder) const=0;
Torok Edwinb2b37c62009-06-30 17:10:35 +000066public:
Douglas Gregorc05d2a12009-07-01 15:12:53 +000067 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwinb2b37c62009-06-30 17:10:35 +000068 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000069 MacroBuilder &Builder) const {
70 TgtInfo::getTargetDefines(Opts, Builder);
71 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
Torok Edwin4e054162009-06-30 17:00:25 +000072 }
Torok Edwinb2b37c62009-06-30 17:10:35 +000073
74};
Chris Lattner859c37a2009-08-12 06:24:27 +000075} // end anonymous namespace
Torok Edwin4e054162009-06-30 17:00:25 +000076
Chris Lattner30ba6742009-08-10 19:03:04 +000077
Daniel Dunbard86666f2010-01-26 01:44:04 +000078static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
Douglas Gregor20b2ebd2011-03-23 00:50:03 +000079 const llvm::Triple &Triple,
80 llvm::StringRef &PlatformName,
81 VersionTuple &PlatformMinVersion) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000082 Builder.defineMacro("__APPLE_CC__", "5621");
83 Builder.defineMacro("__APPLE__");
84 Builder.defineMacro("__MACH__");
85 Builder.defineMacro("OBJC_NEW_PROPERTIES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000086
John McCall31168b02011-06-15 23:02:42 +000087 if (Opts.ObjCAutoRefCount) {
88 Builder.defineMacro("__weak", "__attribute__((objc_lifetime(weak)))");
89 Builder.defineMacro("__strong", "__attribute__((objc_lifetime(strong)))");
90 Builder.defineMacro("__autoreleasing",
91 "__attribute__((objc_lifetime(autoreleasing)))");
92 Builder.defineMacro("__unsafe_unretained",
93 "__attribute__((objc_lifetime(none)))");
94 } else {
95 // __weak is always defined, for use in blocks and with objc pointers.
96 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000097
John McCall31168b02011-06-15 23:02:42 +000098 // Darwin defines __strong even in C mode (just to nothing).
99 if (Opts.getGCMode() != LangOptions::NonGC)
100 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
101 else
102 Builder.defineMacro("__strong", "");
103
104 // __unsafe_unretained is defined to nothing in non-ARC mode. We even
105 // allow this in C, since one might have block pointers in structs that
106 // are used in pure C code and in Objective-C ARC.
107 Builder.defineMacro("__unsafe_unretained", "");
108
109 // The Objective-C bridged cast keywords are defined to nothing in non-ARC
110 // mode; then they become normal, C-style casts.
111 Builder.defineMacro("__bridge", "");
112 Builder.defineMacro("__bridge_transfer", "");
113 Builder.defineMacro("__bridge_retained", "");
114 }
115
Eli Friedmanfd4b1552009-06-04 23:00:29 +0000116 if (Opts.Static)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000117 Builder.defineMacro("__STATIC__");
Eli Friedmanfd4b1552009-06-04 23:00:29 +0000118 else
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000119 Builder.defineMacro("__DYNAMIC__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000120
121 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000122 Builder.defineMacro("_REENTRANT");
Daniel Dunbar497ff132009-04-10 19:52:24 +0000123
Daniel Dunbarecf13562011-04-19 21:40:34 +0000124 // Get the platform type and version number from the triple.
Daniel Dunbar497ff132009-04-10 19:52:24 +0000125 unsigned Maj, Min, Rev;
Mike Stump11289f42009-09-09 15:08:12 +0000126
Daniel Dunbard86666f2010-01-26 01:44:04 +0000127 // If no version was given, default to to 10.4.0, for simplifying tests.
Daniel Dunbarecf13562011-04-19 21:40:34 +0000128 if (Triple.getOSName() == "darwin" || Triple.getOSName() == "osx") {
129 PlatformName = "macosx";
Daniel Dunbard86666f2010-01-26 01:44:04 +0000130 Min = Rev = 0;
131 Maj = 8;
Daniel Dunbarecf13562011-04-19 21:40:34 +0000132 } else {
133 // Otherwise, honor all three triple forms ("-darwinNNN[-iphoneos]",
134 // "-osxNNN", and "-iosNNN").
135
136 if (Triple.getOS() == llvm::Triple::Darwin) {
137 // For historical reasons that make little sense, the version passed here
138 // is the "darwin" version, which drops the 10 and offsets by 4.
139 Triple.getOSVersion(Maj, Min, Rev);
140
141 if (Triple.getEnvironmentName() == "iphoneos") {
142 PlatformName = "ios";
143 } else {
Daniel Dunbarecf13562011-04-19 21:40:34 +0000144 PlatformName = "macosx";
145 Rev = Min;
146 Min = Maj - 4;
147 Maj = 10;
148 }
Daniel Dunbarecf13562011-04-19 21:40:34 +0000149 } else {
Daniel Dunbarecf13562011-04-19 21:40:34 +0000150 Triple.getOSVersion(Maj, Min, Rev);
Daniel Dunbarfcd23892011-04-19 23:34:21 +0000151 PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
Daniel Dunbarecf13562011-04-19 21:40:34 +0000152 }
153 }
Daniel Dunbard86666f2010-01-26 01:44:04 +0000154
155 // Set the appropriate OS version define.
Daniel Dunbarecf13562011-04-19 21:40:34 +0000156 if (PlatformName == "ios") {
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000157 assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
Daniel Dunbard86666f2010-01-26 01:44:04 +0000158 char Str[6];
159 Str[0] = '0' + Maj;
160 Str[1] = '0' + (Min / 10);
161 Str[2] = '0' + (Min % 10);
162 Str[3] = '0' + (Rev / 10);
163 Str[4] = '0' + (Rev % 10);
164 Str[5] = '\0';
165 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
166 } else {
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000167 // Note that the Driver allows versions which aren't representable in the
168 // define (because we only get a single digit for the minor and micro
169 // revision numbers). So, we limit them to the maximum representable
170 // version.
Daniel Dunbard86666f2010-01-26 01:44:04 +0000171 assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000172 assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
Daniel Dunbard86666f2010-01-26 01:44:04 +0000173 char Str[5];
174 Str[0] = '0' + (Maj / 10);
175 Str[1] = '0' + (Maj % 10);
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000176 Str[2] = '0' + std::min(Min, 9U);
177 Str[3] = '0' + std::min(Rev, 9U);
Daniel Dunbard86666f2010-01-26 01:44:04 +0000178 Str[4] = '\0';
179 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
Daniel Dunbar497ff132009-04-10 19:52:24 +0000180 }
Daniel Dunbarecf13562011-04-19 21:40:34 +0000181
182 PlatformMinVersion = VersionTuple(Maj, Min, Rev);
Eli Friedman3fd920a2008-08-20 02:34:37 +0000183}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000184
Chris Lattner30ba6742009-08-10 19:03:04 +0000185namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000186template<typename Target>
187class DarwinTargetInfo : public OSTargetInfo<Target> {
188protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000189 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000190 MacroBuilder &Builder) const {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000191 getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
192 this->PlatformMinVersion);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000193 }
Mike Stump11289f42009-09-09 15:08:12 +0000194
Torok Edwinb2b37c62009-06-30 17:10:35 +0000195public:
196 DarwinTargetInfo(const std::string& triple) :
197 OSTargetInfo<Target>(triple) {
Eric Christopher17c7b892010-06-25 19:04:52 +0000198 this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;
Daniel Dunbar13adc7f2011-02-21 23:12:51 +0000199 this->MCountName = "\01mcount";
Torok Edwinb2b37c62009-06-30 17:10:35 +0000200 }
201
Anders Carlsson0b0a1222010-01-30 18:33:31 +0000202 virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
Chris Lattner30ba6742009-08-10 19:03:04 +0000203 // Let MCSectionMachO validate this.
204 llvm::StringRef Segment, Section;
205 unsigned TAA, StubSize;
Daniel Dunbar75942372011-03-19 02:06:21 +0000206 bool HasTAA;
Chris Lattner30ba6742009-08-10 19:03:04 +0000207 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
Daniel Dunbar75942372011-03-19 02:06:21 +0000208 TAA, HasTAA, StubSize);
Chris Lattner30ba6742009-08-10 19:03:04 +0000209 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000210
Anders Carlsson851318a2010-06-08 22:47:50 +0000211 virtual const char *getStaticInitSectionSpecifier() const {
212 // FIXME: We should return 0 when building kexts.
213 return "__TEXT,__StaticInit,regular,pure_instructions";
214 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000215
Torok Edwinb2b37c62009-06-30 17:10:35 +0000216};
217
Chris Lattner30ba6742009-08-10 19:03:04 +0000218
Torok Edwinb2b37c62009-06-30 17:10:35 +0000219// DragonFlyBSD Target
220template<typename Target>
221class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
222protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000223 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000224 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000225 // DragonFly defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000226 Builder.defineMacro("__DragonFly__");
227 Builder.defineMacro("__DragonFly_cc_version", "100001");
228 Builder.defineMacro("__ELF__");
229 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
230 Builder.defineMacro("__tune_i386__");
231 DefineStd(Builder, "unix", Opts);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000232 }
233public:
Mike Stump11289f42009-09-09 15:08:12 +0000234 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000235 : OSTargetInfo<Target>(triple) {}
236};
237
238// FreeBSD Target
239template<typename Target>
240class FreeBSDTargetInfo : public OSTargetInfo<Target> {
241protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000242 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000243 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000244 // FreeBSD defines; list based off of gcc output
245
Daniel Dunbar40165182009-08-24 09:10:05 +0000246 // FIXME: Move version number handling to llvm::Triple.
Benjamin Kramer31a68e72010-01-30 19:55:01 +0000247 llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000248
Benjamin Kramer31a68e72010-01-30 19:55:01 +0000249 Builder.defineMacro("__FreeBSD__", Release);
250 Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000251 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
252 DefineStd(Builder, "unix", Opts);
253 Builder.defineMacro("__ELF__");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000254 }
255public:
Mike Stump11289f42009-09-09 15:08:12 +0000256 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands9cb27e92009-07-08 13:55:08 +0000257 : OSTargetInfo<Target>(triple) {
258 this->UserLabelPrefix = "";
Roman Divacky178e01602011-02-10 16:52:03 +0000259
260 llvm::Triple Triple(triple);
261 switch (Triple.getArch()) {
262 default:
263 case llvm::Triple::x86:
264 case llvm::Triple::x86_64:
265 this->MCountName = ".mcount";
266 break;
267 case llvm::Triple::mips:
268 case llvm::Triple::mipsel:
269 case llvm::Triple::ppc:
270 case llvm::Triple::ppc64:
271 this->MCountName = "_mcount";
272 break;
273 case llvm::Triple::arm:
274 this->MCountName = "__mcount";
275 break;
276 }
277
Duncan Sands9cb27e92009-07-08 13:55:08 +0000278 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000279};
280
Chris Lattner3e2ee142010-07-07 16:01:42 +0000281// Minix Target
282template<typename Target>
283class MinixTargetInfo : public OSTargetInfo<Target> {
284protected:
285 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
286 MacroBuilder &Builder) const {
287 // Minix defines
288
289 Builder.defineMacro("__minix", "3");
290 Builder.defineMacro("_EM_WSIZE", "4");
291 Builder.defineMacro("_EM_PSIZE", "4");
292 Builder.defineMacro("_EM_SSIZE", "2");
293 Builder.defineMacro("_EM_LSIZE", "4");
294 Builder.defineMacro("_EM_FSIZE", "4");
295 Builder.defineMacro("_EM_DSIZE", "8");
296 DefineStd(Builder, "unix", Opts);
297 }
298public:
299 MinixTargetInfo(const std::string &triple)
300 : OSTargetInfo<Target>(triple) {
301 this->UserLabelPrefix = "";
302 }
303};
304
Torok Edwinb2b37c62009-06-30 17:10:35 +0000305// Linux target
306template<typename Target>
307class LinuxTargetInfo : public OSTargetInfo<Target> {
308protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000309 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000310 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000311 // Linux defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000312 DefineStd(Builder, "unix", Opts);
313 DefineStd(Builder, "linux", Opts);
314 Builder.defineMacro("__gnu_linux__");
315 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000316 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000317 Builder.defineMacro("_REENTRANT");
Douglas Gregor3ecc6652010-04-21 05:52:38 +0000318 if (Opts.CPlusPlus)
319 Builder.defineMacro("_GNU_SOURCE");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000320 }
321public:
Mike Stump11289f42009-09-09 15:08:12 +0000322 LinuxTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000323 : OSTargetInfo<Target>(triple) {
324 this->UserLabelPrefix = "";
Douglas Gregore6d6e512011-01-12 21:19:25 +0000325 this->WIntType = TargetInfo::UnsignedInt;
Torok Edwinb2b37c62009-06-30 17:10:35 +0000326 }
327};
328
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000329// NetBSD Target
330template<typename Target>
331class NetBSDTargetInfo : public OSTargetInfo<Target> {
332protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000333 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000334 MacroBuilder &Builder) const {
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000335 // NetBSD defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000336 Builder.defineMacro("__NetBSD__");
337 Builder.defineMacro("__unix__");
338 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000339 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000340 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000341 }
342public:
Mike Stump11289f42009-09-09 15:08:12 +0000343 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000344 : OSTargetInfo<Target>(triple) {
345 this->UserLabelPrefix = "";
346 }
347};
348
Torok Edwinb2b37c62009-06-30 17:10:35 +0000349// OpenBSD Target
350template<typename Target>
351class OpenBSDTargetInfo : public OSTargetInfo<Target> {
352protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000353 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000354 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000355 // OpenBSD defines; list based off of gcc output
356
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000357 Builder.defineMacro("__OpenBSD__");
358 DefineStd(Builder, "unix", Opts);
359 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000360 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000361 Builder.defineMacro("_POSIX_THREADS");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000362 }
363public:
Mike Stump11289f42009-09-09 15:08:12 +0000364 OpenBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000365 : OSTargetInfo<Target>(triple) {}
366};
367
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000368// PSP Target
369template<typename Target>
370class PSPTargetInfo : public OSTargetInfo<Target> {
371protected:
372 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000373 MacroBuilder &Builder) const {
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000374 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000375 Builder.defineMacro("PSP");
376 Builder.defineMacro("_PSP");
377 Builder.defineMacro("__psp__");
378 Builder.defineMacro("__ELF__");
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000379 }
380public:
381 PSPTargetInfo(const std::string& triple)
382 : OSTargetInfo<Target>(triple) {
383 this->UserLabelPrefix = "";
384 }
385};
386
John Thompsone467e192009-11-19 17:18:50 +0000387// PS3 PPU Target
388template<typename Target>
389class PS3PPUTargetInfo : public OSTargetInfo<Target> {
390protected:
391 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000392 MacroBuilder &Builder) const {
John Thompsone467e192009-11-19 17:18:50 +0000393 // PS3 PPU defines.
John Thompson957816f2010-03-25 16:18:32 +0000394 Builder.defineMacro("__PPC__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000395 Builder.defineMacro("__PPU__");
396 Builder.defineMacro("__CELLOS_LV2__");
397 Builder.defineMacro("__ELF__");
398 Builder.defineMacro("__LP32__");
John Thompson07a61a42010-06-24 22:44:13 +0000399 Builder.defineMacro("_ARCH_PPC64");
400 Builder.defineMacro("__powerpc64__");
John Thompsone467e192009-11-19 17:18:50 +0000401 }
402public:
403 PS3PPUTargetInfo(const std::string& triple)
404 : OSTargetInfo<Target>(triple) {
405 this->UserLabelPrefix = "";
John Thompson6f8dba72009-12-18 14:21:08 +0000406 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
John Thompson07a61a42010-06-24 22:44:13 +0000407 this->IntMaxType = TargetInfo::SignedLongLong;
408 this->UIntMaxType = TargetInfo::UnsignedLongLong;
409 this->Int64Type = TargetInfo::SignedLongLong;
John Thompson6f8dba72009-12-18 14:21:08 +0000410 this->SizeType = TargetInfo::UnsignedInt;
John Thompson07a61a42010-06-24 22:44:13 +0000411 this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
412 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
John Thompsone467e192009-11-19 17:18:50 +0000413 }
414};
415
416// FIXME: Need a real SPU target.
417// PS3 SPU Target
418template<typename Target>
419class PS3SPUTargetInfo : public OSTargetInfo<Target> {
420protected:
421 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000422 MacroBuilder &Builder) const {
John Thompsone467e192009-11-19 17:18:50 +0000423 // PS3 PPU defines.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000424 Builder.defineMacro("__SPU__");
425 Builder.defineMacro("__ELF__");
John Thompsone467e192009-11-19 17:18:50 +0000426 }
427public:
428 PS3SPUTargetInfo(const std::string& triple)
429 : OSTargetInfo<Target>(triple) {
430 this->UserLabelPrefix = "";
431 }
432};
433
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000434// AuroraUX target
435template<typename Target>
436class AuroraUXTargetInfo : public OSTargetInfo<Target> {
437protected:
438 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000439 MacroBuilder &Builder) const {
440 DefineStd(Builder, "sun", Opts);
441 DefineStd(Builder, "unix", Opts);
442 Builder.defineMacro("__ELF__");
443 Builder.defineMacro("__svr4__");
444 Builder.defineMacro("__SVR4");
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000445 }
446public:
447 AuroraUXTargetInfo(const std::string& triple)
448 : OSTargetInfo<Target>(triple) {
449 this->UserLabelPrefix = "";
450 this->WCharType = this->SignedLong;
451 // FIXME: WIntType should be SignedLong
452 }
453};
454
Torok Edwinb2b37c62009-06-30 17:10:35 +0000455// Solaris target
456template<typename Target>
457class SolarisTargetInfo : public OSTargetInfo<Target> {
458protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000459 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000460 MacroBuilder &Builder) const {
461 DefineStd(Builder, "sun", Opts);
462 DefineStd(Builder, "unix", Opts);
463 Builder.defineMacro("__ELF__");
464 Builder.defineMacro("__svr4__");
465 Builder.defineMacro("__SVR4");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000466 }
467public:
Mike Stump11289f42009-09-09 15:08:12 +0000468 SolarisTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000469 : OSTargetInfo<Target>(triple) {
470 this->UserLabelPrefix = "";
471 this->WCharType = this->SignedLong;
472 // FIXME: WIntType should be SignedLong
473 }
474};
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000475
476// Windows target
477template<typename Target>
478class WindowsTargetInfo : public OSTargetInfo<Target> {
479protected:
480 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
481 MacroBuilder &Builder) const {
Michael J. Spencer54bf3c32010-10-21 08:22:51 +0000482 Builder.defineMacro("_WIN32");
483 }
484 void getVisualStudioDefines(const LangOptions &Opts,
485 MacroBuilder &Builder) const {
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000486 if (Opts.CPlusPlus) {
487 if (Opts.RTTI)
488 Builder.defineMacro("_CPPRTTI");
489
490 if (Opts.Exceptions)
491 Builder.defineMacro("_CPPUNWIND");
492 }
493
494 if (!Opts.CharIsSigned)
495 Builder.defineMacro("_CHAR_UNSIGNED");
496
497 // FIXME: POSIXThreads isn't exactly the option this should be defined for,
498 // but it works for now.
499 if (Opts.POSIXThreads)
500 Builder.defineMacro("_MT");
Michael J. Spencer54bf3c32010-10-21 08:22:51 +0000501
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000502 if (Opts.MSCVersion != 0)
503 Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
504
505 if (Opts.Microsoft) {
506 Builder.defineMacro("_MSC_EXTENSIONS");
507
508 if (Opts.CPlusPlus0x) {
509 Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
510 Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
511 Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
512 }
513 }
514
515 Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000516 }
517
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000518public:
519 WindowsTargetInfo(const std::string &triple)
520 : OSTargetInfo<Target>(triple) {}
521};
522
Mike Stump11289f42009-09-09 15:08:12 +0000523} // end anonymous namespace.
Torok Edwinb2b37c62009-06-30 17:10:35 +0000524
Chris Lattner09d98f52008-10-05 21:50:58 +0000525//===----------------------------------------------------------------------===//
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000526// Specific target implementations.
527//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000528
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000529namespace {
530// PPC abstract base class
531class PPCTargetInfo : public TargetInfo {
532 static const Builtin::Info BuiltinInfo[];
533 static const char * const GCCRegNames[];
534 static const TargetInfo::GCCRegAlias GCCRegAliases[];
535
536public:
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000537 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
538
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000539 virtual void getTargetBuiltins(const Builtin::Info *&Records,
540 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000541 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000542 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000543 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000544
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000545 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000546 MacroBuilder &Builder) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000547
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000548 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000549 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000550 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000551 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000552 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000553 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000554 switch (*Name) {
Anders Carlssonf511f642007-11-27 04:11:28 +0000555 default: return false;
556 case 'O': // Zero
John Thompson07a61a42010-06-24 22:44:13 +0000557 break;
Anders Carlssonf511f642007-11-27 04:11:28 +0000558 case 'b': // Base register
559 case 'f': // Floating point register
Chris Lattnerd9725f72009-04-26 07:16:29 +0000560 Info.setAllowsRegister();
John Thompson07a61a42010-06-24 22:44:13 +0000561 break;
562 // FIXME: The following are added to allow parsing.
563 // I just took a guess at what the actions should be.
564 // Also, is more specific checking needed? I.e. specific registers?
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000565 case 'd': // Floating point register (containing 64-bit value)
John Thompson07a61a42010-06-24 22:44:13 +0000566 case 'v': // Altivec vector register
567 Info.setAllowsRegister();
568 break;
569 case 'w':
570 switch (Name[1]) {
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000571 case 'd':// VSX vector register to hold vector double data
572 case 'f':// VSX vector register to hold vector float data
573 case 's':// VSX vector register to hold scalar float data
574 case 'a':// Any VSX register
John Thompson07a61a42010-06-24 22:44:13 +0000575 break;
576 default:
577 return false;
578 }
579 Info.setAllowsRegister();
580 Name++; // Skip over 'w'.
581 break;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000582 case 'h': // `MQ', `CTR', or `LINK' register
583 case 'q': // `MQ' register
584 case 'c': // `CTR' register
585 case 'l': // `LINK' register
586 case 'x': // `CR' register (condition register) number 0
587 case 'y': // `CR' register (condition register)
588 case 'z': // `XER[CA]' carry bit (part of the XER register)
John Thompson07a61a42010-06-24 22:44:13 +0000589 Info.setAllowsRegister();
590 break;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000591 case 'I': // Signed 16-bit constant
John Thompson07a61a42010-06-24 22:44:13 +0000592 case 'J': // Unsigned 16-bit constant shifted left 16 bits
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000593 // (use `L' instead for SImode constants)
594 case 'K': // Unsigned 16-bit constant
595 case 'L': // Signed 16-bit constant shifted left 16 bits
596 case 'M': // Constant larger than 31
597 case 'N': // Exact power of 2
598 case 'P': // Constant whose negation is a signed 16-bit constant
John Thompson07a61a42010-06-24 22:44:13 +0000599 case 'G': // Floating point constant that can be loaded into a
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000600 // register with one instruction per word
John Thompson07a61a42010-06-24 22:44:13 +0000601 case 'H': // Integer/Floating point constant that can be loaded
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000602 // into a register using three instructions
John Thompson07a61a42010-06-24 22:44:13 +0000603 break;
604 case 'm': // Memory operand. Note that on PowerPC targets, m can
605 // include addresses that update the base register. It
606 // is therefore only safe to use `m' in an asm statement
607 // if that asm statement accesses the operand exactly once.
608 // The asm statement must also use `%U<opno>' as a
Sebastian Redldd008712010-08-17 22:42:34 +0000609 // placeholder for the "update" flag in the corresponding
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000610 // load or store instruction. For example:
John Thompson07a61a42010-06-24 22:44:13 +0000611 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000612 // is correct but:
John Thompson07a61a42010-06-24 22:44:13 +0000613 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
614 // is not. Use es rather than m if you don't want the base
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000615 // register to be updated.
616 case 'e':
John Thompsonceebdf12010-06-25 00:02:05 +0000617 if (Name[1] != 's')
618 return false;
Sebastian Redldd008712010-08-17 22:42:34 +0000619 // es: A "stable" memory operand; that is, one which does not
John Thompson07a61a42010-06-24 22:44:13 +0000620 // include any automodification of the base register. Unlike
621 // `m', this constraint can be used in asm statements that
622 // might access the operand several times, or that might not
John Thompsonceebdf12010-06-25 00:02:05 +0000623 // access it at all.
John Thompson07a61a42010-06-24 22:44:13 +0000624 Info.setAllowsMemory();
John Thompsonceebdf12010-06-25 00:02:05 +0000625 Name++; // Skip over 'e'.
John Thompson07a61a42010-06-24 22:44:13 +0000626 break;
627 case 'Q': // Memory operand that is an offset from a register (it is
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000628 // usually better to use `m' or `es' in asm statements)
John Thompson07a61a42010-06-24 22:44:13 +0000629 case 'Z': // Memory operand that is an indexed or indirect from a
630 // register (it is usually better to use `m' or `es' in
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000631 // asm statements)
John Thompson07a61a42010-06-24 22:44:13 +0000632 Info.setAllowsMemory();
633 Info.setAllowsRegister();
634 break;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000635 case 'R': // AIX TOC entry
John Thompson07a61a42010-06-24 22:44:13 +0000636 case 'a': // Address operand that is an indexed or indirect from a
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000637 // register (`p' is preferable for asm statements)
638 case 'S': // Constant suitable as a 64-bit mask operand
639 case 'T': // Constant suitable as a 32-bit mask operand
640 case 'U': // System V Release 4 small data area reference
John Thompson07a61a42010-06-24 22:44:13 +0000641 case 't': // AND masks that can be performed by two rldic{l, r}
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000642 // instructions
643 case 'W': // Vector constant that does not require memory
644 case 'j': // Vector constant that is all zeros.
John Thompson07a61a42010-06-24 22:44:13 +0000645 break;
646 // End FIXME.
Anders Carlssonf511f642007-11-27 04:11:28 +0000647 }
John Thompson07a61a42010-06-24 22:44:13 +0000648 return true;
Anders Carlssonf511f642007-11-27 04:11:28 +0000649 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000650 virtual const char *getClobbers() const {
651 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000652 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000653};
Anders Carlssonf511f642007-11-27 04:11:28 +0000654
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000655const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Fariborz Jahaniane8473c22010-11-30 17:35:24 +0000656#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
657#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
658 ALL_LANGUAGES, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000659#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000660};
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000661
662
Chris Lattnerecd49032009-03-02 22:27:17 +0000663/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
664/// #defines that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000665void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000666 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000667 // Target identification.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000668 Builder.defineMacro("__ppc__");
669 Builder.defineMacro("_ARCH_PPC");
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000670 Builder.defineMacro("__powerpc__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000671 Builder.defineMacro("__POWERPC__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000672 if (PointerWidth == 64) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000673 Builder.defineMacro("_ARCH_PPC64");
674 Builder.defineMacro("_LP64");
675 Builder.defineMacro("__LP64__");
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000676 Builder.defineMacro("__powerpc64__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000677 Builder.defineMacro("__ppc64__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000678 } else {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000679 Builder.defineMacro("__ppc__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000680 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000681
Chris Lattnerecd49032009-03-02 22:27:17 +0000682 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000683 Builder.defineMacro("_BIG_ENDIAN");
684 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000685
Chris Lattnerecd49032009-03-02 22:27:17 +0000686 // Subtarget options.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000687 Builder.defineMacro("__NATURAL_ALIGNMENT__");
688 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000689
Chris Lattnerecd49032009-03-02 22:27:17 +0000690 // FIXME: Should be controlled by command line option.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000691 Builder.defineMacro("__LONG_DOUBLE_128__");
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000692
John Thompsone467e192009-11-19 17:18:50 +0000693 if (Opts.AltiVec) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000694 Builder.defineMacro("__VEC__", "10206");
695 Builder.defineMacro("__ALTIVEC__");
John Thompsone467e192009-11-19 17:18:50 +0000696 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000697}
698
Chris Lattner17df24e2008-04-21 18:56:49 +0000699
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000700const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000701 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
702 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
703 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
704 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
705 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
706 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
707 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
708 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000709 "mq", "lr", "ctr", "ap",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000710 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000711 "xer",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000712 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
713 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
714 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
715 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000716 "vrsave", "vscr",
717 "spe_acc", "spefscr",
718 "sfp"
719};
Chris Lattner10a5b382007-01-29 05:24:35 +0000720
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000721void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000722 unsigned &NumNames) const {
723 Names = GCCRegNames;
724 NumNames = llvm::array_lengthof(GCCRegNames);
725}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000726
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000727const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
728 // While some of these aliases do map to different registers
729 // they still share the same register name.
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000730 { { "0" }, "r0" },
731 { { "1"}, "r1" },
732 { { "2" }, "r2" },
733 { { "3" }, "r3" },
734 { { "4" }, "r4" },
735 { { "5" }, "r5" },
736 { { "6" }, "r6" },
737 { { "7" }, "r7" },
738 { { "8" }, "r8" },
739 { { "9" }, "r9" },
740 { { "10" }, "r10" },
741 { { "11" }, "r11" },
742 { { "12" }, "r12" },
743 { { "13" }, "r13" },
744 { { "14" }, "r14" },
745 { { "15" }, "r15" },
746 { { "16" }, "r16" },
747 { { "17" }, "r17" },
748 { { "18" }, "r18" },
749 { { "19" }, "r19" },
750 { { "20" }, "r20" },
751 { { "21" }, "r21" },
752 { { "22" }, "r22" },
753 { { "23" }, "r23" },
754 { { "24" }, "r24" },
755 { { "25" }, "r25" },
756 { { "26" }, "r26" },
757 { { "27" }, "r27" },
758 { { "28" }, "r28" },
759 { { "29" }, "r29" },
760 { { "30" }, "r30" },
761 { { "31" }, "r31" },
762 { { "fr0" }, "f0" },
763 { { "fr1" }, "f1" },
764 { { "fr2" }, "f2" },
765 { { "fr3" }, "f3" },
766 { { "fr4" }, "f4" },
767 { { "fr5" }, "f5" },
768 { { "fr6" }, "f6" },
769 { { "fr7" }, "f7" },
770 { { "fr8" }, "f8" },
771 { { "fr9" }, "f9" },
Mike Stumpfaacf012009-09-17 21:15:00 +0000772 { { "fr10" }, "f10" },
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000773 { { "fr11" }, "f11" },
774 { { "fr12" }, "f12" },
775 { { "fr13" }, "f13" },
776 { { "fr14" }, "f14" },
777 { { "fr15" }, "f15" },
778 { { "fr16" }, "f16" },
779 { { "fr17" }, "f17" },
780 { { "fr18" }, "f18" },
781 { { "fr19" }, "f19" },
782 { { "fr20" }, "f20" },
783 { { "fr21" }, "f21" },
784 { { "fr22" }, "f22" },
785 { { "fr23" }, "f23" },
786 { { "fr24" }, "f24" },
787 { { "fr25" }, "f25" },
788 { { "fr26" }, "f26" },
789 { { "fr27" }, "f27" },
790 { { "fr28" }, "f28" },
791 { { "fr29" }, "f29" },
792 { { "fr30" }, "f30" },
793 { { "fr31" }, "f31" },
794 { { "cc" }, "cr0" },
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000795};
796
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000797void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000798 unsigned &NumAliases) const {
799 Aliases = GCCRegAliases;
800 NumAliases = llvm::array_lengthof(GCCRegAliases);
801}
802} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000803
Chris Lattner5ba61f02006-10-14 07:39:34 +0000804namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000805class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000806public:
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000807 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedman873f65a2008-08-21 00:13:15 +0000808 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000809 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000810
811 if (getTriple().getOS() == llvm::Triple::FreeBSD)
Roman Divacky965b0b72011-01-06 08:27:10 +0000812 SizeType = UnsignedInt;
813 }
814
815 virtual const char *getVAListDeclaration() const {
816 // This is the ELF definition, and is overridden by the Darwin sub-target
817 return "typedef struct __va_list_tag {"
818 " unsigned char gpr;"
819 " unsigned char fpr;"
820 " unsigned short reserved;"
821 " void* overflow_arg_area;"
822 " void* reg_save_area;"
823 "} __builtin_va_list[1];";
Eli Friedman873f65a2008-08-21 00:13:15 +0000824 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000825};
826} // end anonymous namespace.
827
828namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000829class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000830public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000831 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000832 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2857ccb2009-07-01 03:36:11 +0000833 IntMaxType = SignedLong;
834 UIntMaxType = UnsignedLong;
835 Int64Type = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000836 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000837 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000838 }
Roman Divacky965b0b72011-01-06 08:27:10 +0000839 virtual const char *getVAListDeclaration() const {
840 return "typedef char* __builtin_va_list;";
841 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000842};
843} // end anonymous namespace.
844
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000845
846namespace {
Roman Divacky965b0b72011-01-06 08:27:10 +0000847class DarwinPPC32TargetInfo :
848 public DarwinTargetInfo<PPC32TargetInfo> {
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000849public:
Roman Divacky965b0b72011-01-06 08:27:10 +0000850 DarwinPPC32TargetInfo(const std::string& triple)
851 : DarwinTargetInfo<PPC32TargetInfo>(triple) {
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000852 HasAlignMac68kSupport = true;
Roman Divacky965b0b72011-01-06 08:27:10 +0000853 BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
854 }
855 virtual const char *getVAListDeclaration() const {
856 return "typedef char* __builtin_va_list;";
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000857 }
858};
859
860class DarwinPPC64TargetInfo :
861 public DarwinTargetInfo<PPC64TargetInfo> {
862public:
863 DarwinPPC64TargetInfo(const std::string& triple)
864 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
865 HasAlignMac68kSupport = true;
866 }
867};
868} // end anonymous namespace.
869
Chris Lattner5ba61f02006-10-14 07:39:34 +0000870namespace {
Justin Holewinski514cce82011-04-20 19:34:15 +0000871 class PTXTargetInfo : public TargetInfo {
872 static const char * const GCCRegNames[];
873 static const Builtin::Info BuiltinInfo[];
874 public:
875 PTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
876 TLSSupported = false;
877 LongWidth = LongAlign = 64;
878 }
879 virtual void getTargetDefines(const LangOptions &Opts,
880 MacroBuilder &Builder) const {
881 Builder.defineMacro("__PTX__");
882 }
883 virtual void getTargetBuiltins(const Builtin::Info *&Records,
884 unsigned &NumRecords) const {
885 Records = BuiltinInfo;
886 NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
887 }
888
889 virtual void getGCCRegNames(const char * const *&Names,
890 unsigned &NumNames) const;
891 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
892 unsigned &NumAliases) const {
893 // No aliases.
894 Aliases = 0;
895 NumAliases = 0;
896 }
897 virtual bool validateAsmConstraint(const char *&Name,
898 TargetInfo::ConstraintInfo &info) const {
899 // FIXME: implement
900 return true;
901 }
902 virtual const char *getClobbers() const {
903 // FIXME: Is this really right?
904 return "";
905 }
906 virtual const char *getVAListDeclaration() const {
907 // FIXME: implement
908 return "typedef char* __builtin_va_list;";
909 }
910 };
911
912 const Builtin::Info PTXTargetInfo::BuiltinInfo[] = {
913#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
914#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
915 ALL_LANGUAGES, false },
916#include "clang/Basic/BuiltinsPTX.def"
917 };
918
919 const char * const PTXTargetInfo::GCCRegNames[] = {
920 "r0"
921 };
922
923 void PTXTargetInfo::getGCCRegNames(const char * const *&Names,
924 unsigned &NumNames) const {
925 Names = GCCRegNames;
926 NumNames = llvm::array_lengthof(GCCRegNames);
927 }
928
929
930 class PTX32TargetInfo : public PTXTargetInfo {
931 public:
932 PTX32TargetInfo(const std::string& triple) : PTXTargetInfo(triple) {
933 PointerWidth = PointerAlign = 32;
934 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
935 DescriptionString
936 = "e-p:32:32-i64:64:64-f64:64:64-n1:8:16:32:64";
937 }
938 };
939
940 class PTX64TargetInfo : public PTXTargetInfo {
941 public:
942 PTX64TargetInfo(const std::string& triple) : PTXTargetInfo(triple) {
943 PointerWidth = PointerAlign = 64;
944 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
945 DescriptionString
946 = "e-p:64:64-i64:64:64-f64:64:64-n1:8:16:32:64";
947 }
948 };
949}
950
951namespace {
Chris Lattner5178f562010-03-06 21:21:27 +0000952// MBlaze abstract base class
953class MBlazeTargetInfo : public TargetInfo {
954 static const char * const GCCRegNames[];
955 static const TargetInfo::GCCRegAlias GCCRegAliases[];
956
957public:
958 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
Wesley Peck69bf1282010-12-12 20:56:47 +0000959 DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
Chris Lattner5178f562010-03-06 21:21:27 +0000960 }
961
962 virtual void getTargetBuiltins(const Builtin::Info *&Records,
963 unsigned &NumRecords) const {
964 // FIXME: Implement.
965 Records = 0;
966 NumRecords = 0;
967 }
968
969 virtual void getTargetDefines(const LangOptions &Opts,
970 MacroBuilder &Builder) const;
971
972 virtual const char *getVAListDeclaration() const {
973 return "typedef char* __builtin_va_list;";
974 }
975 virtual const char *getTargetPrefix() const {
976 return "mblaze";
977 }
978 virtual void getGCCRegNames(const char * const *&Names,
979 unsigned &NumNames) const;
980 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
981 unsigned &NumAliases) const;
982 virtual bool validateAsmConstraint(const char *&Name,
983 TargetInfo::ConstraintInfo &Info) const {
984 switch (*Name) {
985 default: return false;
986 case 'O': // Zero
987 return true;
988 case 'b': // Base register
989 case 'f': // Floating point register
990 Info.setAllowsRegister();
991 return true;
992 }
993 }
994 virtual const char *getClobbers() const {
995 return "";
996 }
997};
998
999/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
1000/// #defines that are not tied to a specific subtarget.
1001void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
1002 MacroBuilder &Builder) const {
1003 // Target identification.
1004 Builder.defineMacro("__microblaze__");
1005 Builder.defineMacro("_ARCH_MICROBLAZE");
1006 Builder.defineMacro("__MICROBLAZE__");
1007
1008 // Target properties.
1009 Builder.defineMacro("_BIG_ENDIAN");
1010 Builder.defineMacro("__BIG_ENDIAN__");
1011
1012 // Subtarget options.
1013 Builder.defineMacro("__REGISTER_PREFIX__", "");
1014}
1015
1016
1017const char * const MBlazeTargetInfo::GCCRegNames[] = {
1018 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1019 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1020 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1021 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1022 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
1023 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
1024 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
1025 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
1026 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
1027 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
1028};
1029
1030void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
1031 unsigned &NumNames) const {
1032 Names = GCCRegNames;
1033 NumNames = llvm::array_lengthof(GCCRegNames);
1034}
1035
1036const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
1037 { {"f0"}, "r0" },
1038 { {"f1"}, "r1" },
1039 { {"f2"}, "r2" },
1040 { {"f3"}, "r3" },
1041 { {"f4"}, "r4" },
1042 { {"f5"}, "r5" },
1043 { {"f6"}, "r6" },
1044 { {"f7"}, "r7" },
1045 { {"f8"}, "r8" },
1046 { {"f9"}, "r9" },
1047 { {"f10"}, "r10" },
1048 { {"f11"}, "r11" },
1049 { {"f12"}, "r12" },
1050 { {"f13"}, "r13" },
1051 { {"f14"}, "r14" },
1052 { {"f15"}, "r15" },
1053 { {"f16"}, "r16" },
1054 { {"f17"}, "r17" },
1055 { {"f18"}, "r18" },
1056 { {"f19"}, "r19" },
1057 { {"f20"}, "r20" },
1058 { {"f21"}, "r21" },
1059 { {"f22"}, "r22" },
1060 { {"f23"}, "r23" },
1061 { {"f24"}, "r24" },
1062 { {"f25"}, "r25" },
1063 { {"f26"}, "r26" },
1064 { {"f27"}, "r27" },
1065 { {"f28"}, "r28" },
1066 { {"f29"}, "r29" },
1067 { {"f30"}, "r30" },
1068 { {"f31"}, "r31" },
1069};
1070
1071void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1072 unsigned &NumAliases) const {
1073 Aliases = GCCRegAliases;
1074 NumAliases = llvm::array_lengthof(GCCRegAliases);
1075}
1076} // end anonymous namespace.
1077
1078namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001079// Namespace for x86 abstract base class
1080const Builtin::Info BuiltinInfo[] = {
Fariborz Jahaniane8473c22010-11-30 17:35:24 +00001081#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
1082#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1083 ALL_LANGUAGES, false },
Chris Lattner5abdec72009-06-14 01:05:48 +00001084#include "clang/Basic/BuiltinsX86.def"
Eli Friedman3fd920a2008-08-20 02:34:37 +00001085};
Eli Friedmanb5366062008-05-20 14:21:01 +00001086
Nuno Lopescfca1f02009-12-23 17:49:57 +00001087static const char* const GCCRegNames[] = {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001088 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
1089 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
1090 "argp", "flags", "fspr", "dirflag", "frame",
1091 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
1092 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
1093 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1094 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
1095};
1096
1097const TargetInfo::GCCRegAlias GCCRegAliases[] = {
1098 { { "al", "ah", "eax", "rax" }, "ax" },
1099 { { "bl", "bh", "ebx", "rbx" }, "bx" },
1100 { { "cl", "ch", "ecx", "rcx" }, "cx" },
1101 { { "dl", "dh", "edx", "rdx" }, "dx" },
1102 { { "esi", "rsi" }, "si" },
1103 { { "edi", "rdi" }, "di" },
1104 { { "esp", "rsp" }, "sp" },
1105 { { "ebp", "rbp" }, "bp" },
1106};
1107
1108// X86 target abstract base class; x86-32 and x86-64 are very close, so
1109// most of the implementation can be shared.
1110class X86TargetInfo : public TargetInfo {
Chris Lattner96e43572009-03-02 22:40:39 +00001111 enum X86SSEEnum {
1112 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
1113 } SSELevel;
Anders Carlssone437c682010-01-27 03:47:49 +00001114 enum AMD3DNowEnum {
1115 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
1116 } AMD3DNowLevel;
1117
Eric Christophere1ddaf92010-04-02 23:50:19 +00001118 bool HasAES;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001119 bool HasAVX;
1120
Eli Friedman3fd920a2008-08-20 02:34:37 +00001121public:
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001122 X86TargetInfo(const std::string& triple)
Eric Christophere1ddaf92010-04-02 23:50:19 +00001123 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001124 HasAES(false), HasAVX(false) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001125 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +00001126 }
Chris Lattner10a5b382007-01-29 05:24:35 +00001127 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1128 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001129 Records = BuiltinInfo;
1130 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +00001131 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001132 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +00001133 unsigned &NumNames) const {
1134 Names = GCCRegNames;
1135 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001136 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001137 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001138 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001139 Aliases = GCCRegAliases;
1140 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +00001141 }
Anders Carlsson58436352009-02-28 17:11:49 +00001142 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +00001143 TargetInfo::ConstraintInfo &info) const;
Stuart Hastings7fdc6702011-06-07 23:45:05 +00001144 virtual std::string convertConstraint(const char *&Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +00001145 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001146 return "~{dirflag},~{fpsr},~{flags}";
1147 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001148 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001149 MacroBuilder &Builder) const;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001150 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1151 const std::string &Name,
1152 bool Enabled) const;
Mike Stump11289f42009-09-09 15:08:12 +00001153 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001154 llvm::StringMap<bool> &Features) const;
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00001155 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Chris Lattner5ba61f02006-10-14 07:39:34 +00001156};
Chris Lattnerc25d8a72009-03-02 22:20:04 +00001157
Mike Stump11289f42009-09-09 15:08:12 +00001158void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001159 llvm::StringMap<bool> &Features) const {
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001160 // FIXME: This should not be here.
1161 Features["3dnow"] = false;
1162 Features["3dnowa"] = false;
1163 Features["mmx"] = false;
1164 Features["sse"] = false;
1165 Features["sse2"] = false;
1166 Features["sse3"] = false;
1167 Features["ssse3"] = false;
1168 Features["sse41"] = false;
1169 Features["sse42"] = false;
Eric Christophere1ddaf92010-04-02 23:50:19 +00001170 Features["aes"] = false;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001171 Features["avx"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001172
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001173 // LLVM does not currently recognize this.
1174 // Features["sse4a"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001175
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001176 // FIXME: This *really* should not be here.
1177
1178 // X86_64 always has SSE2.
1179 if (PointerWidth == 64)
1180 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
1181
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001182 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
1183 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
1184 ;
1185 else if (CPU == "pentium-mmx" || CPU == "pentium2")
1186 setFeatureEnabled(Features, "mmx", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001187 else if (CPU == "pentium3")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001188 setFeatureEnabled(Features, "sse", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001189 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001190 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001191 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001192 setFeatureEnabled(Features, "sse3", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001193 else if (CPU == "core2")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001194 setFeatureEnabled(Features, "ssse3", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001195 else if (CPU == "penryn") {
1196 setFeatureEnabled(Features, "sse4", true);
1197 Features["sse42"] = false;
1198 } else if (CPU == "atom")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001199 setFeatureEnabled(Features, "sse3", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001200 else if (CPU == "corei7") {
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001201 setFeatureEnabled(Features, "sse4", true);
Eric Christophere1ddaf92010-04-02 23:50:19 +00001202 setFeatureEnabled(Features, "aes", true);
Benjamin Kramer85e16642011-05-20 15:11:23 +00001203 } else if (CPU == "corei7-avx") {
Roman Divacky27ec14f2011-04-05 20:32:44 +00001204 setFeatureEnabled(Features, "sse4", true);
1205 setFeatureEnabled(Features, "aes", true);
1206// setFeatureEnabled(Features, "avx", true);
1207 } else if (CPU == "k6" || CPU == "winchip-c6")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001208 setFeatureEnabled(Features, "mmx", true);
Mike Stump11289f42009-09-09 15:08:12 +00001209 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001210 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
1211 setFeatureEnabled(Features, "mmx", true);
1212 setFeatureEnabled(Features, "3dnow", true);
1213 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
1214 setFeatureEnabled(Features, "sse", true);
1215 setFeatureEnabled(Features, "3dnowa", true);
1216 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
1217 CPU == "athlon-fx") {
Mike Stump11289f42009-09-09 15:08:12 +00001218 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001219 setFeatureEnabled(Features, "3dnowa", true);
Roman Divackydacbfe42010-12-29 13:28:29 +00001220 } else if (CPU == "k8-sse3") {
1221 setFeatureEnabled(Features, "sse3", true);
1222 setFeatureEnabled(Features, "3dnowa", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001223 } else if (CPU == "c3-2")
1224 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001225}
1226
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001227bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump11289f42009-09-09 15:08:12 +00001228 const std::string &Name,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001229 bool Enabled) const {
Eric Christopher399ffa52010-03-04 02:26:37 +00001230 // FIXME: This *really* should not be here. We need some way of translating
1231 // options into llvm subtarget features.
1232 if (!Features.count(Name) &&
1233 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001234 return false;
1235
1236 if (Enabled) {
1237 if (Name == "mmx")
1238 Features["mmx"] = true;
1239 else if (Name == "sse")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001240 Features["mmx"] = Features["sse"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001241 else if (Name == "sse2")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001242 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001243 else if (Name == "sse3")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001244 Features["mmx"] = Features["sse"] = Features["sse2"] =
1245 Features["sse3"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001246 else if (Name == "ssse3")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001247 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001248 Features["ssse3"] = true;
Eric Christopher399ffa52010-03-04 02:26:37 +00001249 else if (Name == "sse4" || Name == "sse4.2")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001250 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001251 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopher399ffa52010-03-04 02:26:37 +00001252 else if (Name == "sse4.1")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001253 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Eric Christopher399ffa52010-03-04 02:26:37 +00001254 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001255 else if (Name == "3dnow")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001256 Features["3dnowa"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001257 else if (Name == "3dnowa")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001258 Features["3dnow"] = Features["3dnowa"] = true;
Eric Christophere1ddaf92010-04-02 23:50:19 +00001259 else if (Name == "aes")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001260 Features["aes"] = true;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001261 else if (Name == "avx")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001262 Features["avx"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001263 } else {
1264 if (Name == "mmx")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001265 Features["mmx"] = Features["3dnow"] = Features["3dnowa"] =
1266 Features["sse"] = Features["sse2"] = Features["sse3"] =
1267 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001268 else if (Name == "sse")
Mike Stump11289f42009-09-09 15:08:12 +00001269 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001270 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001271 else if (Name == "sse2")
Mike Stump11289f42009-09-09 15:08:12 +00001272 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001273 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001274 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +00001275 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001276 Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001277 else if (Name == "ssse3")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001278 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Michael J. Spencera9e41172011-04-17 19:22:03 +00001279 else if (Name == "sse4" || Name == "sse4.1")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001280 Features["sse41"] = Features["sse42"] = false;
Eric Christophercfeceff2010-03-04 02:31:44 +00001281 else if (Name == "sse4.2")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001282 Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001283 else if (Name == "3dnow")
1284 Features["3dnow"] = Features["3dnowa"] = false;
1285 else if (Name == "3dnowa")
1286 Features["3dnowa"] = false;
Eric Christophere1ddaf92010-04-02 23:50:19 +00001287 else if (Name == "aes")
1288 Features["aes"] = false;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001289 else if (Name == "avx")
1290 Features["avx"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001291 }
1292
1293 return true;
1294}
1295
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001296/// HandleTargetOptions - Perform initialization based on the user
1297/// configured set of features.
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00001298void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar979586e2009-11-11 09:38:56 +00001299 // Remember the maximum enabled sselevel.
1300 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
1301 // Ignore disabled features.
1302 if (Features[i][0] == '-')
1303 continue;
1304
Eric Christophere1ddaf92010-04-02 23:50:19 +00001305 if (Features[i].substr(1) == "aes") {
1306 HasAES = true;
1307 continue;
1308 }
1309
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001310 // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
1311 // For now let it be enabled together with other SSE levels.
1312 if (Features[i].substr(1) == "avx") {
1313 HasAVX = true;
1314 continue;
1315 }
1316
Daniel Dunbar979586e2009-11-11 09:38:56 +00001317 assert(Features[i][0] == '+' && "Invalid target feature!");
1318 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
1319 .Case("sse42", SSE42)
1320 .Case("sse41", SSE41)
1321 .Case("ssse3", SSSE3)
Nuno Lopes4cbc8bd2010-03-12 10:20:09 +00001322 .Case("sse3", SSE3)
Daniel Dunbar979586e2009-11-11 09:38:56 +00001323 .Case("sse2", SSE2)
1324 .Case("sse", SSE1)
1325 .Case("mmx", MMX)
1326 .Default(NoMMXSSE);
1327 SSELevel = std::max(SSELevel, Level);
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001328
1329 AMD3DNowEnum ThreeDNowLevel =
Anders Carlssone437c682010-01-27 03:47:49 +00001330 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
1331 .Case("3dnowa", AMD3DNowAthlon)
1332 .Case("3dnow", AMD3DNow)
1333 .Default(NoAMD3DNow);
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001334
Anders Carlssone437c682010-01-27 03:47:49 +00001335 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar979586e2009-11-11 09:38:56 +00001336 }
Chris Lattnerc25d8a72009-03-02 22:20:04 +00001337}
Chris Lattnerecd49032009-03-02 22:27:17 +00001338
1339/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
1340/// that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001341void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001342 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001343 // Target identification.
1344 if (PointerWidth == 64) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001345 Builder.defineMacro("_LP64");
1346 Builder.defineMacro("__LP64__");
1347 Builder.defineMacro("__amd64__");
1348 Builder.defineMacro("__amd64");
1349 Builder.defineMacro("__x86_64");
1350 Builder.defineMacro("__x86_64__");
Chris Lattnerecd49032009-03-02 22:27:17 +00001351 } else {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001352 DefineStd(Builder, "i386", Opts);
Chris Lattnerecd49032009-03-02 22:27:17 +00001353 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001354
Eric Christophere1ddaf92010-04-02 23:50:19 +00001355 if (HasAES)
1356 Builder.defineMacro("__AES__");
1357
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001358 if (HasAVX)
1359 Builder.defineMacro("__AVX__");
1360
Chris Lattnerecd49032009-03-02 22:27:17 +00001361 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001362 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001363
Chris Lattnerecd49032009-03-02 22:27:17 +00001364 // Subtarget options.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001365 Builder.defineMacro("__nocona");
1366 Builder.defineMacro("__nocona__");
1367 Builder.defineMacro("__tune_nocona__");
1368 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner96e43572009-03-02 22:40:39 +00001369
Chris Lattner6df41af2009-04-19 17:32:33 +00001370 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
1371 // functions in glibc header files that use FP Stack inline asm which the
1372 // backend can't deal with (PR879).
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001373 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001374
Chris Lattner96e43572009-03-02 22:40:39 +00001375 // Each case falls through to the previous one here.
1376 switch (SSELevel) {
1377 case SSE42:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001378 Builder.defineMacro("__SSE4_2__");
Chris Lattner96e43572009-03-02 22:40:39 +00001379 case SSE41:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001380 Builder.defineMacro("__SSE4_1__");
Chris Lattner96e43572009-03-02 22:40:39 +00001381 case SSSE3:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001382 Builder.defineMacro("__SSSE3__");
Chris Lattner96e43572009-03-02 22:40:39 +00001383 case SSE3:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001384 Builder.defineMacro("__SSE3__");
Chris Lattner96e43572009-03-02 22:40:39 +00001385 case SSE2:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001386 Builder.defineMacro("__SSE2__");
1387 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner96e43572009-03-02 22:40:39 +00001388 case SSE1:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001389 Builder.defineMacro("__SSE__");
1390 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner96e43572009-03-02 22:40:39 +00001391 case MMX:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001392 Builder.defineMacro("__MMX__");
Chris Lattner96e43572009-03-02 22:40:39 +00001393 case NoMMXSSE:
1394 break;
1395 }
Michael J. Spencerfeb799c2010-10-18 07:10:59 +00001396
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001397 if (Opts.Microsoft && PointerWidth == 32) {
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001398 switch (SSELevel) {
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001399 case SSE42:
1400 case SSE41:
1401 case SSSE3:
1402 case SSE3:
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001403 case SSE2:
1404 Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
1405 break;
1406 case SSE1:
1407 Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
1408 break;
1409 default:
1410 Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
1411 }
1412 }
1413
Anders Carlssone437c682010-01-27 03:47:49 +00001414 // Each case falls through to the previous one here.
1415 switch (AMD3DNowLevel) {
1416 case AMD3DNowAthlon:
1417 Builder.defineMacro("__3dNOW_A__");
1418 case AMD3DNow:
1419 Builder.defineMacro("__3dNOW__");
1420 case NoAMD3DNow:
1421 break;
1422 }
Chris Lattnerecd49032009-03-02 22:27:17 +00001423}
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001424
1425
Eli Friedman3fd920a2008-08-20 02:34:37 +00001426bool
Anders Carlsson58436352009-02-28 17:11:49 +00001427X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00001428 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +00001429 switch (*Name) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001430 default: return false;
Dale Johannesen46742a42010-08-24 22:33:12 +00001431 case 'Y': // first letter of a pair:
1432 switch (*(Name+1)) {
1433 default: return false;
1434 case '0': // First SSE register.
1435 case 't': // Any SSE register, when SSE2 is enabled.
1436 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1437 case 'm': // any MMX register, when inter-unit moves enabled.
1438 break; // falls through to setAllowsRegister.
1439 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001440 case 'a': // eax.
1441 case 'b': // ebx.
1442 case 'c': // ecx.
1443 case 'd': // edx.
1444 case 'S': // esi.
1445 case 'D': // edi.
1446 case 'A': // edx:eax.
Dale Johannesen46742a42010-08-24 22:33:12 +00001447 case 'f': // any x87 floating point stack register.
Eli Friedman3fd920a2008-08-20 02:34:37 +00001448 case 't': // top of floating point stack.
1449 case 'u': // second from top of floating point stack.
1450 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +00001451 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +00001452 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +00001453 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Dale Johannesen46742a42010-08-24 22:33:12 +00001454 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1455 case 'l': // "Index" registers: any general register that can be used as an
1456 // index in a base+index memory access.
1457 Info.setAllowsRegister();
1458 return true;
1459 case 'C': // SSE floating point constant.
1460 case 'G': // x87 floating point constant.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001461 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +00001462 // x86_64 instructions.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001463 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +00001464 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +00001465 return true;
1466 }
Dale Johannesen46742a42010-08-24 22:33:12 +00001467 return false;
Eli Friedman3fd920a2008-08-20 02:34:37 +00001468}
1469
Dale Johannesen7d3dfc02010-10-29 23:12:32 +00001470
Eli Friedman3fd920a2008-08-20 02:34:37 +00001471std::string
Stuart Hastings7fdc6702011-06-07 23:45:05 +00001472X86TargetInfo::convertConstraint(const char *&Constraint) const {
1473 switch (*Constraint) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001474 case 'a': return std::string("{ax}");
1475 case 'b': return std::string("{bx}");
1476 case 'c': return std::string("{cx}");
1477 case 'd': return std::string("{dx}");
1478 case 'S': return std::string("{si}");
1479 case 'D': return std::string("{di}");
Dale Johannesen70f564e2010-10-22 21:07:10 +00001480 case 'p': // address
1481 return std::string("im");
Eli Friedman3fd920a2008-08-20 02:34:37 +00001482 case 't': // top of floating point stack.
1483 return std::string("{st}");
1484 case 'u': // second from top of floating point stack.
1485 return std::string("{st(1)}"); // second from top of floating point stack.
1486 default:
Stuart Hastings7fdc6702011-06-07 23:45:05 +00001487 return std::string(1, *Constraint);
Eli Friedman3fd920a2008-08-20 02:34:37 +00001488 }
1489}
Eli Friedman3fd920a2008-08-20 02:34:37 +00001490} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +00001491
1492namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001493// X86-32 generic target
1494class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +00001495public:
Eli Friedman3fd920a2008-08-20 02:34:37 +00001496 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
1497 DoubleAlign = LongLongAlign = 32;
1498 LongDoubleWidth = 96;
1499 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +00001500 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1501 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001502 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman32ca82a2009-03-29 20:31:09 +00001503 SizeType = UnsignedInt;
1504 PtrDiffType = SignedInt;
1505 IntPtrType = SignedInt;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001506 RegParmMax = 3;
Daniel Dunbar6f2e8392010-07-14 23:39:36 +00001507
1508 // Use fpret for all types.
1509 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
1510 (1 << TargetInfo::Double) |
1511 (1 << TargetInfo::LongDouble));
Eli Friedman3fd920a2008-08-20 02:34:37 +00001512 }
1513 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001514 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +00001515 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001516
Chris Lattnerd545ad12009-09-23 06:06:36 +00001517 int getEHDataRegisterNumber(unsigned RegNo) const {
1518 if (RegNo == 0) return 0;
1519 if (RegNo == 1) return 2;
1520 return -1;
1521 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001522};
1523} // end anonymous namespace
1524
1525namespace {
Eli Friedmane3aa4542009-07-05 18:47:56 +00001526class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
1527public:
1528 OpenBSDI386TargetInfo(const std::string& triple) :
1529 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
1530 SizeType = UnsignedLong;
1531 IntPtrType = SignedLong;
Eli Friedman245f2292009-07-05 22:31:18 +00001532 PtrDiffType = SignedLong;
Eli Friedmane3aa4542009-07-05 18:47:56 +00001533 }
1534};
1535} // end anonymous namespace
1536
1537namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +00001538class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001539public:
Torok Edwinb2b37c62009-06-30 17:10:35 +00001540 DarwinI386TargetInfo(const std::string& triple) :
1541 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001542 LongDoubleWidth = 128;
1543 LongDoubleAlign = 128;
Eli Friedman32ca82a2009-03-29 20:31:09 +00001544 SizeType = UnsignedLong;
1545 IntPtrType = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +00001546 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1547 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001548 "a0:0:64-f80:128:128-n8:16:32";
Daniel Dunbarbd606522010-05-27 00:35:16 +00001549 HasAlignMac68kSupport = true;
Torok Edwin4e054162009-06-30 17:00:25 +00001550 }
1551
Eli Friedman3fd920a2008-08-20 02:34:37 +00001552};
Daniel Dunbar10de9e62009-06-29 20:52:51 +00001553} // end anonymous namespace
1554
1555namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001556// x86-32 Windows target
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001557class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001558public:
1559 WindowsX86_32TargetInfo(const std::string& triple)
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001560 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +00001561 TLSSupported = false;
Chris Lattner46be2e12009-06-24 17:12:15 +00001562 WCharType = UnsignedShort;
Eli Friedmanebb9e4d2009-06-08 21:16:17 +00001563 DoubleAlign = LongLongAlign = 64;
1564 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Anton Korobeynikovd7e4a092009-12-19 02:05:07 +00001565 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1566 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001567 }
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001568 virtual void getTargetDefines(const LangOptions &Opts,
1569 MacroBuilder &Builder) const {
1570 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
1571 }
1572};
1573} // end anonymous namespace
1574
1575namespace {
1576
1577// x86-32 Windows Visual Studio target
1578class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1579public:
1580 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1581 : WindowsX86_32TargetInfo(triple) {
Eli Friedman015d6282011-03-22 21:25:11 +00001582 LongDoubleWidth = LongDoubleAlign = 64;
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001583 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1584 }
1585 virtual void getTargetDefines(const LangOptions &Opts,
1586 MacroBuilder &Builder) const {
1587 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1588 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
1589 // The value of the following reflects processor type.
1590 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1591 // We lost the original triple, so we use the default.
1592 Builder.defineMacro("_M_IX86", "600");
1593 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001594};
1595} // end anonymous namespace
1596
1597namespace {
1598// x86-32 MinGW target
1599class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1600public:
1601 MinGWX86_32TargetInfo(const std::string& triple)
1602 : WindowsX86_32TargetInfo(triple) {
1603 }
1604 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001605 MacroBuilder &Builder) const {
1606 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001607 DefineStd(Builder, "WIN32", Opts);
1608 DefineStd(Builder, "WINNT", Opts);
1609 Builder.defineMacro("_X86_");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001610 Builder.defineMacro("__MSVCRT__");
1611 Builder.defineMacro("__MINGW32__");
NAKAMURA Takumib2beb012011-03-15 02:32:50 +00001612
1613 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
1614 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
1615 if (Opts.Microsoft)
1616 // Provide "as-is" __declspec.
1617 Builder.defineMacro("__declspec", "__declspec");
1618 else
1619 // Provide alias of __attribute__ like mingw32-gcc.
1620 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001621 }
1622};
1623} // end anonymous namespace
1624
1625namespace {
1626// x86-32 Cygwin target
1627class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1628public:
1629 CygwinX86_32TargetInfo(const std::string& triple)
1630 : X86_32TargetInfo(triple) {
1631 TLSSupported = false;
1632 WCharType = UnsignedShort;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001633 DoubleAlign = LongLongAlign = 64;
1634 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1635 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001636 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001637 }
1638 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001639 MacroBuilder &Builder) const {
1640 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1641 Builder.defineMacro("__CYGWIN__");
1642 Builder.defineMacro("__CYGWIN32__");
1643 DefineStd(Builder, "unix", Opts);
Douglas Gregor3ecc6652010-04-21 05:52:38 +00001644 if (Opts.CPlusPlus)
1645 Builder.defineMacro("_GNU_SOURCE");
Eli Friedmanaa27a872009-06-08 06:11:14 +00001646 }
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001647};
1648} // end anonymous namespace
1649
1650namespace {
Chris Lattnerb986aba2010-04-11 19:29:39 +00001651// x86-32 Haiku target
1652class HaikuX86_32TargetInfo : public X86_32TargetInfo {
1653public:
1654 HaikuX86_32TargetInfo(const std::string& triple)
1655 : X86_32TargetInfo(triple) {
1656 SizeType = UnsignedLong;
Chris Lattner8b290212010-04-22 17:48:00 +00001657 IntPtrType = SignedLong;
1658 PtrDiffType = SignedLong;
Rafael Espindolac55be6d2010-11-09 16:41:02 +00001659 this->UserLabelPrefix = "";
Eli Friedman04831922010-08-22 01:00:03 +00001660 }
Chris Lattnerb986aba2010-04-11 19:29:39 +00001661 virtual void getTargetDefines(const LangOptions &Opts,
1662 MacroBuilder &Builder) const {
1663 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1664 Builder.defineMacro("__INTEL__");
1665 Builder.defineMacro("__HAIKU__");
1666 }
1667};
1668} // end anonymous namespace
1669
1670namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001671// x86-64 generic target
1672class X86_64TargetInfo : public X86TargetInfo {
1673public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001674 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +00001675 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +00001676 LongDoubleWidth = 128;
1677 LongDoubleAlign = 128;
Rafael Espindolae971b9a2010-06-04 23:15:27 +00001678 LargeArrayMinWidth = 128;
1679 LargeArrayAlign = 128;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001680 IntMaxType = SignedLong;
1681 UIntMaxType = UnsignedLong;
Eli Friedman2857ccb2009-07-01 03:36:11 +00001682 Int64Type = SignedLong;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001683 RegParmMax = 6;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001684
Eli Friedman873f65a2008-08-21 00:13:15 +00001685 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1686 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001687 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Daniel Dunbar6f2e8392010-07-14 23:39:36 +00001688
1689 // Use fpret only for long double.
1690 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
Chris Lattner10a5b382007-01-29 05:24:35 +00001691 }
Anders Carlssona7408e72007-10-13 00:45:48 +00001692 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001693 return "typedef struct __va_list_tag {"
1694 " unsigned gp_offset;"
1695 " unsigned fp_offset;"
1696 " void* overflow_arg_area;"
1697 " void* reg_save_area;"
John McCall61d82582010-05-28 18:25:28 +00001698 "} __va_list_tag;"
Eli Friedmanfb36b022009-07-03 00:45:06 +00001699 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001700 }
Michael J. Spencerfeb799c2010-10-18 07:10:59 +00001701
Chris Lattnerd545ad12009-09-23 06:06:36 +00001702 int getEHDataRegisterNumber(unsigned RegNo) const {
1703 if (RegNo == 0) return 0;
1704 if (RegNo == 1) return 1;
1705 return -1;
1706 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001707};
1708} // end anonymous namespace
1709
1710namespace {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001711// x86-64 Windows target
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001712class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001713public:
1714 WindowsX86_64TargetInfo(const std::string& triple)
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001715 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001716 TLSSupported = false;
1717 WCharType = UnsignedShort;
Mike Stumpaf9afe92009-10-08 23:00:00 +00001718 LongWidth = LongAlign = 32;
Michael J. Spencerfeb799c2010-10-18 07:10:59 +00001719 DoubleAlign = LongLongAlign = 64;
Nate Begeman6e8865a2010-07-21 02:02:56 +00001720 IntMaxType = SignedLongLong;
1721 UIntMaxType = UnsignedLongLong;
1722 Int64Type = SignedLongLong;
Cameron Esfahanieb856502010-09-15 00:28:12 +00001723 SizeType = UnsignedLongLong;
1724 PtrDiffType = SignedLongLong;
1725 IntPtrType = SignedLongLong;
NAKAMURA Takumif7c30222011-01-17 22:56:08 +00001726 this->UserLabelPrefix = "";
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001727 }
1728 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001729 MacroBuilder &Builder) const {
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001730 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001731 Builder.defineMacro("_WIN64");
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001732 }
NAKAMURA Takumia2e468c2011-01-17 22:56:23 +00001733 virtual const char *getVAListDeclaration() const {
1734 return "typedef char* __builtin_va_list;";
1735 }
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001736};
1737} // end anonymous namespace
1738
1739namespace {
1740// x86-64 Windows Visual Studio target
1741class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1742public:
1743 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1744 : WindowsX86_64TargetInfo(triple) {
Eli Friedman015d6282011-03-22 21:25:11 +00001745 LongDoubleWidth = LongDoubleAlign = 64;
1746 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001747 }
1748 virtual void getTargetDefines(const LangOptions &Opts,
1749 MacroBuilder &Builder) const {
1750 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1751 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001752 Builder.defineMacro("_M_X64");
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001753 Builder.defineMacro("_M_AMD64");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001754 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001755};
1756} // end anonymous namespace
1757
1758namespace {
1759// x86-64 MinGW target
1760class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1761public:
1762 MinGWX86_64TargetInfo(const std::string& triple)
1763 : WindowsX86_64TargetInfo(triple) {
1764 }
1765 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001766 MacroBuilder &Builder) const {
1767 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001768 DefineStd(Builder, "WIN64", Opts);
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001769 Builder.defineMacro("__MSVCRT__");
NAKAMURA Takumi2b7eeb22011-03-08 12:06:46 +00001770 Builder.defineMacro("__MINGW32__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001771 Builder.defineMacro("__MINGW64__");
NAKAMURA Takumib2beb012011-03-15 02:32:50 +00001772
1773 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
1774 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
1775 if (Opts.Microsoft)
1776 // Provide "as-is" __declspec.
1777 Builder.defineMacro("__declspec", "__declspec");
1778 else
1779 // Provide alias of __attribute__ like mingw32-gcc.
1780 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001781 }
1782};
1783} // end anonymous namespace
1784
1785namespace {
Eli Friedman2857ccb2009-07-01 03:36:11 +00001786class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1787public:
Mike Stump11289f42009-09-09 15:08:12 +00001788 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman2857ccb2009-07-01 03:36:11 +00001789 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1790 Int64Type = SignedLongLong;
1791 }
1792};
1793} // end anonymous namespace
1794
1795namespace {
Eli Friedman245f2292009-07-05 22:31:18 +00001796class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1797public:
Mike Stump11289f42009-09-09 15:08:12 +00001798 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman245f2292009-07-05 22:31:18 +00001799 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1800 IntMaxType = SignedLongLong;
1801 UIntMaxType = UnsignedLongLong;
1802 Int64Type = SignedLongLong;
1803 }
1804};
1805} // end anonymous namespace
1806
1807namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001808class ARMTargetInfo : public TargetInfo {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001809 // Possible FPU choices.
1810 enum FPUMode {
1811 NoFPU,
1812 VFP2FPU,
1813 VFP3FPU,
1814 NeonFPU
1815 };
1816
1817 static bool FPUModeIsVFP(FPUMode Mode) {
1818 return Mode >= VFP2FPU && Mode <= NeonFPU;
1819 }
1820
1821 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1822 static const char * const GCCRegNames[];
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001823
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001824 std::string ABI, CPU;
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001825
1826 unsigned FPU : 3;
1827
Daniel Dunbar893d4752009-12-19 04:15:38 +00001828 unsigned IsThumb : 1;
1829
1830 // Initialized via features.
1831 unsigned SoftFloat : 1;
1832 unsigned SoftFloatABI : 1;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001833
Chris Lattner5cc15e02010-03-03 19:03:45 +00001834 static const Builtin::Info BuiltinInfo[];
1835
Chris Lattner17df24e2008-04-21 18:56:49 +00001836public:
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001837 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001838 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001839 {
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001840 SizeType = UnsignedInt;
1841 PtrDiffType = SignedInt;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001842
Chris Lattner1a8f3942010-04-23 16:29:58 +00001843 // {} in inline assembly are neon specifiers, not assembly variant
1844 // specifiers.
1845 NoAsmVariants = true;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001846
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001847 // FIXME: Should we just treat this as a feature?
Daniel Dunbarc454ecf2009-12-18 19:57:13 +00001848 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbar03184792009-09-22 21:44:58 +00001849 if (IsThumb) {
Sandeep Patelf87b3732011-04-04 22:58:12 +00001850 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
1851 // so set preferred for small types to 32.
Daniel Dunbar03184792009-09-22 21:44:58 +00001852 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1853 "i64:64:64-f32:32:32-f64:64:64-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001854 "v64:64:64-v128:64:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001855 } else {
1856 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1857 "i64:64:64-f32:32:32-f64:64:64-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001858 "v64:64:64-v128:64:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001859 }
John McCall86353412010-08-21 22:46:04 +00001860
1861 // ARM targets default to using the ARM C++ ABI.
1862 CXXABI = CXXABI_ARM;
Eli Friedmanb5366062008-05-20 14:21:01 +00001863 }
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001864 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001865 virtual bool setABI(const std::string &Name) {
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001866 ABI = Name;
1867
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001868 // The defaults (above) are for AAPCS, check if we need to change them.
1869 //
1870 // FIXME: We need support for -meabi... we could just mangle it into the
1871 // name.
1872 if (Name == "apcs-gnu") {
Daniel Dunbar377dc2f2010-01-27 20:23:08 +00001873 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001874 SizeType = UnsignedLong;
1875
Daniel Dunbarf8125062010-04-22 16:14:54 +00001876 // Do not respect the alignment of bit-field types when laying out
1877 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
1878 UseBitFieldTypeAlignment = false;
1879
Daniel Dunbar03184792009-09-22 21:44:58 +00001880 if (IsThumb) {
Sandeep Patelf87b3732011-04-04 22:58:12 +00001881 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
1882 // so set preferred for small types to 32.
Daniel Dunbar03184792009-09-22 21:44:58 +00001883 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1884 "i64:32:32-f32:32:32-f64:32:32-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001885 "v64:32:64-v128:32:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001886 } else {
1887 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001888 "i64:32:64-f32:32:32-f64:32:64-"
1889 "v64:32:64-v128:32:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001890 }
1891
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001892 // FIXME: Override "preferred align" for double and long long.
1893 } else if (Name == "aapcs") {
1894 // FIXME: Enumerated types are variable width in straight AAPCS.
1895 } else if (Name == "aapcs-linux") {
1896 ;
1897 } else
1898 return false;
1899
1900 return true;
1901 }
Daniel Dunbar893d4752009-12-19 04:15:38 +00001902
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001903 void getDefaultFeatures(const std::string &CPU,
1904 llvm::StringMap<bool> &Features) const {
1905 // FIXME: This should not be here.
1906 Features["vfp2"] = false;
1907 Features["vfp3"] = false;
1908 Features["neon"] = false;
1909
1910 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1911 Features["vfp2"] = true;
1912 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1913 Features["neon"] = true;
1914 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001915
Daniel Dunbar893d4752009-12-19 04:15:38 +00001916 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1917 const std::string &Name,
1918 bool Enabled) const {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001919 if (Name == "soft-float" || Name == "soft-float-abi") {
1920 Features[Name] = Enabled;
1921 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1922 // These effectively are a single option, reset them when any is enabled.
1923 if (Enabled)
1924 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1925 Features[Name] = Enabled;
1926 } else
Daniel Dunbar893d4752009-12-19 04:15:38 +00001927 return false;
1928
Daniel Dunbar893d4752009-12-19 04:15:38 +00001929 return true;
1930 }
1931
1932 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001933 FPU = NoFPU;
Daniel Dunbar893d4752009-12-19 04:15:38 +00001934 SoftFloat = SoftFloatABI = false;
1935 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1936 if (Features[i] == "+soft-float")
1937 SoftFloat = true;
1938 else if (Features[i] == "+soft-float-abi")
1939 SoftFloatABI = true;
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001940 else if (Features[i] == "+vfp2")
1941 FPU = VFP2FPU;
1942 else if (Features[i] == "+vfp3")
1943 FPU = VFP3FPU;
1944 else if (Features[i] == "+neon")
1945 FPU = NeonFPU;
Daniel Dunbar893d4752009-12-19 04:15:38 +00001946 }
1947
1948 // Remove front-end specific options which the backend handles differently.
1949 std::vector<std::string>::iterator it;
1950 it = std::find(Features.begin(), Features.end(), "+soft-float");
1951 if (it != Features.end())
1952 Features.erase(it);
1953 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1954 if (it != Features.end())
1955 Features.erase(it);
1956 }
1957
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001958 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1959 return llvm::StringSwitch<const char*>(Name)
1960 .Cases("arm8", "arm810", "4")
1961 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1962 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1963 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1964 .Case("ep9312", "4T")
1965 .Cases("arm10tdmi", "arm1020t", "5T")
1966 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1967 .Case("arm926ej-s", "5TEJ")
1968 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1969 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001970 .Case("arm1136j-s", "6J")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001971 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001972 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001973 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1974 .Cases("cortex-a8", "cortex-a9", "7A")
Bob Wilson44acad82011-01-06 16:57:20 +00001975 .Case("cortex-m3", "7M")
Bob Wilson87ba1d32011-03-21 21:55:25 +00001976 .Case("cortex-m0", "6M")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001977 .Default(0);
1978 }
1979 virtual bool setCPU(const std::string &Name) {
1980 if (!getCPUDefineSuffix(Name))
1981 return false;
1982
1983 CPU = Name;
1984 return true;
1985 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001986 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001987 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001988 // Target identification.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001989 Builder.defineMacro("__arm");
1990 Builder.defineMacro("__arm__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001991
Chris Lattnerecd49032009-03-02 22:27:17 +00001992 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001993 Builder.defineMacro("__ARMEL__");
1994 Builder.defineMacro("__LITTLE_ENDIAN__");
1995 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001996
1997 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001998 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001999
Mike Stump9d54bd72009-04-08 02:07:04 +00002000 // Subtarget options.
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00002001
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002002 // FIXME: It's more complicated than this and we don't really support
2003 // interworking.
2004 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002005 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002006
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002007 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002008 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002009
Daniel Dunbar893d4752009-12-19 04:15:38 +00002010 if (SoftFloat)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002011 Builder.defineMacro("__SOFTFP__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002012
2013 if (CPU == "xscale")
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002014 Builder.defineMacro("__XSCALE__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00002015
Bob Wilson19c1b882011-05-13 18:56:03 +00002016 bool IsARMv7 = CPUArch.startswith("7");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00002017 if (IsThumb) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002018 Builder.defineMacro("__THUMBEL__");
2019 Builder.defineMacro("__thumb__");
Bob Wilson19c1b882011-05-13 18:56:03 +00002020 if (CPUArch == "6T2" || IsARMv7)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002021 Builder.defineMacro("__thumb2__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00002022 }
2023
2024 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002025 Builder.defineMacro("__APCS_32__");
Daniel Dunbar0def3d12009-12-21 23:28:17 +00002026
2027 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002028 Builder.defineMacro("__VFP_FP__");
Daniel Dunbar0def3d12009-12-21 23:28:17 +00002029
2030 // This only gets set when Neon instructions are actually available, unlike
2031 // the VFP define, hence the soft float and arch check. This is subtly
2032 // different from gcc, we follow the intent which was that it should be set
2033 // when Neon instructions are actually available.
Bob Wilson19c1b882011-05-13 18:56:03 +00002034 if (FPU == NeonFPU && !SoftFloat && IsARMv7)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002035 Builder.defineMacro("__ARM_NEON__");
Chris Lattner17df24e2008-04-21 18:56:49 +00002036 }
2037 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2038 unsigned &NumRecords) const {
Chris Lattner5cc15e02010-03-03 19:03:45 +00002039 Records = BuiltinInfo;
2040 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner17df24e2008-04-21 18:56:49 +00002041 }
2042 virtual const char *getVAListDeclaration() const {
John McCalle155a3d2011-05-09 02:19:37 +00002043 return "typedef void* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +00002044 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002045 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002046 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002047 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002048 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00002049 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00002050 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00002051 // FIXME: Check if this is complete
Anders Carlsson58436352009-02-28 17:11:49 +00002052 switch (*Name) {
Eli Friedmanf05b7722008-08-20 07:44:10 +00002053 default:
Nate Begeman2908fa02008-04-22 05:03:19 +00002054 case 'l': // r0-r7
2055 case 'h': // r8-r15
2056 case 'w': // VFP Floating point register single precision
2057 case 'P': // VFP Floating point register double precision
Chris Lattnerd9725f72009-04-26 07:16:29 +00002058 Info.setAllowsRegister();
Nate Begeman2908fa02008-04-22 05:03:19 +00002059 return true;
Stuart Hastings7fdc6702011-06-07 23:45:05 +00002060 case 'U': // a memory reference...
2061 switch (Name[1]) {
2062 case 'q': // ...ARMV4 ldrsb
2063 case 'v': // ...VFP load/store (reg+constant offset)
2064 case 'y': // ...iWMMXt load/store
2065 Info.setAllowsMemory();
2066 Name++;
2067 return true;
2068 }
Nate Begeman2908fa02008-04-22 05:03:19 +00002069 }
Chris Lattner17df24e2008-04-21 18:56:49 +00002070 return false;
2071 }
Stuart Hastings7fdc6702011-06-07 23:45:05 +00002072 std::string
2073 virtual convertConstraint(const char *&Constraint) const {
2074 std::string R;
2075 switch (*Constraint) {
2076 case 'U': // Two-character constraint; add "^" hint for later parsing.
Stuart Hastings5b7b11c2011-06-08 16:06:31 +00002077 R = std::string("^") + std::string(Constraint, 2);
Stuart Hastings7fdc6702011-06-07 23:45:05 +00002078 Constraint++;
2079 break;
2080 default:
2081 return std::string(1, *Constraint);
2082 }
2083 return R;
2084 }
Chris Lattner17df24e2008-04-21 18:56:49 +00002085 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00002086 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +00002087 return "";
2088 }
2089};
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002090
2091const char * const ARMTargetInfo::GCCRegNames[] = {
Daniel Dunbar9034aa32010-08-11 02:17:20 +00002092 // Integer registers
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002093 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Daniel Dunbar9034aa32010-08-11 02:17:20 +00002094 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
2095
2096 // Float registers
2097 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2098 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
2099 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002100 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
Daniel Dunbar9034aa32010-08-11 02:17:20 +00002101
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002102 // Double registers
2103 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
2104 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
Dale Johannesend2b2ad02010-10-28 01:05:37 +00002105 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
2106 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002107
2108 // Quad registers
Dale Johannesend2b2ad02010-10-28 01:05:37 +00002109 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
2110 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002111};
2112
2113void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
Daniel Dunbar256e1f32010-08-11 02:17:11 +00002114 unsigned &NumNames) const {
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002115 Names = GCCRegNames;
2116 NumNames = llvm::array_lengthof(GCCRegNames);
2117}
2118
2119const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002120 { { "a1" }, "r0" },
2121 { { "a2" }, "r1" },
2122 { { "a3" }, "r2" },
2123 { { "a4" }, "r3" },
2124 { { "v1" }, "r4" },
2125 { { "v2" }, "r5" },
2126 { { "v3" }, "r6" },
2127 { { "v4" }, "r7" },
2128 { { "v5" }, "r8" },
2129 { { "v6", "rfp" }, "r9" },
2130 { { "sl" }, "r10" },
2131 { { "fp" }, "r11" },
2132 { { "ip" }, "r12" },
Daniel Dunbar256e1f32010-08-11 02:17:11 +00002133 { { "r13" }, "sp" },
2134 { { "r14" }, "lr" },
2135 { { "r15" }, "pc" },
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002136 // The S, D and Q registers overlap, but aren't really aliases; we
2137 // don't want to substitute one of these for a different-sized one.
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002138};
2139
2140void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2141 unsigned &NumAliases) const {
2142 Aliases = GCCRegAliases;
2143 NumAliases = llvm::array_lengthof(GCCRegAliases);
2144}
Chris Lattner5cc15e02010-03-03 19:03:45 +00002145
2146const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
Fariborz Jahaniane8473c22010-11-30 17:35:24 +00002147#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
2148#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
2149 ALL_LANGUAGES, false },
Chris Lattner5cc15e02010-03-03 19:03:45 +00002150#include "clang/Basic/BuiltinsARM.def"
2151};
Chris Lattner17df24e2008-04-21 18:56:49 +00002152} // end anonymous namespace.
2153
Eli Friedmanf05b7722008-08-20 07:44:10 +00002154
2155namespace {
Mike Stump11289f42009-09-09 15:08:12 +00002156class DarwinARMTargetInfo :
Torok Edwinb2b37c62009-06-30 17:10:35 +00002157 public DarwinTargetInfo<ARMTargetInfo> {
2158protected:
Daniel Dunbar40165182009-08-24 09:10:05 +00002159 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002160 MacroBuilder &Builder) const {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002161 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
Eli Friedmand88c8a12009-04-19 21:38:35 +00002162 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00002163
Torok Edwinb2b37c62009-06-30 17:10:35 +00002164public:
Mike Stump11289f42009-09-09 15:08:12 +00002165 DarwinARMTargetInfo(const std::string& triple)
Daniel Dunbar3eeeccd2010-05-27 07:00:26 +00002166 : DarwinTargetInfo<ARMTargetInfo>(triple) {
2167 HasAlignMac68kSupport = true;
2168 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00002169};
2170} // end anonymous namespace.
2171
Chris Lattner5ba61f02006-10-14 07:39:34 +00002172namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002173class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +00002174 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2175 static const char * const GCCRegNames[];
Bruno Cardoso Lopese7f211c2010-11-09 17:21:19 +00002176 bool SoftFloat;
Gabor Greif49991682008-02-21 16:29:08 +00002177public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002178 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
2179 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +00002180 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00002181 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002182 }
Bruno Cardoso Lopese7f211c2010-11-09 17:21:19 +00002183 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
2184 const std::string &Name,
2185 bool Enabled) const {
2186 if (Name == "soft-float")
2187 Features[Name] = Enabled;
2188 else
2189 return false;
2190
2191 return true;
2192 }
2193 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
2194 SoftFloat = false;
2195 for (unsigned i = 0, e = Features.size(); i != e; ++i)
2196 if (Features[i] == "+soft-float")
2197 SoftFloat = true;
2198 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00002199 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002200 MacroBuilder &Builder) const {
2201 DefineStd(Builder, "sparc", Opts);
2202 Builder.defineMacro("__sparcv8");
2203 Builder.defineMacro("__REGISTER_PREFIX__", "");
Bruno Cardoso Lopese7f211c2010-11-09 17:21:19 +00002204
2205 if (SoftFloat)
2206 Builder.defineMacro("SOFT_FLOAT", "1");
Gabor Greif49991682008-02-21 16:29:08 +00002207 }
2208 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2209 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002210 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +00002211 }
2212 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002213 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +00002214 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002215 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00002216 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002217 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00002218 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00002219 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif49991682008-02-21 16:29:08 +00002220 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002221 // FIXME: Implement!
2222 return false;
Gabor Greif49991682008-02-21 16:29:08 +00002223 }
2224 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002225 // FIXME: Implement!
2226 return "";
Gabor Greif49991682008-02-21 16:29:08 +00002227 }
2228};
2229
Chris Lattner9b415d62009-01-27 01:58:38 +00002230const char * const SparcV8TargetInfo::GCCRegNames[] = {
2231 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2232 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2233 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2234 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
2235};
2236
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002237void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00002238 unsigned &NumNames) const {
2239 Names = GCCRegNames;
2240 NumNames = llvm::array_lengthof(GCCRegNames);
2241}
2242
2243const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002244 { { "g0" }, "r0" },
2245 { { "g1" }, "r1" },
2246 { { "g2" }, "r2" },
2247 { { "g3" }, "r3" },
2248 { { "g4" }, "r4" },
2249 { { "g5" }, "r5" },
2250 { { "g6" }, "r6" },
2251 { { "g7" }, "r7" },
2252 { { "o0" }, "r8" },
2253 { { "o1" }, "r9" },
2254 { { "o2" }, "r10" },
2255 { { "o3" }, "r11" },
2256 { { "o4" }, "r12" },
2257 { { "o5" }, "r13" },
2258 { { "o6", "sp" }, "r14" },
2259 { { "o7" }, "r15" },
2260 { { "l0" }, "r16" },
2261 { { "l1" }, "r17" },
2262 { { "l2" }, "r18" },
2263 { { "l3" }, "r19" },
2264 { { "l4" }, "r20" },
2265 { { "l5" }, "r21" },
2266 { { "l6" }, "r22" },
2267 { { "l7" }, "r23" },
2268 { { "i0" }, "r24" },
2269 { { "i1" }, "r25" },
2270 { { "i2" }, "r26" },
2271 { { "i3" }, "r27" },
2272 { { "i4" }, "r28" },
2273 { { "i5" }, "r29" },
2274 { { "i6", "fp" }, "r30" },
2275 { { "i7" }, "r31" },
Chris Lattner9b415d62009-01-27 01:58:38 +00002276};
2277
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002278void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00002279 unsigned &NumAliases) const {
2280 Aliases = GCCRegAliases;
2281 NumAliases = llvm::array_lengthof(GCCRegAliases);
2282}
Gabor Greif49991682008-02-21 16:29:08 +00002283} // end anonymous namespace.
2284
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002285namespace {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002286class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
2287public:
2288 AuroraUXSparcV8TargetInfo(const std::string& triple) :
2289 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
2290 SizeType = UnsignedInt;
2291 PtrDiffType = SignedInt;
2292 }
2293};
Torok Edwinb2b37c62009-06-30 17:10:35 +00002294class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002295public:
2296 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwinb2b37c62009-06-30 17:10:35 +00002297 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmand50881c2008-11-02 02:43:55 +00002298 SizeType = UnsignedInt;
2299 PtrDiffType = SignedInt;
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002300 }
2301};
2302} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +00002303
Chris Lattnerb781dc792008-05-08 05:58:21 +00002304namespace {
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002305 class MSP430TargetInfo : public TargetInfo {
2306 static const char * const GCCRegNames[];
2307 public:
2308 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
2309 TLSSupported = false;
Anton Korobeynikovcbc4e982010-01-30 12:55:11 +00002310 IntWidth = 16; IntAlign = 16;
2311 LongWidth = 32; LongLongWidth = 64;
2312 LongAlign = LongLongAlign = 16;
2313 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002314 SizeType = UnsignedInt;
2315 IntMaxType = SignedLong;
2316 UIntMaxType = UnsignedLong;
2317 IntPtrType = SignedShort;
2318 PtrDiffType = SignedInt;
Edward O'Callaghan847f2a12009-11-21 00:49:54 +00002319 SigAtomicType = SignedLong;
Anton Korobeynikovd94329a2009-12-19 01:32:37 +00002320 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002321 }
2322 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002323 MacroBuilder &Builder) const {
2324 Builder.defineMacro("MSP430");
2325 Builder.defineMacro("__MSP430__");
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002326 // FIXME: defines for different 'flavours' of MCU
2327 }
2328 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2329 unsigned &NumRecords) const {
2330 // FIXME: Implement.
2331 Records = 0;
2332 NumRecords = 0;
2333 }
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002334 virtual void getGCCRegNames(const char * const *&Names,
2335 unsigned &NumNames) const;
2336 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2337 unsigned &NumAliases) const {
2338 // No aliases.
2339 Aliases = 0;
2340 NumAliases = 0;
2341 }
2342 virtual bool validateAsmConstraint(const char *&Name,
2343 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov051913b2009-10-15 23:17:13 +00002344 // No target constraints for now.
2345 return false;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002346 }
2347 virtual const char *getClobbers() const {
2348 // FIXME: Is this really right?
2349 return "";
2350 }
2351 virtual const char *getVAListDeclaration() const {
2352 // FIXME: implement
Anton Korobeynikov2f910822009-05-08 18:24:57 +00002353 return "typedef char* __builtin_va_list;";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002354 }
2355 };
2356
2357 const char * const MSP430TargetInfo::GCCRegNames[] = {
2358 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2359 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2360 };
2361
2362 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
2363 unsigned &NumNames) const {
2364 Names = GCCRegNames;
2365 NumNames = llvm::array_lengthof(GCCRegNames);
2366 }
2367}
2368
2369
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002370namespace {
2371 class SystemZTargetInfo : public TargetInfo {
2372 static const char * const GCCRegNames[];
2373 public:
2374 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
2375 TLSSupported = false;
2376 IntWidth = IntAlign = 32;
2377 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
2378 PointerWidth = PointerAlign = 64;
Chris Lattner5c67237f2009-11-07 18:59:41 +00002379 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
2380 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002381 }
2382 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002383 MacroBuilder &Builder) const {
2384 Builder.defineMacro("__s390__");
2385 Builder.defineMacro("__s390x__");
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002386 }
2387 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2388 unsigned &NumRecords) const {
2389 // FIXME: Implement.
2390 Records = 0;
2391 NumRecords = 0;
2392 }
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002393
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002394 virtual void getGCCRegNames(const char * const *&Names,
2395 unsigned &NumNames) const;
2396 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2397 unsigned &NumAliases) const {
2398 // No aliases.
2399 Aliases = 0;
2400 NumAliases = 0;
2401 }
2402 virtual bool validateAsmConstraint(const char *&Name,
2403 TargetInfo::ConstraintInfo &info) const {
2404 // FIXME: implement
2405 return true;
2406 }
2407 virtual const char *getClobbers() const {
2408 // FIXME: Is this really right?
2409 return "";
2410 }
2411 virtual const char *getVAListDeclaration() const {
2412 // FIXME: implement
2413 return "typedef char* __builtin_va_list;";
2414 }
2415 };
2416
2417 const char * const SystemZTargetInfo::GCCRegNames[] = {
2418 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2419 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2420 };
2421
2422 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
2423 unsigned &NumNames) const {
2424 Names = GCCRegNames;
2425 NumNames = llvm::array_lengthof(GCCRegNames);
2426 }
2427}
2428
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002429namespace {
2430 class BlackfinTargetInfo : public TargetInfo {
2431 static const char * const GCCRegNames[];
2432 public:
2433 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
2434 TLSSupported = false;
2435 DoubleAlign = 32;
2436 LongLongAlign = 32;
2437 LongDoubleAlign = 32;
Chris Lattner5c67237f2009-11-07 18:59:41 +00002438 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002439 }
2440
2441 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002442 MacroBuilder &Builder) const {
2443 DefineStd(Builder, "bfin", Opts);
2444 DefineStd(Builder, "BFIN", Opts);
2445 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002446 // FIXME: This one is really dependent on -mcpu
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002447 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002448 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
2449 }
2450
2451 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2452 unsigned &NumRecords) const {
2453 // FIXME: Implement.
2454 Records = 0;
2455 NumRecords = 0;
2456 }
2457
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002458 virtual void getGCCRegNames(const char * const *&Names,
2459 unsigned &NumNames) const;
2460
2461 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2462 unsigned &NumAliases) const {
2463 // No aliases.
2464 Aliases = 0;
2465 NumAliases = 0;
2466 }
2467
2468 virtual bool validateAsmConstraint(const char *&Name,
2469 TargetInfo::ConstraintInfo &Info) const {
2470 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
2471 Info.setAllowsRegister();
2472 return true;
2473 }
2474 return false;
2475 }
2476
2477 virtual const char *getClobbers() const {
2478 return "";
2479 }
2480
2481 virtual const char *getVAListDeclaration() const {
2482 return "typedef char* __builtin_va_list;";
2483 }
2484 };
2485
2486 const char * const BlackfinTargetInfo::GCCRegNames[] = {
2487 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2488 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
2489 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
2490 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
2491 "a0", "a1", "cc",
2492 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
2493 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
2494 };
2495
2496 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
2497 unsigned &NumNames) const {
2498 Names = GCCRegNames;
2499 NumNames = llvm::array_lengthof(GCCRegNames);
2500 }
2501}
2502
Eli Friedmana9c3d712009-08-19 20:47:07 +00002503namespace {
2504
Mike Stump11289f42009-09-09 15:08:12 +00002505 // LLVM and Clang cannot be used directly to output native binaries for
2506 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmana9c3d712009-08-19 20:47:07 +00002507 // type and alignment information.
Mike Stump11289f42009-09-09 15:08:12 +00002508 //
2509 // TCE uses the llvm bitcode as input and uses it for generating customized
2510 // target processor and program binary. TCE co-design environment is
Eli Friedmana9c3d712009-08-19 20:47:07 +00002511 // publicly available in http://tce.cs.tut.fi
2512
2513 class TCETargetInfo : public TargetInfo{
2514 public:
2515 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
2516 TLSSupported = false;
2517 IntWidth = 32;
2518 LongWidth = LongLongWidth = 32;
Eli Friedmana9c3d712009-08-19 20:47:07 +00002519 PointerWidth = 32;
2520 IntAlign = 32;
2521 LongAlign = LongLongAlign = 32;
2522 PointerAlign = 32;
2523 SizeType = UnsignedInt;
2524 IntMaxType = SignedLong;
2525 UIntMaxType = UnsignedLong;
2526 IntPtrType = SignedInt;
2527 PtrDiffType = SignedInt;
2528 FloatWidth = 32;
2529 FloatAlign = 32;
2530 DoubleWidth = 32;
2531 DoubleAlign = 32;
2532 LongDoubleWidth = 32;
2533 LongDoubleAlign = 32;
2534 FloatFormat = &llvm::APFloat::IEEEsingle;
2535 DoubleFormat = &llvm::APFloat::IEEEsingle;
2536 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner09797542010-03-04 21:07:38 +00002537 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
2538 "i16:16:32-i32:32:32-i64:32:32-"
NAKAMURA Takumidba4ed32011-02-18 08:44:38 +00002539 "f32:32:32-f64:32:32-v64:32:32-"
2540 "v128:32:32-a0:0:32-n32";
Eli Friedmana9c3d712009-08-19 20:47:07 +00002541 }
2542
2543 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002544 MacroBuilder &Builder) const {
2545 DefineStd(Builder, "tce", Opts);
2546 Builder.defineMacro("__TCE__");
2547 Builder.defineMacro("__TCE_V1__");
Eli Friedmana9c3d712009-08-19 20:47:07 +00002548 }
2549 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2550 unsigned &NumRecords) const {}
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002551 virtual const char *getClobbers() const {
2552 return "";
2553 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00002554 virtual const char *getVAListDeclaration() const {
2555 return "typedef void* __builtin_va_list;";
2556 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00002557 virtual void getGCCRegNames(const char * const *&Names,
2558 unsigned &NumNames) const {}
2559 virtual bool validateAsmConstraint(const char *&Name,
2560 TargetInfo::ConstraintInfo &info) const {
2561 return true;
2562 }
2563 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2564 unsigned &NumAliases) const {}
2565 };
2566}
2567
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002568namespace {
2569class MipsTargetInfo : public TargetInfo {
Eric Christopher0b26a612010-03-02 02:41:08 +00002570 std::string ABI, CPU;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002571 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2572 static const char * const GCCRegNames[];
2573public:
Eric Christopher0b26a612010-03-02 02:41:08 +00002574 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002575 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
Akira Hatanakab579fe52011-06-02 00:09:17 +00002576 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
2577 SizeType = UnsignedInt;
2578 PtrDiffType = SignedInt;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002579 }
Eric Christopher0b26a612010-03-02 02:41:08 +00002580 virtual const char *getABI() const { return ABI.c_str(); }
2581 virtual bool setABI(const std::string &Name) {
2582
2583 if ((Name == "o32") || (Name == "eabi")) {
2584 ABI = Name;
2585 return true;
2586 } else
2587 return false;
2588 }
2589 virtual bool setCPU(const std::string &Name) {
2590 CPU = Name;
2591 return true;
2592 }
2593 void getDefaultFeatures(const std::string &CPU,
2594 llvm::StringMap<bool> &Features) const {
2595 Features[ABI] = true;
2596 Features[CPU] = true;
2597 }
2598 virtual void getArchDefines(const LangOptions &Opts,
2599 MacroBuilder &Builder) const {
2600 if (ABI == "o32")
2601 Builder.defineMacro("__mips_o32");
2602 else if (ABI == "eabi")
2603 Builder.defineMacro("__mips_eabi");
2604 }
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002605 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002606 MacroBuilder &Builder) const {
2607 DefineStd(Builder, "mips", Opts);
2608 Builder.defineMacro("_mips");
2609 DefineStd(Builder, "MIPSEB", Opts);
2610 Builder.defineMacro("_MIPSEB");
2611 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christopher0b26a612010-03-02 02:41:08 +00002612 getArchDefines(Opts, Builder);
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002613 }
2614 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2615 unsigned &NumRecords) const {
2616 // FIXME: Implement!
2617 }
2618 virtual const char *getVAListDeclaration() const {
2619 return "typedef void* __builtin_va_list;";
2620 }
2621 virtual void getGCCRegNames(const char * const *&Names,
2622 unsigned &NumNames) const;
2623 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2624 unsigned &NumAliases) const;
2625 virtual bool validateAsmConstraint(const char *&Name,
2626 TargetInfo::ConstraintInfo &Info) const {
2627 switch (*Name) {
2628 default:
2629 case 'r': // CPU registers.
2630 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2631 case 'y': // Equivalent to "r", backwards compatibility only.
2632 case 'f': // floating-point registers.
2633 Info.setAllowsRegister();
2634 return true;
2635 }
2636 return false;
2637 }
2638
2639 virtual const char *getClobbers() const {
2640 // FIXME: Implement!
2641 return "";
2642 }
2643};
2644
2645const char * const MipsTargetInfo::GCCRegNames[] = {
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00002646 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002647 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2648 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2649 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2650 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2651 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2652 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2653 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2654 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2655 "$fcc5","$fcc6","$fcc7"
2656};
2657
2658void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2659 unsigned &NumNames) const {
2660 Names = GCCRegNames;
2661 NumNames = llvm::array_lengthof(GCCRegNames);
2662}
2663
2664const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2665 { { "at" }, "$1" },
2666 { { "v0" }, "$2" },
2667 { { "v1" }, "$3" },
2668 { { "a0" }, "$4" },
2669 { { "a1" }, "$5" },
2670 { { "a2" }, "$6" },
2671 { { "a3" }, "$7" },
2672 { { "t0" }, "$8" },
2673 { { "t1" }, "$9" },
2674 { { "t2" }, "$10" },
2675 { { "t3" }, "$11" },
2676 { { "t4" }, "$12" },
2677 { { "t5" }, "$13" },
2678 { { "t6" }, "$14" },
2679 { { "t7" }, "$15" },
2680 { { "s0" }, "$16" },
2681 { { "s1" }, "$17" },
2682 { { "s2" }, "$18" },
2683 { { "s3" }, "$19" },
2684 { { "s4" }, "$20" },
2685 { { "s5" }, "$21" },
2686 { { "s6" }, "$22" },
2687 { { "s7" }, "$23" },
2688 { { "t8" }, "$24" },
2689 { { "t9" }, "$25" },
2690 { { "k0" }, "$26" },
2691 { { "k1" }, "$27" },
2692 { { "gp" }, "$28" },
2693 { { "sp" }, "$29" },
2694 { { "fp" }, "$30" },
2695 { { "ra" }, "$31" }
2696};
2697
2698void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2699 unsigned &NumAliases) const {
2700 Aliases = GCCRegAliases;
2701 NumAliases = llvm::array_lengthof(GCCRegAliases);
2702}
2703} // end anonymous namespace.
2704
2705namespace {
2706class MipselTargetInfo : public MipsTargetInfo {
2707public:
2708 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2709 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
Akira Hatanakab579fe52011-06-02 00:09:17 +00002710 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002711 }
2712
2713 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002714 MacroBuilder &Builder) const;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002715};
2716
2717void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002718 MacroBuilder &Builder) const {
2719 DefineStd(Builder, "mips", Opts);
2720 Builder.defineMacro("_mips");
2721 DefineStd(Builder, "MIPSEL", Opts);
2722 Builder.defineMacro("_MIPSEL");
2723 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christopher0b26a612010-03-02 02:41:08 +00002724 getArchDefines(Opts, Builder);
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002725}
2726} // end anonymous namespace.
2727
Chris Lattner5ba61f02006-10-14 07:39:34 +00002728//===----------------------------------------------------------------------===//
2729// Driver code
2730//===----------------------------------------------------------------------===//
2731
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002732static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar52322032009-08-18 05:47:58 +00002733 llvm::Triple Triple(T);
2734 llvm::Triple::OSType os = Triple.getOS();
Eli Friedmanb5366062008-05-20 14:21:01 +00002735
Daniel Dunbar52322032009-08-18 05:47:58 +00002736 switch (Triple.getArch()) {
2737 default:
2738 return NULL;
Eli Friedmanb5366062008-05-20 14:21:01 +00002739
Daniel Dunbar52322032009-08-18 05:47:58 +00002740 case llvm::Triple::arm:
Daniel Dunbar33a004e2009-09-11 01:14:50 +00002741 case llvm::Triple::thumb:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002742 if (Triple.isOSDarwin())
2743 return new DarwinARMTargetInfo(T);
2744
Daniel Dunbar52322032009-08-18 05:47:58 +00002745 switch (os) {
Rafael Espindolaad8fed52010-06-10 00:46:51 +00002746 case llvm::Triple::Linux:
2747 return new LinuxTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002748 case llvm::Triple::FreeBSD:
Torok Edwinb2b37c62009-06-30 17:10:35 +00002749 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002750 default:
2751 return new ARMTargetInfo(T);
2752 }
Eli Friedmanb5366062008-05-20 14:21:01 +00002753
Daniel Dunbar52322032009-08-18 05:47:58 +00002754 case llvm::Triple::bfin:
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002755 return new BlackfinTargetInfo(T);
2756
Daniel Dunbar52322032009-08-18 05:47:58 +00002757 case llvm::Triple::msp430:
2758 return new MSP430TargetInfo(T);
Eli Friedmanb5366062008-05-20 14:21:01 +00002759
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002760 case llvm::Triple::mips:
2761 if (os == llvm::Triple::Psp)
2762 return new PSPTargetInfo<MipsTargetInfo>(T);
2763 if (os == llvm::Triple::Linux)
2764 return new LinuxTargetInfo<MipsTargetInfo>(T);
2765 return new MipsTargetInfo(T);
2766
2767 case llvm::Triple::mipsel:
2768 if (os == llvm::Triple::Psp)
2769 return new PSPTargetInfo<MipselTargetInfo>(T);
2770 if (os == llvm::Triple::Linux)
2771 return new LinuxTargetInfo<MipselTargetInfo>(T);
2772 return new MipselTargetInfo(T);
2773
Daniel Dunbar52322032009-08-18 05:47:58 +00002774 case llvm::Triple::ppc:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002775 if (Triple.isOSDarwin())
Roman Divacky965b0b72011-01-06 08:27:10 +00002776 return new DarwinPPC32TargetInfo(T);
Chris Lattnerdb5c16b2010-02-16 18:14:57 +00002777 else if (os == llvm::Triple::FreeBSD)
2778 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002779 return new PPC32TargetInfo(T);
2780
2781 case llvm::Triple::ppc64:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002782 if (Triple.isOSDarwin())
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +00002783 return new DarwinPPC64TargetInfo(T);
John Thompsone467e192009-11-19 17:18:50 +00002784 else if (os == llvm::Triple::Lv2)
2785 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnerdb5c16b2010-02-16 18:14:57 +00002786 else if (os == llvm::Triple::FreeBSD)
2787 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002788 return new PPC64TargetInfo(T);
2789
Justin Holewinski514cce82011-04-20 19:34:15 +00002790 case llvm::Triple::ptx32:
2791 return new PTX32TargetInfo(T);
2792 case llvm::Triple::ptx64:
2793 return new PTX64TargetInfo(T);
2794
Chris Lattner5178f562010-03-06 21:21:27 +00002795 case llvm::Triple::mblaze:
2796 return new MBlazeTargetInfo(T);
2797
Daniel Dunbar52322032009-08-18 05:47:58 +00002798 case llvm::Triple::sparc:
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002799 if (os == llvm::Triple::AuroraUX)
2800 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002801 if (os == llvm::Triple::Solaris)
2802 return new SolarisSparcV8TargetInfo(T);
2803 return new SparcV8TargetInfo(T);
2804
John Thompsone467e192009-11-19 17:18:50 +00002805 // FIXME: Need a real SPU target.
2806 case llvm::Triple::cellspu:
2807 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2808
Daniel Dunbar52322032009-08-18 05:47:58 +00002809 case llvm::Triple::systemz:
2810 return new SystemZTargetInfo(T);
2811
Eli Friedmana9c3d712009-08-19 20:47:07 +00002812 case llvm::Triple::tce:
2813 return new TCETargetInfo(T);
2814
Daniel Dunbar52322032009-08-18 05:47:58 +00002815 case llvm::Triple::x86:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002816 if (Triple.isOSDarwin())
2817 return new DarwinI386TargetInfo(T);
2818
Daniel Dunbar52322032009-08-18 05:47:58 +00002819 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002820 case llvm::Triple::AuroraUX:
2821 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002822 case llvm::Triple::Linux:
2823 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2824 case llvm::Triple::DragonFly:
2825 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2826 case llvm::Triple::NetBSD:
2827 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2828 case llvm::Triple::OpenBSD:
2829 return new OpenBSDI386TargetInfo(T);
2830 case llvm::Triple::FreeBSD:
2831 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
Chris Lattner3e2ee142010-07-07 16:01:42 +00002832 case llvm::Triple::Minix:
2833 return new MinixTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002834 case llvm::Triple::Solaris:
2835 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2836 case llvm::Triple::Cygwin:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002837 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002838 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002839 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002840 case llvm::Triple::Win32:
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00002841 return new VisualStudioWindowsX86_32TargetInfo(T);
Chris Lattnerb986aba2010-04-11 19:29:39 +00002842 case llvm::Triple::Haiku:
2843 return new HaikuX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002844 default:
2845 return new X86_32TargetInfo(T);
2846 }
2847
2848 case llvm::Triple::x86_64:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002849 if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
2850 return new DarwinX86_64TargetInfo(T);
2851
Daniel Dunbar52322032009-08-18 05:47:58 +00002852 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002853 case llvm::Triple::AuroraUX:
2854 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002855 case llvm::Triple::Linux:
2856 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner002ba6b2010-01-09 05:41:14 +00002857 case llvm::Triple::DragonFly:
2858 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002859 case llvm::Triple::NetBSD:
2860 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2861 case llvm::Triple::OpenBSD:
2862 return new OpenBSDX86_64TargetInfo(T);
2863 case llvm::Triple::FreeBSD:
2864 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2865 case llvm::Triple::Solaris:
2866 return new SolarisTargetInfo<X86_64TargetInfo>(T);
NAKAMURA Takumi31ea2f12011-02-17 08:51:38 +00002867 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002868 return new MinGWX86_64TargetInfo(T);
2869 case llvm::Triple::Win32: // This is what Triple.h supports now.
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002870 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002871 default:
2872 return new X86_64TargetInfo(T);
2873 }
2874 }
Chris Lattner5ba61f02006-10-14 07:39:34 +00002875}
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002876
2877/// CreateTargetInfo - Return the target info object for the specified target
2878/// triple.
2879TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002880 TargetOptions &Opts) {
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002881 llvm::Triple Triple(Opts.Triple);
2882
2883 // Construct the target
2884 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2885 if (!Target) {
2886 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2887 return 0;
2888 }
2889
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002890 // Set the target CPU if specified.
2891 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2892 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2893 return 0;
2894 }
2895
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002896 // Set the target ABI if specified.
2897 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2898 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2899 return 0;
2900 }
2901
Charles Davis95a546e2010-06-11 01:06:47 +00002902 // Set the target C++ ABI.
John McCall86353412010-08-21 22:46:04 +00002903 if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Charles Davis95a546e2010-06-11 01:06:47 +00002904 Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
2905 return 0;
2906 }
2907
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002908 // Compute the default target features, we need the target to handle this
2909 // because features may have dependencies on one another.
2910 llvm::StringMap<bool> Features;
2911 Target->getDefaultFeatures(Opts.CPU, Features);
2912
2913 // Apply the user specified deltas.
2914 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2915 ie = Opts.Features.end(); it != ie; ++it) {
2916 const char *Name = it->c_str();
2917
2918 // Apply the feature via the target.
2919 if ((Name[0] != '-' && Name[0] != '+') ||
2920 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2921 Diags.Report(diag::err_target_invalid_feature) << Name;
2922 return 0;
2923 }
2924 }
2925
2926 // Add the features to the compile options.
2927 //
2928 // FIXME: If we are completely confident that we have the right set, we only
2929 // need to pass the minuses.
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002930 Opts.Features.clear();
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002931 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2932 ie = Features.end(); it != ie; ++it)
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002933 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2934 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002935
2936 return Target.take();
2937}