1 //===--- Targets.cpp - Implement -arch option and targets -----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements construction of a TargetInfo object from a
11 // target triple.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/Basic/TargetInfo.h"
16 #include "clang/Basic/Builtins.h"
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/LangOptions.h"
19 #include "clang/Basic/MacroBuilder.h"
20 #include "clang/Basic/TargetBuiltins.h"
21 #include "clang/Basic/TargetOptions.h"
22 #include "llvm/ADT/APFloat.h"
23 #include "llvm/ADT/OwningPtr.h"
24 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/ADT/StringSwitch.h"
27 #include "llvm/ADT/Triple.h"
28 #include "llvm/IR/Type.h"
29 #include "llvm/MC/MCSectionMachO.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include <algorithm>
32 using namespace clang;
33
34 //===----------------------------------------------------------------------===//
35 // Common code shared among targets.
36 //===----------------------------------------------------------------------===//
37
38 /// DefineStd - Define a macro name and standard variants. For example if
39 /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
40 /// when in GNU mode.
DefineStd(MacroBuilder & Builder,StringRef MacroName,const LangOptions & Opts)41 static void DefineStd(MacroBuilder &Builder, StringRef MacroName,
42 const LangOptions &Opts) {
43 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
44
45 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
46 // in the user's namespace.
47 if (Opts.GNUMode)
48 Builder.defineMacro(MacroName);
49
50 // Define __unix.
51 Builder.defineMacro("__" + MacroName);
52
53 // Define __unix__.
54 Builder.defineMacro("__" + MacroName + "__");
55 }
56
defineCPUMacros(MacroBuilder & Builder,StringRef CPUName,bool Tuning=true)57 static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName,
58 bool Tuning = true) {
59 Builder.defineMacro("__" + CPUName);
60 Builder.defineMacro("__" + CPUName + "__");
61 if (Tuning)
62 Builder.defineMacro("__tune_" + CPUName + "__");
63 }
64
65 //===----------------------------------------------------------------------===//
66 // Defines specific to certain operating systems.
67 //===----------------------------------------------------------------------===//
68
69 namespace {
70 template<typename TgtInfo>
71 class OSTargetInfo : public TgtInfo {
72 protected:
73 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
74 MacroBuilder &Builder) const=0;
75 public:
OSTargetInfo(const std::string & triple)76 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const77 virtual void getTargetDefines(const LangOptions &Opts,
78 MacroBuilder &Builder) const {
79 TgtInfo::getTargetDefines(Opts, Builder);
80 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
81 }
82
83 };
84 } // end anonymous namespace
85
86
getDarwinDefines(MacroBuilder & Builder,const LangOptions & Opts,const llvm::Triple & Triple,StringRef & PlatformName,VersionTuple & PlatformMinVersion)87 static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
88 const llvm::Triple &Triple,
89 StringRef &PlatformName,
90 VersionTuple &PlatformMinVersion) {
91 Builder.defineMacro("__APPLE_CC__", "5621");
92 Builder.defineMacro("__APPLE__");
93 Builder.defineMacro("__MACH__");
94 Builder.defineMacro("OBJC_NEW_PROPERTIES");
95 // AddressSanitizer doesn't play well with source fortification, which is on
96 // by default on Darwin.
97 if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0");
98
99 if (!Opts.ObjCAutoRefCount) {
100 // __weak is always defined, for use in blocks and with objc pointers.
101 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
102
103 // Darwin defines __strong even in C mode (just to nothing).
104 if (Opts.getGC() != LangOptions::NonGC)
105 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
106 else
107 Builder.defineMacro("__strong", "");
108
109 // __unsafe_unretained is defined to nothing in non-ARC mode. We even
110 // allow this in C, since one might have block pointers in structs that
111 // are used in pure C code and in Objective-C ARC.
112 Builder.defineMacro("__unsafe_unretained", "");
113 }
114
115 if (Opts.Static)
116 Builder.defineMacro("__STATIC__");
117 else
118 Builder.defineMacro("__DYNAMIC__");
119
120 if (Opts.POSIXThreads)
121 Builder.defineMacro("_REENTRANT");
122
123 // Get the platform type and version number from the triple.
124 unsigned Maj, Min, Rev;
125 if (Triple.isMacOSX()) {
126 Triple.getMacOSXVersion(Maj, Min, Rev);
127 PlatformName = "macosx";
128 } else {
129 Triple.getOSVersion(Maj, Min, Rev);
130 PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
131 }
132
133 // If -target arch-pc-win32-macho option specified, we're
134 // generating code for Win32 ABI. No need to emit
135 // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
136 if (PlatformName == "win32") {
137 PlatformMinVersion = VersionTuple(Maj, Min, Rev);
138 return;
139 }
140
141 // Set the appropriate OS version define.
142 if (Triple.getOS() == llvm::Triple::IOS) {
143 assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
144 char Str[6];
145 Str[0] = '0' + Maj;
146 Str[1] = '0' + (Min / 10);
147 Str[2] = '0' + (Min % 10);
148 Str[3] = '0' + (Rev / 10);
149 Str[4] = '0' + (Rev % 10);
150 Str[5] = '\0';
151 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
152 } else {
153 // Note that the Driver allows versions which aren't representable in the
154 // define (because we only get a single digit for the minor and micro
155 // revision numbers). So, we limit them to the maximum representable
156 // version.
157 assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
158 assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
159 char Str[5];
160 Str[0] = '0' + (Maj / 10);
161 Str[1] = '0' + (Maj % 10);
162 Str[2] = '0' + std::min(Min, 9U);
163 Str[3] = '0' + std::min(Rev, 9U);
164 Str[4] = '\0';
165 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
166 }
167
168 PlatformMinVersion = VersionTuple(Maj, Min, Rev);
169 }
170
171 namespace {
172 template<typename Target>
173 class DarwinTargetInfo : public OSTargetInfo<Target> {
174 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const175 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
176 MacroBuilder &Builder) const {
177 getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
178 this->PlatformMinVersion);
179 }
180
181 public:
DarwinTargetInfo(const std::string & triple)182 DarwinTargetInfo(const std::string& triple) :
183 OSTargetInfo<Target>(triple) {
184 llvm::Triple T = llvm::Triple(triple);
185 this->TLSSupported = T.isMacOSX() && !T.isMacOSXVersionLT(10,7);
186 this->MCountName = "\01mcount";
187 }
188
isValidSectionSpecifier(StringRef SR) const189 virtual std::string isValidSectionSpecifier(StringRef SR) const {
190 // Let MCSectionMachO validate this.
191 StringRef Segment, Section;
192 unsigned TAA, StubSize;
193 bool HasTAA;
194 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
195 TAA, HasTAA, StubSize);
196 }
197
getStaticInitSectionSpecifier() const198 virtual const char *getStaticInitSectionSpecifier() const {
199 // FIXME: We should return 0 when building kexts.
200 return "__TEXT,__StaticInit,regular,pure_instructions";
201 }
202
203 /// Darwin does not support protected visibility. Darwin's "default"
204 /// is very similar to ELF's "protected"; Darwin requires a "weak"
205 /// attribute on declarations that can be dynamically replaced.
hasProtectedVisibility() const206 virtual bool hasProtectedVisibility() const {
207 return false;
208 }
209 };
210
211
212 // DragonFlyBSD Target
213 template<typename Target>
214 class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
215 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const216 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
217 MacroBuilder &Builder) const {
218 // DragonFly defines; list based off of gcc output
219 Builder.defineMacro("__DragonFly__");
220 Builder.defineMacro("__DragonFly_cc_version", "100001");
221 Builder.defineMacro("__ELF__");
222 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
223 Builder.defineMacro("__tune_i386__");
224 DefineStd(Builder, "unix", Opts);
225 }
226 public:
DragonFlyBSDTargetInfo(const std::string & triple)227 DragonFlyBSDTargetInfo(const std::string &triple)
228 : OSTargetInfo<Target>(triple) {
229 this->UserLabelPrefix = "";
230
231 llvm::Triple Triple(triple);
232 switch (Triple.getArch()) {
233 default:
234 case llvm::Triple::x86:
235 case llvm::Triple::x86_64:
236 this->MCountName = ".mcount";
237 break;
238 }
239 }
240 };
241
242 // FreeBSD Target
243 template<typename Target>
244 class FreeBSDTargetInfo : public OSTargetInfo<Target> {
245 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const246 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
247 MacroBuilder &Builder) const {
248 // FreeBSD defines; list based off of gcc output
249
250 unsigned Release = Triple.getOSMajorVersion();
251 if (Release == 0U)
252 Release = 8;
253
254 Builder.defineMacro("__FreeBSD__", Twine(Release));
255 Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U));
256 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
257 DefineStd(Builder, "unix", Opts);
258 Builder.defineMacro("__ELF__");
259 }
260 public:
FreeBSDTargetInfo(const std::string & triple)261 FreeBSDTargetInfo(const std::string &triple)
262 : OSTargetInfo<Target>(triple) {
263 this->UserLabelPrefix = "";
264
265 llvm::Triple Triple(triple);
266 switch (Triple.getArch()) {
267 default:
268 case llvm::Triple::x86:
269 case llvm::Triple::x86_64:
270 this->MCountName = ".mcount";
271 break;
272 case llvm::Triple::mips:
273 case llvm::Triple::mipsel:
274 case llvm::Triple::ppc:
275 case llvm::Triple::ppc64:
276 this->MCountName = "_mcount";
277 break;
278 case llvm::Triple::arm:
279 this->MCountName = "__mcount";
280 break;
281 }
282
283 }
284 };
285
286 // Minix Target
287 template<typename Target>
288 class MinixTargetInfo : public OSTargetInfo<Target> {
289 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const290 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
291 MacroBuilder &Builder) const {
292 // Minix defines
293
294 Builder.defineMacro("__minix", "3");
295 Builder.defineMacro("_EM_WSIZE", "4");
296 Builder.defineMacro("_EM_PSIZE", "4");
297 Builder.defineMacro("_EM_SSIZE", "2");
298 Builder.defineMacro("_EM_LSIZE", "4");
299 Builder.defineMacro("_EM_FSIZE", "4");
300 Builder.defineMacro("_EM_DSIZE", "8");
301 Builder.defineMacro("__ELF__");
302 DefineStd(Builder, "unix", Opts);
303 }
304 public:
MinixTargetInfo(const std::string & triple)305 MinixTargetInfo(const std::string &triple)
306 : OSTargetInfo<Target>(triple) {
307 this->UserLabelPrefix = "";
308 }
309 };
310
311 // Linux target
312 template<typename Target>
313 class LinuxTargetInfo : public OSTargetInfo<Target> {
314 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const315 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
316 MacroBuilder &Builder) const {
317 // Linux defines; list based off of gcc output
318 DefineStd(Builder, "unix", Opts);
319 DefineStd(Builder, "linux", Opts);
320 Builder.defineMacro("__gnu_linux__");
321 Builder.defineMacro("__ELF__");
322 if (Triple.getEnvironment() == llvm::Triple::Android)
323 Builder.defineMacro("__ANDROID__", "1");
324 if (Opts.POSIXThreads)
325 Builder.defineMacro("_REENTRANT");
326 if (Opts.CPlusPlus)
327 Builder.defineMacro("_GNU_SOURCE");
328 }
329 public:
LinuxTargetInfo(const std::string & triple)330 LinuxTargetInfo(const std::string& triple)
331 : OSTargetInfo<Target>(triple) {
332 this->UserLabelPrefix = "";
333 this->WIntType = TargetInfo::UnsignedInt;
334 }
335
getStaticInitSectionSpecifier() const336 virtual const char *getStaticInitSectionSpecifier() const {
337 return ".text.startup";
338 }
339 };
340
341 // NetBSD Target
342 template<typename Target>
343 class NetBSDTargetInfo : public OSTargetInfo<Target> {
344 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const345 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
346 MacroBuilder &Builder) const {
347 // NetBSD defines; list based off of gcc output
348 Builder.defineMacro("__NetBSD__");
349 Builder.defineMacro("__unix__");
350 Builder.defineMacro("__ELF__");
351 if (Opts.POSIXThreads)
352 Builder.defineMacro("_POSIX_THREADS");
353 }
354 public:
NetBSDTargetInfo(const std::string & triple)355 NetBSDTargetInfo(const std::string &triple)
356 : OSTargetInfo<Target>(triple) {
357 this->UserLabelPrefix = "";
358 }
359 };
360
361 // OpenBSD Target
362 template<typename Target>
363 class OpenBSDTargetInfo : public OSTargetInfo<Target> {
364 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const365 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
366 MacroBuilder &Builder) const {
367 // OpenBSD defines; list based off of gcc output
368
369 Builder.defineMacro("__OpenBSD__");
370 DefineStd(Builder, "unix", Opts);
371 Builder.defineMacro("__ELF__");
372 if (Opts.POSIXThreads)
373 Builder.defineMacro("_REENTRANT");
374 }
375 public:
OpenBSDTargetInfo(const std::string & triple)376 OpenBSDTargetInfo(const std::string &triple)
377 : OSTargetInfo<Target>(triple) {
378 this->UserLabelPrefix = "";
379 this->TLSSupported = false;
380
381 llvm::Triple Triple(triple);
382 switch (Triple.getArch()) {
383 default:
384 case llvm::Triple::x86:
385 case llvm::Triple::x86_64:
386 case llvm::Triple::arm:
387 case llvm::Triple::sparc:
388 this->MCountName = "__mcount";
389 break;
390 case llvm::Triple::mips64:
391 case llvm::Triple::mips64el:
392 case llvm::Triple::ppc:
393 case llvm::Triple::sparcv9:
394 this->MCountName = "_mcount";
395 break;
396 }
397 }
398 };
399
400 // Bitrig Target
401 template<typename Target>
402 class BitrigTargetInfo : public OSTargetInfo<Target> {
403 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const404 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
405 MacroBuilder &Builder) const {
406 // Bitrig defines; list based off of gcc output
407
408 Builder.defineMacro("__Bitrig__");
409 DefineStd(Builder, "unix", Opts);
410 Builder.defineMacro("__ELF__");
411 if (Opts.POSIXThreads)
412 Builder.defineMacro("_REENTRANT");
413 }
414 public:
BitrigTargetInfo(const std::string & triple)415 BitrigTargetInfo(const std::string &triple)
416 : OSTargetInfo<Target>(triple) {
417 this->UserLabelPrefix = "";
418 this->TLSSupported = false;
419 this->MCountName = "__mcount";
420 }
421 };
422
423 // PSP Target
424 template<typename Target>
425 class PSPTargetInfo : public OSTargetInfo<Target> {
426 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const427 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
428 MacroBuilder &Builder) const {
429 // PSP defines; list based on the output of the pspdev gcc toolchain.
430 Builder.defineMacro("PSP");
431 Builder.defineMacro("_PSP");
432 Builder.defineMacro("__psp__");
433 Builder.defineMacro("__ELF__");
434 }
435 public:
PSPTargetInfo(const std::string & triple)436 PSPTargetInfo(const std::string& triple)
437 : OSTargetInfo<Target>(triple) {
438 this->UserLabelPrefix = "";
439 }
440 };
441
442 // PS3 PPU Target
443 template<typename Target>
444 class PS3PPUTargetInfo : public OSTargetInfo<Target> {
445 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const446 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
447 MacroBuilder &Builder) const {
448 // PS3 PPU defines.
449 Builder.defineMacro("__PPC__");
450 Builder.defineMacro("__PPU__");
451 Builder.defineMacro("__CELLOS_LV2__");
452 Builder.defineMacro("__ELF__");
453 Builder.defineMacro("__LP32__");
454 Builder.defineMacro("_ARCH_PPC64");
455 Builder.defineMacro("__powerpc64__");
456 }
457 public:
PS3PPUTargetInfo(const std::string & triple)458 PS3PPUTargetInfo(const std::string& triple)
459 : OSTargetInfo<Target>(triple) {
460 this->UserLabelPrefix = "";
461 this->LongWidth = this->LongAlign = 32;
462 this->PointerWidth = this->PointerAlign = 32;
463 this->IntMaxType = TargetInfo::SignedLongLong;
464 this->UIntMaxType = TargetInfo::UnsignedLongLong;
465 this->Int64Type = TargetInfo::SignedLongLong;
466 this->SizeType = TargetInfo::UnsignedInt;
467 this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
468 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
469 }
470 };
471
472 // FIXME: Need a real SPU target.
473 // PS3 SPU Target
474 template<typename Target>
475 class PS3SPUTargetInfo : public OSTargetInfo<Target> {
476 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const477 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
478 MacroBuilder &Builder) const {
479 // PS3 PPU defines.
480 Builder.defineMacro("__SPU__");
481 Builder.defineMacro("__ELF__");
482 }
483 public:
PS3SPUTargetInfo(const std::string & triple)484 PS3SPUTargetInfo(const std::string& triple)
485 : OSTargetInfo<Target>(triple) {
486 this->UserLabelPrefix = "";
487 }
488 };
489
490 // AuroraUX target
491 template<typename Target>
492 class AuroraUXTargetInfo : public OSTargetInfo<Target> {
493 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const494 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
495 MacroBuilder &Builder) const {
496 DefineStd(Builder, "sun", Opts);
497 DefineStd(Builder, "unix", Opts);
498 Builder.defineMacro("__ELF__");
499 Builder.defineMacro("__svr4__");
500 Builder.defineMacro("__SVR4");
501 }
502 public:
AuroraUXTargetInfo(const std::string & triple)503 AuroraUXTargetInfo(const std::string& triple)
504 : OSTargetInfo<Target>(triple) {
505 this->UserLabelPrefix = "";
506 this->WCharType = this->SignedLong;
507 // FIXME: WIntType should be SignedLong
508 }
509 };
510
511 // Solaris target
512 template<typename Target>
513 class SolarisTargetInfo : public OSTargetInfo<Target> {
514 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const515 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
516 MacroBuilder &Builder) const {
517 DefineStd(Builder, "sun", Opts);
518 DefineStd(Builder, "unix", Opts);
519 Builder.defineMacro("__ELF__");
520 Builder.defineMacro("__svr4__");
521 Builder.defineMacro("__SVR4");
522 // Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
523 // newer, but to 500 for everything else. feature_test.h has a check to
524 // ensure that you are not using C99 with an old version of X/Open or C89
525 // with a new version.
526 if (Opts.C99 || Opts.C11)
527 Builder.defineMacro("_XOPEN_SOURCE", "600");
528 else
529 Builder.defineMacro("_XOPEN_SOURCE", "500");
530 if (Opts.CPlusPlus)
531 Builder.defineMacro("__C99FEATURES__");
532 Builder.defineMacro("_LARGEFILE_SOURCE");
533 Builder.defineMacro("_LARGEFILE64_SOURCE");
534 Builder.defineMacro("__EXTENSIONS__");
535 Builder.defineMacro("_REENTRANT");
536 }
537 public:
SolarisTargetInfo(const std::string & triple)538 SolarisTargetInfo(const std::string& triple)
539 : OSTargetInfo<Target>(triple) {
540 this->UserLabelPrefix = "";
541 this->WCharType = this->SignedInt;
542 // FIXME: WIntType should be SignedLong
543 }
544 };
545
546 // Windows target
547 template<typename Target>
548 class WindowsTargetInfo : public OSTargetInfo<Target> {
549 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const550 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
551 MacroBuilder &Builder) const {
552 Builder.defineMacro("_WIN32");
553 }
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const554 void getVisualStudioDefines(const LangOptions &Opts,
555 MacroBuilder &Builder) const {
556 if (Opts.CPlusPlus) {
557 if (Opts.RTTI)
558 Builder.defineMacro("_CPPRTTI");
559
560 if (Opts.Exceptions)
561 Builder.defineMacro("_CPPUNWIND");
562 }
563
564 if (!Opts.CharIsSigned)
565 Builder.defineMacro("_CHAR_UNSIGNED");
566
567 // FIXME: POSIXThreads isn't exactly the option this should be defined for,
568 // but it works for now.
569 if (Opts.POSIXThreads)
570 Builder.defineMacro("_MT");
571
572 if (Opts.MSCVersion != 0)
573 Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
574
575 if (Opts.MicrosoftExt) {
576 Builder.defineMacro("_MSC_EXTENSIONS");
577
578 if (Opts.CPlusPlus11) {
579 Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
580 Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
581 Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
582 }
583 }
584
585 Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
586 }
587
588 public:
WindowsTargetInfo(const std::string & triple)589 WindowsTargetInfo(const std::string &triple)
590 : OSTargetInfo<Target>(triple) {}
591 };
592
593 template <typename Target>
594 class NaClTargetInfo : public OSTargetInfo<Target> {
595 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const596 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
597 MacroBuilder &Builder) const {
598 if (Opts.POSIXThreads)
599 Builder.defineMacro("_REENTRANT");
600 if (Opts.CPlusPlus)
601 Builder.defineMacro("_GNU_SOURCE");
602
603 DefineStd(Builder, "unix", Opts);
604 Builder.defineMacro("__ELF__");
605 Builder.defineMacro("__native_client__");
606 }
607 public:
NaClTargetInfo(const std::string & triple)608 NaClTargetInfo(const std::string &triple)
609 : OSTargetInfo<Target>(triple) {
610 this->UserLabelPrefix = "";
611 this->LongAlign = 32;
612 this->LongWidth = 32;
613 this->PointerAlign = 32;
614 this->PointerWidth = 32;
615 this->IntMaxType = TargetInfo::SignedLongLong;
616 this->UIntMaxType = TargetInfo::UnsignedLongLong;
617 this->Int64Type = TargetInfo::SignedLongLong;
618 this->DoubleAlign = 64;
619 this->LongDoubleWidth = 64;
620 this->LongDoubleAlign = 64;
621 this->SizeType = TargetInfo::UnsignedInt;
622 this->PtrDiffType = TargetInfo::SignedInt;
623 this->IntPtrType = TargetInfo::SignedInt;
624 this->RegParmMax = 2;
625 this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
626 this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
627 "f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
628 }
checkCallingConvention(CallingConv CC) const629 virtual typename Target::CallingConvCheckResult checkCallingConvention(
630 CallingConv CC) const {
631 return CC == CC_PnaclCall ? Target::CCCR_OK :
632 Target::checkCallingConvention(CC);
633 }
634 };
635 } // end anonymous namespace.
636
637 //===----------------------------------------------------------------------===//
638 // Specific target implementations.
639 //===----------------------------------------------------------------------===//
640
641 namespace {
642 // PPC abstract base class
643 class PPCTargetInfo : public TargetInfo {
644 static const Builtin::Info BuiltinInfo[];
645 static const char * const GCCRegNames[];
646 static const TargetInfo::GCCRegAlias GCCRegAliases[];
647 std::string CPU;
648 public:
PPCTargetInfo(const std::string & triple)649 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
650 LongDoubleWidth = LongDoubleAlign = 128;
651 LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
652 }
653
654 /// \brief Flags for architecture specific defines.
655 typedef enum {
656 ArchDefineNone = 0,
657 ArchDefineName = 1 << 0, // <name> is substituted for arch name.
658 ArchDefinePpcgr = 1 << 1,
659 ArchDefinePpcsq = 1 << 2,
660 ArchDefine440 = 1 << 3,
661 ArchDefine603 = 1 << 4,
662 ArchDefine604 = 1 << 5,
663 ArchDefinePwr4 = 1 << 6,
664 ArchDefinePwr5 = 1 << 7,
665 ArchDefinePwr5x = 1 << 8,
666 ArchDefinePwr6 = 1 << 9,
667 ArchDefinePwr6x = 1 << 10,
668 ArchDefinePwr7 = 1 << 11,
669 ArchDefineA2 = 1 << 12,
670 ArchDefineA2q = 1 << 13
671 } ArchDefineTypes;
672
673 // Note: GCC recognizes the following additional cpus:
674 // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801,
675 // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell,
676 // titan, rs64.
setCPU(const std::string & Name)677 virtual bool setCPU(const std::string &Name) {
678 bool CPUKnown = llvm::StringSwitch<bool>(Name)
679 .Case("generic", true)
680 .Case("440", true)
681 .Case("450", true)
682 .Case("601", true)
683 .Case("602", true)
684 .Case("603", true)
685 .Case("603e", true)
686 .Case("603ev", true)
687 .Case("604", true)
688 .Case("604e", true)
689 .Case("620", true)
690 .Case("630", true)
691 .Case("g3", true)
692 .Case("7400", true)
693 .Case("g4", true)
694 .Case("7450", true)
695 .Case("g4+", true)
696 .Case("750", true)
697 .Case("970", true)
698 .Case("g5", true)
699 .Case("a2", true)
700 .Case("a2q", true)
701 .Case("e500mc", true)
702 .Case("e5500", true)
703 .Case("power3", true)
704 .Case("pwr3", true)
705 .Case("power4", true)
706 .Case("pwr4", true)
707 .Case("power5", true)
708 .Case("pwr5", true)
709 .Case("power5x", true)
710 .Case("pwr5x", true)
711 .Case("power6", true)
712 .Case("pwr6", true)
713 .Case("power6x", true)
714 .Case("pwr6x", true)
715 .Case("power7", true)
716 .Case("pwr7", true)
717 .Case("powerpc", true)
718 .Case("ppc", true)
719 .Case("powerpc64", true)
720 .Case("ppc64", true)
721 .Default(false);
722
723 if (CPUKnown)
724 CPU = Name;
725
726 return CPUKnown;
727 }
728
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const729 virtual void getTargetBuiltins(const Builtin::Info *&Records,
730 unsigned &NumRecords) const {
731 Records = BuiltinInfo;
732 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
733 }
734
isCLZForZeroUndef() const735 virtual bool isCLZForZeroUndef() const { return false; }
736
737 virtual void getTargetDefines(const LangOptions &Opts,
738 MacroBuilder &Builder) const;
739
740 virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
741
742 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
743 StringRef Name,
744 bool Enabled) const;
745
746 virtual bool hasFeature(StringRef Feature) const;
747
748 virtual void getGCCRegNames(const char * const *&Names,
749 unsigned &NumNames) const;
750 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
751 unsigned &NumAliases) const;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const752 virtual bool validateAsmConstraint(const char *&Name,
753 TargetInfo::ConstraintInfo &Info) const {
754 switch (*Name) {
755 default: return false;
756 case 'O': // Zero
757 break;
758 case 'b': // Base register
759 case 'f': // Floating point register
760 Info.setAllowsRegister();
761 break;
762 // FIXME: The following are added to allow parsing.
763 // I just took a guess at what the actions should be.
764 // Also, is more specific checking needed? I.e. specific registers?
765 case 'd': // Floating point register (containing 64-bit value)
766 case 'v': // Altivec vector register
767 Info.setAllowsRegister();
768 break;
769 case 'w':
770 switch (Name[1]) {
771 case 'd':// VSX vector register to hold vector double data
772 case 'f':// VSX vector register to hold vector float data
773 case 's':// VSX vector register to hold scalar float data
774 case 'a':// Any VSX register
775 break;
776 default:
777 return false;
778 }
779 Info.setAllowsRegister();
780 Name++; // Skip over 'w'.
781 break;
782 case 'h': // `MQ', `CTR', or `LINK' register
783 case 'q': // `MQ' register
784 case 'c': // `CTR' register
785 case 'l': // `LINK' register
786 case 'x': // `CR' register (condition register) number 0
787 case 'y': // `CR' register (condition register)
788 case 'z': // `XER[CA]' carry bit (part of the XER register)
789 Info.setAllowsRegister();
790 break;
791 case 'I': // Signed 16-bit constant
792 case 'J': // Unsigned 16-bit constant shifted left 16 bits
793 // (use `L' instead for SImode constants)
794 case 'K': // Unsigned 16-bit constant
795 case 'L': // Signed 16-bit constant shifted left 16 bits
796 case 'M': // Constant larger than 31
797 case 'N': // Exact power of 2
798 case 'P': // Constant whose negation is a signed 16-bit constant
799 case 'G': // Floating point constant that can be loaded into a
800 // register with one instruction per word
801 case 'H': // Integer/Floating point constant that can be loaded
802 // into a register using three instructions
803 break;
804 case 'm': // Memory operand. Note that on PowerPC targets, m can
805 // include addresses that update the base register. It
806 // is therefore only safe to use `m' in an asm statement
807 // if that asm statement accesses the operand exactly once.
808 // The asm statement must also use `%U<opno>' as a
809 // placeholder for the "update" flag in the corresponding
810 // load or store instruction. For example:
811 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
812 // is correct but:
813 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
814 // is not. Use es rather than m if you don't want the base
815 // register to be updated.
816 case 'e':
817 if (Name[1] != 's')
818 return false;
819 // es: A "stable" memory operand; that is, one which does not
820 // include any automodification of the base register. Unlike
821 // `m', this constraint can be used in asm statements that
822 // might access the operand several times, or that might not
823 // access it at all.
824 Info.setAllowsMemory();
825 Name++; // Skip over 'e'.
826 break;
827 case 'Q': // Memory operand that is an offset from a register (it is
828 // usually better to use `m' or `es' in asm statements)
829 case 'Z': // Memory operand that is an indexed or indirect from a
830 // register (it is usually better to use `m' or `es' in
831 // asm statements)
832 Info.setAllowsMemory();
833 Info.setAllowsRegister();
834 break;
835 case 'R': // AIX TOC entry
836 case 'a': // Address operand that is an indexed or indirect from a
837 // register (`p' is preferable for asm statements)
838 case 'S': // Constant suitable as a 64-bit mask operand
839 case 'T': // Constant suitable as a 32-bit mask operand
840 case 'U': // System V Release 4 small data area reference
841 case 't': // AND masks that can be performed by two rldic{l, r}
842 // instructions
843 case 'W': // Vector constant that does not require memory
844 case 'j': // Vector constant that is all zeros.
845 break;
846 // End FIXME.
847 }
848 return true;
849 }
getClobbers() const850 virtual const char *getClobbers() const {
851 return "";
852 }
getEHDataRegisterNumber(unsigned RegNo) const853 int getEHDataRegisterNumber(unsigned RegNo) const {
854 if (RegNo == 0) return 3;
855 if (RegNo == 1) return 4;
856 return -1;
857 }
858 };
859
860 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
861 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
862 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
863 ALL_LANGUAGES },
864 #include "clang/Basic/BuiltinsPPC.def"
865 };
866
867
868 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
869 /// #defines that are not tied to a specific subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const870 void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
871 MacroBuilder &Builder) const {
872 // Target identification.
873 Builder.defineMacro("__ppc__");
874 Builder.defineMacro("_ARCH_PPC");
875 Builder.defineMacro("__powerpc__");
876 Builder.defineMacro("__POWERPC__");
877 if (PointerWidth == 64) {
878 Builder.defineMacro("_ARCH_PPC64");
879 Builder.defineMacro("__powerpc64__");
880 Builder.defineMacro("__ppc64__");
881 } else {
882 Builder.defineMacro("__ppc__");
883 }
884
885 // Target properties.
886 if (getTriple().getOS() != llvm::Triple::NetBSD &&
887 getTriple().getOS() != llvm::Triple::OpenBSD)
888 Builder.defineMacro("_BIG_ENDIAN");
889 Builder.defineMacro("__BIG_ENDIAN__");
890
891 // Subtarget options.
892 Builder.defineMacro("__NATURAL_ALIGNMENT__");
893 Builder.defineMacro("__REGISTER_PREFIX__", "");
894
895 // FIXME: Should be controlled by command line option.
896 Builder.defineMacro("__LONG_DOUBLE_128__");
897
898 if (Opts.AltiVec) {
899 Builder.defineMacro("__VEC__", "10206");
900 Builder.defineMacro("__ALTIVEC__");
901 }
902
903 // CPU identification.
904 ArchDefineTypes defs = (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
905 .Case("440", ArchDefineName)
906 .Case("450", ArchDefineName | ArchDefine440)
907 .Case("601", ArchDefineName)
908 .Case("602", ArchDefineName | ArchDefinePpcgr)
909 .Case("603", ArchDefineName | ArchDefinePpcgr)
910 .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
911 .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
912 .Case("604", ArchDefineName | ArchDefinePpcgr)
913 .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
914 .Case("620", ArchDefineName | ArchDefinePpcgr)
915 .Case("630", ArchDefineName | ArchDefinePpcgr)
916 .Case("7400", ArchDefineName | ArchDefinePpcgr)
917 .Case("7450", ArchDefineName | ArchDefinePpcgr)
918 .Case("750", ArchDefineName | ArchDefinePpcgr)
919 .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
920 | ArchDefinePpcsq)
921 .Case("a2", ArchDefineA2)
922 .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q)
923 .Case("pwr3", ArchDefinePpcgr)
924 .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
925 .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
926 | ArchDefinePpcsq)
927 .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4
928 | ArchDefinePpcgr | ArchDefinePpcsq)
929 .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5
930 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
931 .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x
932 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
933 | ArchDefinePpcsq)
934 .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
935 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
936 | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
937 .Case("power3", ArchDefinePpcgr)
938 .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
939 .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
940 | ArchDefinePpcsq)
941 .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
942 | ArchDefinePpcgr | ArchDefinePpcsq)
943 .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
944 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
945 .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x
946 | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
947 | ArchDefinePpcsq)
948 .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
949 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
950 | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
951 .Default(ArchDefineNone);
952
953 if (defs & ArchDefineName)
954 Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
955 if (defs & ArchDefinePpcgr)
956 Builder.defineMacro("_ARCH_PPCGR");
957 if (defs & ArchDefinePpcsq)
958 Builder.defineMacro("_ARCH_PPCSQ");
959 if (defs & ArchDefine440)
960 Builder.defineMacro("_ARCH_440");
961 if (defs & ArchDefine603)
962 Builder.defineMacro("_ARCH_603");
963 if (defs & ArchDefine604)
964 Builder.defineMacro("_ARCH_604");
965 if (defs & ArchDefinePwr4)
966 Builder.defineMacro("_ARCH_PWR4");
967 if (defs & ArchDefinePwr5)
968 Builder.defineMacro("_ARCH_PWR5");
969 if (defs & ArchDefinePwr5x)
970 Builder.defineMacro("_ARCH_PWR5X");
971 if (defs & ArchDefinePwr6)
972 Builder.defineMacro("_ARCH_PWR6");
973 if (defs & ArchDefinePwr6x)
974 Builder.defineMacro("_ARCH_PWR6X");
975 if (defs & ArchDefinePwr7)
976 Builder.defineMacro("_ARCH_PWR7");
977 if (defs & ArchDefineA2)
978 Builder.defineMacro("_ARCH_A2");
979 if (defs & ArchDefineA2q) {
980 Builder.defineMacro("_ARCH_A2Q");
981 Builder.defineMacro("_ARCH_QP");
982 }
983
984 if (getTriple().getVendor() == llvm::Triple::BGQ) {
985 Builder.defineMacro("__bg__");
986 Builder.defineMacro("__THW_BLUEGENE__");
987 Builder.defineMacro("__bgq__");
988 Builder.defineMacro("__TOS_BGQ__");
989 }
990
991 // FIXME: The following are not yet generated here by Clang, but are
992 // generated by GCC:
993 //
994 // _SOFT_FLOAT_
995 // __RECIP_PRECISION__
996 // __APPLE_ALTIVEC__
997 // __VSX__
998 // __RECIP__
999 // __RECIPF__
1000 // __RSQRTE__
1001 // __RSQRTEF__
1002 // _SOFT_DOUBLE_
1003 // __NO_LWSYNC__
1004 // __HAVE_BSWAP__
1005 // __LONGDOUBLE128
1006 // __CMODEL_MEDIUM__
1007 // __CMODEL_LARGE__
1008 // _CALL_SYSV
1009 // _CALL_DARWIN
1010 // __NO_FPRS__
1011 }
1012
getDefaultFeatures(llvm::StringMap<bool> & Features) const1013 void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
1014 Features["altivec"] = llvm::StringSwitch<bool>(CPU)
1015 .Case("7400", true)
1016 .Case("g4", true)
1017 .Case("7450", true)
1018 .Case("g4+", true)
1019 .Case("970", true)
1020 .Case("g5", true)
1021 .Case("pwr6", true)
1022 .Case("pwr7", true)
1023 .Case("ppc64", true)
1024 .Default(false);
1025
1026 Features["qpx"] = (CPU == "a2q");
1027 }
1028
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const1029 bool PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
1030 StringRef Name,
1031 bool Enabled) const {
1032 if (Name == "altivec" || Name == "qpx") {
1033 Features[Name] = Enabled;
1034 return true;
1035 }
1036
1037 return false;
1038 }
1039
hasFeature(StringRef Feature) const1040 bool PPCTargetInfo::hasFeature(StringRef Feature) const {
1041 return Feature == "powerpc";
1042 }
1043
1044
1045 const char * const PPCTargetInfo::GCCRegNames[] = {
1046 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1047 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1048 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1049 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1050 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1051 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1052 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1053 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1054 "mq", "lr", "ctr", "ap",
1055 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
1056 "xer",
1057 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
1058 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
1059 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
1060 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1061 "vrsave", "vscr",
1062 "spe_acc", "spefscr",
1063 "sfp"
1064 };
1065
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const1066 void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
1067 unsigned &NumNames) const {
1068 Names = GCCRegNames;
1069 NumNames = llvm::array_lengthof(GCCRegNames);
1070 }
1071
1072 const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
1073 // While some of these aliases do map to different registers
1074 // they still share the same register name.
1075 { { "0" }, "r0" },
1076 { { "1"}, "r1" },
1077 { { "2" }, "r2" },
1078 { { "3" }, "r3" },
1079 { { "4" }, "r4" },
1080 { { "5" }, "r5" },
1081 { { "6" }, "r6" },
1082 { { "7" }, "r7" },
1083 { { "8" }, "r8" },
1084 { { "9" }, "r9" },
1085 { { "10" }, "r10" },
1086 { { "11" }, "r11" },
1087 { { "12" }, "r12" },
1088 { { "13" }, "r13" },
1089 { { "14" }, "r14" },
1090 { { "15" }, "r15" },
1091 { { "16" }, "r16" },
1092 { { "17" }, "r17" },
1093 { { "18" }, "r18" },
1094 { { "19" }, "r19" },
1095 { { "20" }, "r20" },
1096 { { "21" }, "r21" },
1097 { { "22" }, "r22" },
1098 { { "23" }, "r23" },
1099 { { "24" }, "r24" },
1100 { { "25" }, "r25" },
1101 { { "26" }, "r26" },
1102 { { "27" }, "r27" },
1103 { { "28" }, "r28" },
1104 { { "29" }, "r29" },
1105 { { "30" }, "r30" },
1106 { { "31" }, "r31" },
1107 { { "fr0" }, "f0" },
1108 { { "fr1" }, "f1" },
1109 { { "fr2" }, "f2" },
1110 { { "fr3" }, "f3" },
1111 { { "fr4" }, "f4" },
1112 { { "fr5" }, "f5" },
1113 { { "fr6" }, "f6" },
1114 { { "fr7" }, "f7" },
1115 { { "fr8" }, "f8" },
1116 { { "fr9" }, "f9" },
1117 { { "fr10" }, "f10" },
1118 { { "fr11" }, "f11" },
1119 { { "fr12" }, "f12" },
1120 { { "fr13" }, "f13" },
1121 { { "fr14" }, "f14" },
1122 { { "fr15" }, "f15" },
1123 { { "fr16" }, "f16" },
1124 { { "fr17" }, "f17" },
1125 { { "fr18" }, "f18" },
1126 { { "fr19" }, "f19" },
1127 { { "fr20" }, "f20" },
1128 { { "fr21" }, "f21" },
1129 { { "fr22" }, "f22" },
1130 { { "fr23" }, "f23" },
1131 { { "fr24" }, "f24" },
1132 { { "fr25" }, "f25" },
1133 { { "fr26" }, "f26" },
1134 { { "fr27" }, "f27" },
1135 { { "fr28" }, "f28" },
1136 { { "fr29" }, "f29" },
1137 { { "fr30" }, "f30" },
1138 { { "fr31" }, "f31" },
1139 { { "cc" }, "cr0" },
1140 };
1141
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1142 void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1143 unsigned &NumAliases) const {
1144 Aliases = GCCRegAliases;
1145 NumAliases = llvm::array_lengthof(GCCRegAliases);
1146 }
1147 } // end anonymous namespace.
1148
1149 namespace {
1150 class PPC32TargetInfo : public PPCTargetInfo {
1151 public:
PPC32TargetInfo(const std::string & triple)1152 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
1153 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1154 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
1155
1156 switch (getTriple().getOS()) {
1157 case llvm::Triple::Linux:
1158 case llvm::Triple::FreeBSD:
1159 case llvm::Triple::NetBSD:
1160 SizeType = UnsignedInt;
1161 PtrDiffType = SignedInt;
1162 IntPtrType = SignedInt;
1163 break;
1164 default:
1165 break;
1166 }
1167
1168 if (getTriple().getOS() == llvm::Triple::FreeBSD) {
1169 LongDoubleWidth = LongDoubleAlign = 64;
1170 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1171 }
1172
1173 // PPC32 supports atomics up to 4 bytes.
1174 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
1175 }
1176
getBuiltinVaListKind() const1177 virtual BuiltinVaListKind getBuiltinVaListKind() const {
1178 // This is the ELF definition, and is overridden by the Darwin sub-target
1179 return TargetInfo::PowerABIBuiltinVaList;
1180 }
1181 };
1182 } // end anonymous namespace.
1183
1184 namespace {
1185 class PPC64TargetInfo : public PPCTargetInfo {
1186 public:
PPC64TargetInfo(const std::string & triple)1187 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
1188 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
1189 IntMaxType = SignedLong;
1190 UIntMaxType = UnsignedLong;
1191 Int64Type = SignedLong;
1192
1193 if (getTriple().getOS() == llvm::Triple::FreeBSD) {
1194 LongDoubleWidth = LongDoubleAlign = 64;
1195 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1196 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1197 "i64:64:64-f32:32:32-f64:64:64-f128:64:64-"
1198 "v128:128:128-n32:64";
1199 } else
1200 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1201 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
1202 "v128:128:128-n32:64";
1203
1204 // PPC64 supports atomics up to 8 bytes.
1205 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
1206 }
getBuiltinVaListKind() const1207 virtual BuiltinVaListKind getBuiltinVaListKind() const {
1208 return TargetInfo::CharPtrBuiltinVaList;
1209 }
1210 };
1211 } // end anonymous namespace.
1212
1213
1214 namespace {
1215 class DarwinPPC32TargetInfo :
1216 public DarwinTargetInfo<PPC32TargetInfo> {
1217 public:
DarwinPPC32TargetInfo(const std::string & triple)1218 DarwinPPC32TargetInfo(const std::string& triple)
1219 : DarwinTargetInfo<PPC32TargetInfo>(triple) {
1220 HasAlignMac68kSupport = true;
1221 BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
1222 LongLongAlign = 32;
1223 SuitableAlign = 128;
1224 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1225 "i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32";
1226 }
getBuiltinVaListKind() const1227 virtual BuiltinVaListKind getBuiltinVaListKind() const {
1228 return TargetInfo::CharPtrBuiltinVaList;
1229 }
1230 };
1231
1232 class DarwinPPC64TargetInfo :
1233 public DarwinTargetInfo<PPC64TargetInfo> {
1234 public:
DarwinPPC64TargetInfo(const std::string & triple)1235 DarwinPPC64TargetInfo(const std::string& triple)
1236 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
1237 HasAlignMac68kSupport = true;
1238 SuitableAlign = 128;
1239 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1240 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
1241 }
1242 };
1243 } // end anonymous namespace.
1244
1245 namespace {
1246 static const unsigned NVPTXAddrSpaceMap[] = {
1247 1, // opencl_global
1248 3, // opencl_local
1249 4, // opencl_constant
1250 1, // cuda_device
1251 4, // cuda_constant
1252 3, // cuda_shared
1253 };
1254 class NVPTXTargetInfo : public TargetInfo {
1255 static const char * const GCCRegNames[];
1256 static const Builtin::Info BuiltinInfo[];
1257 std::vector<StringRef> AvailableFeatures;
1258 public:
NVPTXTargetInfo(const std::string & triple)1259 NVPTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
1260 BigEndian = false;
1261 TLSSupported = false;
1262 LongWidth = LongAlign = 64;
1263 AddrSpaceMap = &NVPTXAddrSpaceMap;
1264 // Define available target features
1265 // These must be defined in sorted order!
1266 NoAsmVariants = true;
1267 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1268 virtual void getTargetDefines(const LangOptions &Opts,
1269 MacroBuilder &Builder) const {
1270 Builder.defineMacro("__PTX__");
1271 Builder.defineMacro("__NVPTX__");
1272 }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const1273 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1274 unsigned &NumRecords) const {
1275 Records = BuiltinInfo;
1276 NumRecords = clang::NVPTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
1277 }
hasFeature(StringRef Feature) const1278 virtual bool hasFeature(StringRef Feature) const {
1279 return Feature == "ptx" || Feature == "nvptx";
1280 }
1281
1282 virtual void getGCCRegNames(const char * const *&Names,
1283 unsigned &NumNames) const;
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1284 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1285 unsigned &NumAliases) const {
1286 // No aliases.
1287 Aliases = 0;
1288 NumAliases = 0;
1289 }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const1290 virtual bool validateAsmConstraint(const char *&Name,
1291 TargetInfo::ConstraintInfo &info) const {
1292 // FIXME: implement
1293 return true;
1294 }
getClobbers() const1295 virtual const char *getClobbers() const {
1296 // FIXME: Is this really right?
1297 return "";
1298 }
getBuiltinVaListKind() const1299 virtual BuiltinVaListKind getBuiltinVaListKind() const {
1300 // FIXME: implement
1301 return TargetInfo::CharPtrBuiltinVaList;
1302 }
setCPU(const std::string & Name)1303 virtual bool setCPU(const std::string &Name) {
1304 return Name == "sm_10" || Name == "sm_13" || Name == "sm_20";
1305 }
1306 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1307 StringRef Name,
1308 bool Enabled) const;
1309 };
1310
1311 const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
1312 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
1313 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1314 ALL_LANGUAGES },
1315 #include "clang/Basic/BuiltinsNVPTX.def"
1316 };
1317
1318 const char * const NVPTXTargetInfo::GCCRegNames[] = {
1319 "r0"
1320 };
1321
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const1322 void NVPTXTargetInfo::getGCCRegNames(const char * const *&Names,
1323 unsigned &NumNames) const {
1324 Names = GCCRegNames;
1325 NumNames = llvm::array_lengthof(GCCRegNames);
1326 }
1327
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const1328 bool NVPTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
1329 StringRef Name,
1330 bool Enabled) const {
1331 if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(),
1332 Name)) {
1333 Features[Name] = Enabled;
1334 return true;
1335 } else {
1336 return false;
1337 }
1338 }
1339
1340 class NVPTX32TargetInfo : public NVPTXTargetInfo {
1341 public:
NVPTX32TargetInfo(const std::string & triple)1342 NVPTX32TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) {
1343 PointerWidth = PointerAlign = 32;
1344 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
1345 DescriptionString
1346 = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
1347 "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-"
1348 "n16:32:64";
1349 }
1350 };
1351
1352 class NVPTX64TargetInfo : public NVPTXTargetInfo {
1353 public:
NVPTX64TargetInfo(const std::string & triple)1354 NVPTX64TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) {
1355 PointerWidth = PointerAlign = 64;
1356 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
1357 DescriptionString
1358 = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
1359 "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-"
1360 "n16:32:64";
1361 }
1362 };
1363 }
1364
1365 namespace {
1366
1367 static const unsigned R600AddrSpaceMap[] = {
1368 1, // opencl_global
1369 3, // opencl_local
1370 2, // opencl_constant
1371 1, // cuda_device
1372 2, // cuda_constant
1373 3 // cuda_shared
1374 };
1375
1376 static const char *DescriptionStringR600 =
1377 "e"
1378 "-p:32:32:32"
1379 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32"
1380 "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
1381 "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
1382 "-n32:64";
1383
1384 static const char *DescriptionStringR600DoubleOps =
1385 "e"
1386 "-p:32:32:32"
1387 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
1388 "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
1389 "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
1390 "-n32:64";
1391
1392 static const char *DescriptionStringSI =
1393 "e"
1394 "-p:64:64:64"
1395 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
1396 "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
1397 "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
1398 "-n32:64";
1399
1400 class R600TargetInfo : public TargetInfo {
1401 /// \brief The GPU profiles supported by the R600 target.
1402 enum GPUKind {
1403 GK_NONE,
1404 GK_R600,
1405 GK_R600_DOUBLE_OPS,
1406 GK_R700,
1407 GK_R700_DOUBLE_OPS,
1408 GK_EVERGREEN,
1409 GK_EVERGREEN_DOUBLE_OPS,
1410 GK_NORTHERN_ISLANDS,
1411 GK_CAYMAN,
1412 GK_SOUTHERN_ISLANDS
1413 } GPU;
1414
1415 public:
R600TargetInfo(const std::string & triple)1416 R600TargetInfo(const std::string& triple)
1417 : TargetInfo(triple),
1418 GPU(GK_R600) {
1419 DescriptionString = DescriptionStringR600;
1420 AddrSpaceMap = &R600AddrSpaceMap;
1421 }
1422
getClobbers() const1423 virtual const char * getClobbers() const {
1424 return "";
1425 }
1426
getGCCRegNames(const char * const * & Names,unsigned & numNames) const1427 virtual void getGCCRegNames(const char * const *&Names,
1428 unsigned &numNames) const {
1429 Names = NULL;
1430 numNames = 0;
1431 }
1432
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1433 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1434 unsigned &NumAliases) const {
1435 Aliases = NULL;
1436 NumAliases = 0;
1437 }
1438
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const1439 virtual bool validateAsmConstraint(const char *&Name,
1440 TargetInfo::ConstraintInfo &info) const {
1441 return true;
1442 }
1443
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const1444 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1445 unsigned &NumRecords) const {
1446 Records = NULL;
1447 NumRecords = 0;
1448 }
1449
1450
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1451 virtual void getTargetDefines(const LangOptions &Opts,
1452 MacroBuilder &Builder) const {
1453 Builder.defineMacro("__R600__");
1454 }
1455
getBuiltinVaListKind() const1456 virtual BuiltinVaListKind getBuiltinVaListKind() const {
1457 return TargetInfo::CharPtrBuiltinVaList;
1458 }
1459
setCPU(const std::string & Name)1460 virtual bool setCPU(const std::string &Name) {
1461 GPU = llvm::StringSwitch<GPUKind>(Name)
1462 .Case("r600" , GK_R600)
1463 .Case("rv610", GK_R600)
1464 .Case("rv620", GK_R600)
1465 .Case("rv630", GK_R600)
1466 .Case("rv635", GK_R600)
1467 .Case("rs780", GK_R600)
1468 .Case("rs880", GK_R600)
1469 .Case("rv670", GK_R600_DOUBLE_OPS)
1470 .Case("rv710", GK_R700)
1471 .Case("rv730", GK_R700)
1472 .Case("rv740", GK_R700_DOUBLE_OPS)
1473 .Case("rv770", GK_R700_DOUBLE_OPS)
1474 .Case("palm", GK_EVERGREEN)
1475 .Case("cedar", GK_EVERGREEN)
1476 .Case("sumo", GK_EVERGREEN)
1477 .Case("sumo2", GK_EVERGREEN)
1478 .Case("redwood", GK_EVERGREEN)
1479 .Case("juniper", GK_EVERGREEN)
1480 .Case("hemlock", GK_EVERGREEN_DOUBLE_OPS)
1481 .Case("cypress", GK_EVERGREEN_DOUBLE_OPS)
1482 .Case("barts", GK_NORTHERN_ISLANDS)
1483 .Case("turks", GK_NORTHERN_ISLANDS)
1484 .Case("caicos", GK_NORTHERN_ISLANDS)
1485 .Case("cayman", GK_CAYMAN)
1486 .Case("aruba", GK_CAYMAN)
1487 .Case("SI", GK_SOUTHERN_ISLANDS)
1488 .Case("pitcairn", GK_SOUTHERN_ISLANDS)
1489 .Case("verde", GK_SOUTHERN_ISLANDS)
1490 .Case("oland", GK_SOUTHERN_ISLANDS)
1491 .Default(GK_NONE);
1492
1493 if (GPU == GK_NONE) {
1494 return false;
1495 }
1496
1497 // Set the correct data layout
1498 switch (GPU) {
1499 case GK_NONE:
1500 case GK_R600:
1501 case GK_R700:
1502 case GK_EVERGREEN:
1503 case GK_NORTHERN_ISLANDS:
1504 DescriptionString = DescriptionStringR600;
1505 break;
1506 case GK_R600_DOUBLE_OPS:
1507 case GK_R700_DOUBLE_OPS:
1508 case GK_EVERGREEN_DOUBLE_OPS:
1509 case GK_CAYMAN:
1510 DescriptionString = DescriptionStringR600DoubleOps;
1511 break;
1512 case GK_SOUTHERN_ISLANDS:
1513 DescriptionString = DescriptionStringSI;
1514 break;
1515 }
1516
1517 return true;
1518 }
1519 };
1520
1521 } // end anonymous namespace
1522
1523 namespace {
1524 // MBlaze abstract base class
1525 class MBlazeTargetInfo : public TargetInfo {
1526 static const char * const GCCRegNames[];
1527 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1528
1529 public:
MBlazeTargetInfo(const std::string & triple)1530 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
1531 DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
1532 }
1533
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const1534 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1535 unsigned &NumRecords) const {
1536 // FIXME: Implement.
1537 Records = 0;
1538 NumRecords = 0;
1539 }
1540
1541 virtual void getTargetDefines(const LangOptions &Opts,
1542 MacroBuilder &Builder) const;
1543
hasFeature(StringRef Feature) const1544 virtual bool hasFeature(StringRef Feature) const {
1545 return Feature == "mblaze";
1546 }
1547
getBuiltinVaListKind() const1548 virtual BuiltinVaListKind getBuiltinVaListKind() const {
1549 return TargetInfo::CharPtrBuiltinVaList;
1550 }
getTargetPrefix() const1551 virtual const char *getTargetPrefix() const {
1552 return "mblaze";
1553 }
1554 virtual void getGCCRegNames(const char * const *&Names,
1555 unsigned &NumNames) const;
1556 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1557 unsigned &NumAliases) const;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1558 virtual bool validateAsmConstraint(const char *&Name,
1559 TargetInfo::ConstraintInfo &Info) const {
1560 switch (*Name) {
1561 default: return false;
1562 case 'O': // Zero
1563 return true;
1564 case 'b': // Base register
1565 case 'f': // Floating point register
1566 Info.setAllowsRegister();
1567 return true;
1568 }
1569 }
getClobbers() const1570 virtual const char *getClobbers() const {
1571 return "";
1572 }
1573 };
1574
1575 /// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
1576 /// #defines that are not tied to a specific subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1577 void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
1578 MacroBuilder &Builder) const {
1579 // Target identification.
1580 Builder.defineMacro("__microblaze__");
1581 Builder.defineMacro("_ARCH_MICROBLAZE");
1582 Builder.defineMacro("__MICROBLAZE__");
1583
1584 // Target properties.
1585 Builder.defineMacro("_BIG_ENDIAN");
1586 Builder.defineMacro("__BIG_ENDIAN__");
1587
1588 // Subtarget options.
1589 Builder.defineMacro("__REGISTER_PREFIX__", "");
1590 }
1591
1592
1593 const char * const MBlazeTargetInfo::GCCRegNames[] = {
1594 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1595 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1596 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1597 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1598 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
1599 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
1600 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
1601 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
1602 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
1603 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
1604 };
1605
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const1606 void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
1607 unsigned &NumNames) const {
1608 Names = GCCRegNames;
1609 NumNames = llvm::array_lengthof(GCCRegNames);
1610 }
1611
1612 const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
1613 { {"f0"}, "r0" },
1614 { {"f1"}, "r1" },
1615 { {"f2"}, "r2" },
1616 { {"f3"}, "r3" },
1617 { {"f4"}, "r4" },
1618 { {"f5"}, "r5" },
1619 { {"f6"}, "r6" },
1620 { {"f7"}, "r7" },
1621 { {"f8"}, "r8" },
1622 { {"f9"}, "r9" },
1623 { {"f10"}, "r10" },
1624 { {"f11"}, "r11" },
1625 { {"f12"}, "r12" },
1626 { {"f13"}, "r13" },
1627 { {"f14"}, "r14" },
1628 { {"f15"}, "r15" },
1629 { {"f16"}, "r16" },
1630 { {"f17"}, "r17" },
1631 { {"f18"}, "r18" },
1632 { {"f19"}, "r19" },
1633 { {"f20"}, "r20" },
1634 { {"f21"}, "r21" },
1635 { {"f22"}, "r22" },
1636 { {"f23"}, "r23" },
1637 { {"f24"}, "r24" },
1638 { {"f25"}, "r25" },
1639 { {"f26"}, "r26" },
1640 { {"f27"}, "r27" },
1641 { {"f28"}, "r28" },
1642 { {"f29"}, "r29" },
1643 { {"f30"}, "r30" },
1644 { {"f31"}, "r31" },
1645 };
1646
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1647 void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1648 unsigned &NumAliases) const {
1649 Aliases = GCCRegAliases;
1650 NumAliases = llvm::array_lengthof(GCCRegAliases);
1651 }
1652 } // end anonymous namespace.
1653
1654 namespace {
1655 // Namespace for x86 abstract base class
1656 const Builtin::Info BuiltinInfo[] = {
1657 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
1658 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1659 ALL_LANGUAGES },
1660 #include "clang/Basic/BuiltinsX86.def"
1661 };
1662
1663 static const char* const GCCRegNames[] = {
1664 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
1665 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
1666 "argp", "flags", "fpcr", "fpsr", "dirflag", "frame",
1667 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
1668 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
1669 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1670 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
1671 "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
1672 "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
1673 };
1674
1675 const TargetInfo::AddlRegName AddlRegNames[] = {
1676 { { "al", "ah", "eax", "rax" }, 0 },
1677 { { "bl", "bh", "ebx", "rbx" }, 3 },
1678 { { "cl", "ch", "ecx", "rcx" }, 2 },
1679 { { "dl", "dh", "edx", "rdx" }, 1 },
1680 { { "esi", "rsi" }, 4 },
1681 { { "edi", "rdi" }, 5 },
1682 { { "esp", "rsp" }, 7 },
1683 { { "ebp", "rbp" }, 6 },
1684 };
1685
1686 // X86 target abstract base class; x86-32 and x86-64 are very close, so
1687 // most of the implementation can be shared.
1688 class X86TargetInfo : public TargetInfo {
1689 enum X86SSEEnum {
1690 NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2
1691 } SSELevel;
1692 enum MMX3DNowEnum {
1693 NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
1694 } MMX3DNowLevel;
1695
1696 bool HasAES;
1697 bool HasPCLMUL;
1698 bool HasLZCNT;
1699 bool HasRDRND;
1700 bool HasBMI;
1701 bool HasBMI2;
1702 bool HasPOPCNT;
1703 bool HasRTM;
1704 bool HasSSE4a;
1705 bool HasFMA4;
1706 bool HasFMA;
1707 bool HasXOP;
1708 bool HasF16C;
1709
1710 /// \brief Enumeration of all of the X86 CPUs supported by Clang.
1711 ///
1712 /// Each enumeration represents a particular CPU supported by Clang. These
1713 /// loosely correspond to the options passed to '-march' or '-mtune' flags.
1714 enum CPUKind {
1715 CK_Generic,
1716
1717 /// \name i386
1718 /// i386-generation processors.
1719 //@{
1720 CK_i386,
1721 //@}
1722
1723 /// \name i486
1724 /// i486-generation processors.
1725 //@{
1726 CK_i486,
1727 CK_WinChipC6,
1728 CK_WinChip2,
1729 CK_C3,
1730 //@}
1731
1732 /// \name i586
1733 /// i586-generation processors, P5 microarchitecture based.
1734 //@{
1735 CK_i586,
1736 CK_Pentium,
1737 CK_PentiumMMX,
1738 //@}
1739
1740 /// \name i686
1741 /// i686-generation processors, P6 / Pentium M microarchitecture based.
1742 //@{
1743 CK_i686,
1744 CK_PentiumPro,
1745 CK_Pentium2,
1746 CK_Pentium3,
1747 CK_Pentium3M,
1748 CK_PentiumM,
1749 CK_C3_2,
1750
1751 /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
1752 /// Clang however has some logic to suport this.
1753 // FIXME: Warn, deprecate, and potentially remove this.
1754 CK_Yonah,
1755 //@}
1756
1757 /// \name Netburst
1758 /// Netburst microarchitecture based processors.
1759 //@{
1760 CK_Pentium4,
1761 CK_Pentium4M,
1762 CK_Prescott,
1763 CK_Nocona,
1764 //@}
1765
1766 /// \name Core
1767 /// Core microarchitecture based processors.
1768 //@{
1769 CK_Core2,
1770
1771 /// This enumerator, like \see CK_Yonah, is a bit odd. It is another
1772 /// codename which GCC no longer accepts as an option to -march, but Clang
1773 /// has some logic for recognizing it.
1774 // FIXME: Warn, deprecate, and potentially remove this.
1775 CK_Penryn,
1776 //@}
1777
1778 /// \name Atom
1779 /// Atom processors
1780 //@{
1781 CK_Atom,
1782 //@}
1783
1784 /// \name Nehalem
1785 /// Nehalem microarchitecture based processors.
1786 //@{
1787 CK_Corei7,
1788 CK_Corei7AVX,
1789 CK_CoreAVXi,
1790 CK_CoreAVX2,
1791 //@}
1792
1793 /// \name K6
1794 /// K6 architecture processors.
1795 //@{
1796 CK_K6,
1797 CK_K6_2,
1798 CK_K6_3,
1799 //@}
1800
1801 /// \name K7
1802 /// K7 architecture processors.
1803 //@{
1804 CK_Athlon,
1805 CK_AthlonThunderbird,
1806 CK_Athlon4,
1807 CK_AthlonXP,
1808 CK_AthlonMP,
1809 //@}
1810
1811 /// \name K8
1812 /// K8 architecture processors.
1813 //@{
1814 CK_Athlon64,
1815 CK_Athlon64SSE3,
1816 CK_AthlonFX,
1817 CK_K8,
1818 CK_K8SSE3,
1819 CK_Opteron,
1820 CK_OpteronSSE3,
1821 CK_AMDFAM10,
1822 //@}
1823
1824 /// \name Bobcat
1825 /// Bobcat architecture processors.
1826 //@{
1827 CK_BTVER1,
1828 //@}
1829
1830 /// \name Bulldozer
1831 /// Bulldozer architecture processors.
1832 //@{
1833 CK_BDVER1,
1834 CK_BDVER2,
1835 //@}
1836
1837 /// This specification is deprecated and will be removed in the future.
1838 /// Users should prefer \see CK_K8.
1839 // FIXME: Warn on this when the CPU is set to it.
1840 CK_x86_64,
1841 //@}
1842
1843 /// \name Geode
1844 /// Geode processors.
1845 //@{
1846 CK_Geode
1847 //@}
1848 } CPU;
1849
1850 public:
X86TargetInfo(const std::string & triple)1851 X86TargetInfo(const std::string& triple)
1852 : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
1853 HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false),
1854 HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasRTM(false),
1855 HasSSE4a(false), HasFMA4(false), HasFMA(false), HasXOP(false),
1856 HasF16C(false), CPU(CK_Generic) {
1857 BigEndian = false;
1858 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
1859 }
getFloatEvalMethod() const1860 virtual unsigned getFloatEvalMethod() const {
1861 // X87 evaluates with 80 bits "long double" precision.
1862 return SSELevel == NoSSE ? 2 : 0;
1863 }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const1864 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1865 unsigned &NumRecords) const {
1866 Records = BuiltinInfo;
1867 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
1868 }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const1869 virtual void getGCCRegNames(const char * const *&Names,
1870 unsigned &NumNames) const {
1871 Names = GCCRegNames;
1872 NumNames = llvm::array_lengthof(GCCRegNames);
1873 }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const1874 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1875 unsigned &NumAliases) const {
1876 Aliases = 0;
1877 NumAliases = 0;
1878 }
getGCCAddlRegNames(const AddlRegName * & Names,unsigned & NumNames) const1879 virtual void getGCCAddlRegNames(const AddlRegName *&Names,
1880 unsigned &NumNames) const {
1881 Names = AddlRegNames;
1882 NumNames = llvm::array_lengthof(AddlRegNames);
1883 }
1884 virtual bool validateAsmConstraint(const char *&Name,
1885 TargetInfo::ConstraintInfo &info) const;
1886 virtual std::string convertConstraint(const char *&Constraint) const;
getClobbers() const1887 virtual const char *getClobbers() const {
1888 return "~{dirflag},~{fpsr},~{flags}";
1889 }
1890 virtual void getTargetDefines(const LangOptions &Opts,
1891 MacroBuilder &Builder) const;
1892 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1893 StringRef Name,
1894 bool Enabled) const;
1895 virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
1896 virtual bool hasFeature(StringRef Feature) const;
1897 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
getABI() const1898 virtual const char* getABI() const {
1899 if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
1900 return "avx";
1901 else if (getTriple().getArch() == llvm::Triple::x86 &&
1902 MMX3DNowLevel == NoMMX3DNow)
1903 return "no-mmx";
1904 return "";
1905 }
setCPU(const std::string & Name)1906 virtual bool setCPU(const std::string &Name) {
1907 CPU = llvm::StringSwitch<CPUKind>(Name)
1908 .Case("i386", CK_i386)
1909 .Case("i486", CK_i486)
1910 .Case("winchip-c6", CK_WinChipC6)
1911 .Case("winchip2", CK_WinChip2)
1912 .Case("c3", CK_C3)
1913 .Case("i586", CK_i586)
1914 .Case("pentium", CK_Pentium)
1915 .Case("pentium-mmx", CK_PentiumMMX)
1916 .Case("i686", CK_i686)
1917 .Case("pentiumpro", CK_PentiumPro)
1918 .Case("pentium2", CK_Pentium2)
1919 .Case("pentium3", CK_Pentium3)
1920 .Case("pentium3m", CK_Pentium3M)
1921 .Case("pentium-m", CK_PentiumM)
1922 .Case("c3-2", CK_C3_2)
1923 .Case("yonah", CK_Yonah)
1924 .Case("pentium4", CK_Pentium4)
1925 .Case("pentium4m", CK_Pentium4M)
1926 .Case("prescott", CK_Prescott)
1927 .Case("nocona", CK_Nocona)
1928 .Case("core2", CK_Core2)
1929 .Case("penryn", CK_Penryn)
1930 .Case("atom", CK_Atom)
1931 .Case("corei7", CK_Corei7)
1932 .Case("corei7-avx", CK_Corei7AVX)
1933 .Case("core-avx-i", CK_CoreAVXi)
1934 .Case("core-avx2", CK_CoreAVX2)
1935 .Case("k6", CK_K6)
1936 .Case("k6-2", CK_K6_2)
1937 .Case("k6-3", CK_K6_3)
1938 .Case("athlon", CK_Athlon)
1939 .Case("athlon-tbird", CK_AthlonThunderbird)
1940 .Case("athlon-4", CK_Athlon4)
1941 .Case("athlon-xp", CK_AthlonXP)
1942 .Case("athlon-mp", CK_AthlonMP)
1943 .Case("athlon64", CK_Athlon64)
1944 .Case("athlon64-sse3", CK_Athlon64SSE3)
1945 .Case("athlon-fx", CK_AthlonFX)
1946 .Case("k8", CK_K8)
1947 .Case("k8-sse3", CK_K8SSE3)
1948 .Case("opteron", CK_Opteron)
1949 .Case("opteron-sse3", CK_OpteronSSE3)
1950 .Case("amdfam10", CK_AMDFAM10)
1951 .Case("btver1", CK_BTVER1)
1952 .Case("bdver1", CK_BDVER1)
1953 .Case("bdver2", CK_BDVER2)
1954 .Case("x86-64", CK_x86_64)
1955 .Case("geode", CK_Geode)
1956 .Default(CK_Generic);
1957
1958 // Perform any per-CPU checks necessary to determine if this CPU is
1959 // acceptable.
1960 // FIXME: This results in terrible diagnostics. Clang just says the CPU is
1961 // invalid without explaining *why*.
1962 switch (CPU) {
1963 case CK_Generic:
1964 // No processor selected!
1965 return false;
1966
1967 case CK_i386:
1968 case CK_i486:
1969 case CK_WinChipC6:
1970 case CK_WinChip2:
1971 case CK_C3:
1972 case CK_i586:
1973 case CK_Pentium:
1974 case CK_PentiumMMX:
1975 case CK_i686:
1976 case CK_PentiumPro:
1977 case CK_Pentium2:
1978 case CK_Pentium3:
1979 case CK_Pentium3M:
1980 case CK_PentiumM:
1981 case CK_Yonah:
1982 case CK_C3_2:
1983 case CK_Pentium4:
1984 case CK_Pentium4M:
1985 case CK_Prescott:
1986 case CK_K6:
1987 case CK_K6_2:
1988 case CK_K6_3:
1989 case CK_Athlon:
1990 case CK_AthlonThunderbird:
1991 case CK_Athlon4:
1992 case CK_AthlonXP:
1993 case CK_AthlonMP:
1994 case CK_Geode:
1995 // Only accept certain architectures when compiling in 32-bit mode.
1996 if (getTriple().getArch() != llvm::Triple::x86)
1997 return false;
1998
1999 // Fallthrough
2000 case CK_Nocona:
2001 case CK_Core2:
2002 case CK_Penryn:
2003 case CK_Atom:
2004 case CK_Corei7:
2005 case CK_Corei7AVX:
2006 case CK_CoreAVXi:
2007 case CK_CoreAVX2:
2008 case CK_Athlon64:
2009 case CK_Athlon64SSE3:
2010 case CK_AthlonFX:
2011 case CK_K8:
2012 case CK_K8SSE3:
2013 case CK_Opteron:
2014 case CK_OpteronSSE3:
2015 case CK_AMDFAM10:
2016 case CK_BTVER1:
2017 case CK_BDVER1:
2018 case CK_BDVER2:
2019 case CK_x86_64:
2020 return true;
2021 }
2022 llvm_unreachable("Unhandled CPU kind");
2023 }
2024
checkCallingConvention(CallingConv CC) const2025 virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
2026 // We accept all non-ARM calling conventions
2027 return (CC == CC_X86ThisCall ||
2028 CC == CC_X86FastCall ||
2029 CC == CC_X86StdCall ||
2030 CC == CC_C ||
2031 CC == CC_X86Pascal ||
2032 CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
2033 }
2034
getDefaultCallingConv(CallingConvMethodType MT) const2035 virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
2036 return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
2037 }
2038 };
2039
getDefaultFeatures(llvm::StringMap<bool> & Features) const2040 void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
2041 // FIXME: This should not be here.
2042 Features["3dnow"] = false;
2043 Features["3dnowa"] = false;
2044 Features["mmx"] = false;
2045 Features["sse"] = false;
2046 Features["sse2"] = false;
2047 Features["sse3"] = false;
2048 Features["ssse3"] = false;
2049 Features["sse41"] = false;
2050 Features["sse42"] = false;
2051 Features["sse4a"] = false;
2052 Features["aes"] = false;
2053 Features["pclmul"] = false;
2054 Features["avx"] = false;
2055 Features["avx2"] = false;
2056 Features["lzcnt"] = false;
2057 Features["rdrand"] = false;
2058 Features["bmi"] = false;
2059 Features["bmi2"] = false;
2060 Features["popcnt"] = false;
2061 Features["rtm"] = false;
2062 Features["fma4"] = false;
2063 Features["fma"] = false;
2064 Features["xop"] = false;
2065 Features["f16c"] = false;
2066
2067 // FIXME: This *really* should not be here.
2068
2069 // X86_64 always has SSE2.
2070 if (getTriple().getArch() == llvm::Triple::x86_64)
2071 setFeatureEnabled(Features, "sse2", true);
2072
2073 switch (CPU) {
2074 case CK_Generic:
2075 case CK_i386:
2076 case CK_i486:
2077 case CK_i586:
2078 case CK_Pentium:
2079 case CK_i686:
2080 case CK_PentiumPro:
2081 break;
2082 case CK_PentiumMMX:
2083 case CK_Pentium2:
2084 setFeatureEnabled(Features, "mmx", true);
2085 break;
2086 case CK_Pentium3:
2087 case CK_Pentium3M:
2088 setFeatureEnabled(Features, "sse", true);
2089 break;
2090 case CK_PentiumM:
2091 case CK_Pentium4:
2092 case CK_Pentium4M:
2093 case CK_x86_64:
2094 setFeatureEnabled(Features, "sse2", true);
2095 break;
2096 case CK_Yonah:
2097 case CK_Prescott:
2098 case CK_Nocona:
2099 setFeatureEnabled(Features, "sse3", true);
2100 break;
2101 case CK_Core2:
2102 setFeatureEnabled(Features, "ssse3", true);
2103 break;
2104 case CK_Penryn:
2105 setFeatureEnabled(Features, "sse4.1", true);
2106 break;
2107 case CK_Atom:
2108 setFeatureEnabled(Features, "ssse3", true);
2109 break;
2110 case CK_Corei7:
2111 setFeatureEnabled(Features, "sse4", true);
2112 break;
2113 case CK_Corei7AVX:
2114 setFeatureEnabled(Features, "avx", true);
2115 setFeatureEnabled(Features, "aes", true);
2116 setFeatureEnabled(Features, "pclmul", true);
2117 break;
2118 case CK_CoreAVXi:
2119 setFeatureEnabled(Features, "avx", true);
2120 setFeatureEnabled(Features, "aes", true);
2121 setFeatureEnabled(Features, "pclmul", true);
2122 setFeatureEnabled(Features, "rdrnd", true);
2123 setFeatureEnabled(Features, "f16c", true);
2124 break;
2125 case CK_CoreAVX2:
2126 setFeatureEnabled(Features, "avx2", true);
2127 setFeatureEnabled(Features, "aes", true);
2128 setFeatureEnabled(Features, "pclmul", true);
2129 setFeatureEnabled(Features, "lzcnt", true);
2130 setFeatureEnabled(Features, "rdrnd", true);
2131 setFeatureEnabled(Features, "f16c", true);
2132 setFeatureEnabled(Features, "bmi", true);
2133 setFeatureEnabled(Features, "bmi2", true);
2134 setFeatureEnabled(Features, "rtm", true);
2135 setFeatureEnabled(Features, "fma", true);
2136 break;
2137 case CK_K6:
2138 case CK_WinChipC6:
2139 setFeatureEnabled(Features, "mmx", true);
2140 break;
2141 case CK_K6_2:
2142 case CK_K6_3:
2143 case CK_WinChip2:
2144 case CK_C3:
2145 setFeatureEnabled(Features, "3dnow", true);
2146 break;
2147 case CK_Athlon:
2148 case CK_AthlonThunderbird:
2149 case CK_Geode:
2150 setFeatureEnabled(Features, "3dnowa", true);
2151 break;
2152 case CK_Athlon4:
2153 case CK_AthlonXP:
2154 case CK_AthlonMP:
2155 setFeatureEnabled(Features, "sse", true);
2156 setFeatureEnabled(Features, "3dnowa", true);
2157 break;
2158 case CK_K8:
2159 case CK_Opteron:
2160 case CK_Athlon64:
2161 case CK_AthlonFX:
2162 setFeatureEnabled(Features, "sse2", true);
2163 setFeatureEnabled(Features, "3dnowa", true);
2164 break;
2165 case CK_K8SSE3:
2166 case CK_OpteronSSE3:
2167 case CK_Athlon64SSE3:
2168 setFeatureEnabled(Features, "sse3", true);
2169 setFeatureEnabled(Features, "3dnowa", true);
2170 break;
2171 case CK_AMDFAM10:
2172 setFeatureEnabled(Features, "sse3", true);
2173 setFeatureEnabled(Features, "sse4a", true);
2174 setFeatureEnabled(Features, "3dnowa", true);
2175 setFeatureEnabled(Features, "lzcnt", true);
2176 setFeatureEnabled(Features, "popcnt", true);
2177 break;
2178 case CK_BTVER1:
2179 setFeatureEnabled(Features, "ssse3", true);
2180 setFeatureEnabled(Features, "sse4a", true);
2181 setFeatureEnabled(Features, "lzcnt", true);
2182 setFeatureEnabled(Features, "popcnt", true);
2183 break;
2184 case CK_BDVER1:
2185 setFeatureEnabled(Features, "xop", true);
2186 setFeatureEnabled(Features, "lzcnt", true);
2187 setFeatureEnabled(Features, "aes", true);
2188 setFeatureEnabled(Features, "pclmul", true);
2189 break;
2190 case CK_BDVER2:
2191 setFeatureEnabled(Features, "xop", true);
2192 setFeatureEnabled(Features, "lzcnt", true);
2193 setFeatureEnabled(Features, "aes", true);
2194 setFeatureEnabled(Features, "pclmul", true);
2195 setFeatureEnabled(Features, "bmi", true);
2196 setFeatureEnabled(Features, "fma", true);
2197 setFeatureEnabled(Features, "f16c", true);
2198 break;
2199 case CK_C3_2:
2200 setFeatureEnabled(Features, "sse", true);
2201 break;
2202 }
2203 }
2204
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const2205 bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
2206 StringRef Name,
2207 bool Enabled) const {
2208 // FIXME: This *really* should not be here. We need some way of translating
2209 // options into llvm subtarget features.
2210 if (!Features.count(Name) &&
2211 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1" &&
2212 Name != "rdrnd"))
2213 return false;
2214
2215 // FIXME: this should probably use a switch with fall through.
2216
2217 if (Enabled) {
2218 if (Name == "mmx")
2219 Features["mmx"] = true;
2220 else if (Name == "sse")
2221 Features["mmx"] = Features["sse"] = true;
2222 else if (Name == "sse2")
2223 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
2224 else if (Name == "sse3")
2225 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2226 true;
2227 else if (Name == "ssse3")
2228 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2229 Features["ssse3"] = true;
2230 else if (Name == "sse4" || Name == "sse4.2")
2231 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2232 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2233 Features["popcnt"] = true;
2234 else if (Name == "sse4.1")
2235 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2236 Features["ssse3"] = Features["sse41"] = true;
2237 else if (Name == "3dnow")
2238 Features["mmx"] = Features["3dnow"] = true;
2239 else if (Name == "3dnowa")
2240 Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true;
2241 else if (Name == "aes")
2242 Features["sse"] = Features["sse2"] = Features["aes"] = true;
2243 else if (Name == "pclmul")
2244 Features["sse"] = Features["sse2"] = Features["pclmul"] = true;
2245 else if (Name == "avx")
2246 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2247 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2248 Features["popcnt"] = Features["avx"] = true;
2249 else if (Name == "avx2")
2250 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2251 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2252 Features["popcnt"] = Features["avx"] = Features["avx2"] = true;
2253 else if (Name == "fma")
2254 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2255 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2256 Features["popcnt"] = Features["avx"] = Features["fma"] = true;
2257 else if (Name == "fma4")
2258 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2259 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2260 Features["popcnt"] = Features["avx"] = Features["sse4a"] =
2261 Features["fma4"] = true;
2262 else if (Name == "xop")
2263 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2264 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2265 Features["popcnt"] = Features["avx"] = Features["sse4a"] =
2266 Features["fma4"] = Features["xop"] = true;
2267 else if (Name == "sse4a")
2268 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
2269 Features["sse4a"] = true;
2270 else if (Name == "lzcnt")
2271 Features["lzcnt"] = true;
2272 else if (Name == "rdrnd")
2273 Features["rdrand"] = true;
2274 else if (Name == "bmi")
2275 Features["bmi"] = true;
2276 else if (Name == "bmi2")
2277 Features["bmi2"] = true;
2278 else if (Name == "popcnt")
2279 Features["popcnt"] = true;
2280 else if (Name == "f16c")
2281 Features["f16c"] = true;
2282 else if (Name == "rtm")
2283 Features["rtm"] = true;
2284 } else {
2285 if (Name == "mmx")
2286 Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false;
2287 else if (Name == "sse")
2288 Features["sse"] = Features["sse2"] = Features["sse3"] =
2289 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2290 Features["sse4a"] = Features["avx"] = Features["avx2"] =
2291 Features["fma"] = Features["fma4"] = Features["aes"] =
2292 Features["pclmul"] = Features["xop"] = false;
2293 else if (Name == "sse2")
2294 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
2295 Features["sse41"] = Features["sse42"] = Features["sse4a"] =
2296 Features["avx"] = Features["avx2"] = Features["fma"] =
2297 Features["fma4"] = Features["aes"] = Features["pclmul"] =
2298 Features["xop"] = false;
2299 else if (Name == "sse3")
2300 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
2301 Features["sse42"] = Features["sse4a"] = Features["avx"] =
2302 Features["avx2"] = Features["fma"] = Features["fma4"] =
2303 Features["xop"] = false;
2304 else if (Name == "ssse3")
2305 Features["ssse3"] = Features["sse41"] = Features["sse42"] =
2306 Features["avx"] = Features["avx2"] = Features["fma"] = false;
2307 else if (Name == "sse4" || Name == "sse4.1")
2308 Features["sse41"] = Features["sse42"] = Features["avx"] =
2309 Features["avx2"] = Features["fma"] = false;
2310 else if (Name == "sse4.2")
2311 Features["sse42"] = Features["avx"] = Features["avx2"] =
2312 Features["fma"] = false;
2313 else if (Name == "3dnow")
2314 Features["3dnow"] = Features["3dnowa"] = false;
2315 else if (Name == "3dnowa")
2316 Features["3dnowa"] = false;
2317 else if (Name == "aes")
2318 Features["aes"] = false;
2319 else if (Name == "pclmul")
2320 Features["pclmul"] = false;
2321 else if (Name == "avx")
2322 Features["avx"] = Features["avx2"] = Features["fma"] =
2323 Features["fma4"] = Features["xop"] = false;
2324 else if (Name == "avx2")
2325 Features["avx2"] = false;
2326 else if (Name == "fma")
2327 Features["fma"] = false;
2328 else if (Name == "sse4a")
2329 Features["sse4a"] = Features["fma4"] = Features["xop"] = false;
2330 else if (Name == "lzcnt")
2331 Features["lzcnt"] = false;
2332 else if (Name == "rdrnd")
2333 Features["rdrand"] = false;
2334 else if (Name == "bmi")
2335 Features["bmi"] = false;
2336 else if (Name == "bmi2")
2337 Features["bmi2"] = false;
2338 else if (Name == "popcnt")
2339 Features["popcnt"] = false;
2340 else if (Name == "fma4")
2341 Features["fma4"] = Features["xop"] = false;
2342 else if (Name == "xop")
2343 Features["xop"] = false;
2344 else if (Name == "f16c")
2345 Features["f16c"] = false;
2346 else if (Name == "rtm")
2347 Features["rtm"] = false;
2348 }
2349
2350 return true;
2351 }
2352
2353 /// HandleTargetOptions - Perform initialization based on the user
2354 /// configured set of features.
HandleTargetFeatures(std::vector<std::string> & Features)2355 void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
2356 // Remember the maximum enabled sselevel.
2357 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
2358 // Ignore disabled features.
2359 if (Features[i][0] == '-')
2360 continue;
2361
2362 StringRef Feature = StringRef(Features[i]).substr(1);
2363
2364 if (Feature == "aes") {
2365 HasAES = true;
2366 continue;
2367 }
2368
2369 if (Feature == "pclmul") {
2370 HasPCLMUL = true;
2371 continue;
2372 }
2373
2374 if (Feature == "lzcnt") {
2375 HasLZCNT = true;
2376 continue;
2377 }
2378
2379 if (Feature == "rdrand") {
2380 HasRDRND = true;
2381 continue;
2382 }
2383
2384 if (Feature == "bmi") {
2385 HasBMI = true;
2386 continue;
2387 }
2388
2389 if (Feature == "bmi2") {
2390 HasBMI2 = true;
2391 continue;
2392 }
2393
2394 if (Feature == "popcnt") {
2395 HasPOPCNT = true;
2396 continue;
2397 }
2398
2399 if (Feature == "rtm") {
2400 HasRTM = true;
2401 continue;
2402 }
2403
2404 if (Feature == "sse4a") {
2405 HasSSE4a = true;
2406 continue;
2407 }
2408
2409 if (Feature == "fma4") {
2410 HasFMA4 = true;
2411 continue;
2412 }
2413
2414 if (Feature == "fma") {
2415 HasFMA = true;
2416 continue;
2417 }
2418
2419 if (Feature == "xop") {
2420 HasXOP = true;
2421 continue;
2422 }
2423
2424 if (Feature == "f16c") {
2425 HasF16C = true;
2426 continue;
2427 }
2428
2429 assert(Features[i][0] == '+' && "Invalid target feature!");
2430 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
2431 .Case("avx2", AVX2)
2432 .Case("avx", AVX)
2433 .Case("sse42", SSE42)
2434 .Case("sse41", SSE41)
2435 .Case("ssse3", SSSE3)
2436 .Case("sse3", SSE3)
2437 .Case("sse2", SSE2)
2438 .Case("sse", SSE1)
2439 .Default(NoSSE);
2440 SSELevel = std::max(SSELevel, Level);
2441
2442 MMX3DNowEnum ThreeDNowLevel =
2443 llvm::StringSwitch<MMX3DNowEnum>(Feature)
2444 .Case("3dnowa", AMD3DNowAthlon)
2445 .Case("3dnow", AMD3DNow)
2446 .Case("mmx", MMX)
2447 .Default(NoMMX3DNow);
2448
2449 MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
2450 }
2451
2452 // Don't tell the backend if we're turning off mmx; it will end up disabling
2453 // SSE, which we don't want.
2454 std::vector<std::string>::iterator it;
2455 it = std::find(Features.begin(), Features.end(), "-mmx");
2456 if (it != Features.end())
2457 Features.erase(it);
2458 }
2459
2460 /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
2461 /// definitions for this particular subtarget.
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2462 void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
2463 MacroBuilder &Builder) const {
2464 // Target identification.
2465 if (getTriple().getArch() == llvm::Triple::x86_64) {
2466 Builder.defineMacro("__amd64__");
2467 Builder.defineMacro("__amd64");
2468 Builder.defineMacro("__x86_64");
2469 Builder.defineMacro("__x86_64__");
2470 } else {
2471 DefineStd(Builder, "i386", Opts);
2472 }
2473
2474 // Subtarget options.
2475 // FIXME: We are hard-coding the tune parameters based on the CPU, but they
2476 // truly should be based on -mtune options.
2477 switch (CPU) {
2478 case CK_Generic:
2479 break;
2480 case CK_i386:
2481 // The rest are coming from the i386 define above.
2482 Builder.defineMacro("__tune_i386__");
2483 break;
2484 case CK_i486:
2485 case CK_WinChipC6:
2486 case CK_WinChip2:
2487 case CK_C3:
2488 defineCPUMacros(Builder, "i486");
2489 break;
2490 case CK_PentiumMMX:
2491 Builder.defineMacro("__pentium_mmx__");
2492 Builder.defineMacro("__tune_pentium_mmx__");
2493 // Fallthrough
2494 case CK_i586:
2495 case CK_Pentium:
2496 defineCPUMacros(Builder, "i586");
2497 defineCPUMacros(Builder, "pentium");
2498 break;
2499 case CK_Pentium3:
2500 case CK_Pentium3M:
2501 case CK_PentiumM:
2502 Builder.defineMacro("__tune_pentium3__");
2503 // Fallthrough
2504 case CK_Pentium2:
2505 case CK_C3_2:
2506 Builder.defineMacro("__tune_pentium2__");
2507 // Fallthrough
2508 case CK_PentiumPro:
2509 Builder.defineMacro("__tune_i686__");
2510 Builder.defineMacro("__tune_pentiumpro__");
2511 // Fallthrough
2512 case CK_i686:
2513 Builder.defineMacro("__i686");
2514 Builder.defineMacro("__i686__");
2515 // Strangely, __tune_i686__ isn't defined by GCC when CPU == i686.
2516 Builder.defineMacro("__pentiumpro");
2517 Builder.defineMacro("__pentiumpro__");
2518 break;
2519 case CK_Pentium4:
2520 case CK_Pentium4M:
2521 defineCPUMacros(Builder, "pentium4");
2522 break;
2523 case CK_Yonah:
2524 case CK_Prescott:
2525 case CK_Nocona:
2526 defineCPUMacros(Builder, "nocona");
2527 break;
2528 case CK_Core2:
2529 case CK_Penryn:
2530 defineCPUMacros(Builder, "core2");
2531 break;
2532 case CK_Atom:
2533 defineCPUMacros(Builder, "atom");
2534 break;
2535 case CK_Corei7:
2536 case CK_Corei7AVX:
2537 case CK_CoreAVXi:
2538 case CK_CoreAVX2:
2539 defineCPUMacros(Builder, "corei7");
2540 break;
2541 case CK_K6_2:
2542 Builder.defineMacro("__k6_2__");
2543 Builder.defineMacro("__tune_k6_2__");
2544 // Fallthrough
2545 case CK_K6_3:
2546 if (CPU != CK_K6_2) { // In case of fallthrough
2547 // FIXME: GCC may be enabling these in cases where some other k6
2548 // architecture is specified but -m3dnow is explicitly provided. The
2549 // exact semantics need to be determined and emulated here.
2550 Builder.defineMacro("__k6_3__");
2551 Builder.defineMacro("__tune_k6_3__");
2552 }
2553 // Fallthrough
2554 case CK_K6:
2555 defineCPUMacros(Builder, "k6");
2556 break;
2557 case CK_Athlon:
2558 case CK_AthlonThunderbird:
2559 case CK_Athlon4:
2560 case CK_AthlonXP:
2561 case CK_AthlonMP:
2562 defineCPUMacros(Builder, "athlon");
2563 if (SSELevel != NoSSE) {
2564 Builder.defineMacro("__athlon_sse__");
2565 Builder.defineMacro("__tune_athlon_sse__");
2566 }
2567 break;
2568 case CK_K8:
2569 case CK_K8SSE3:
2570 case CK_x86_64:
2571 case CK_Opteron:
2572 case CK_OpteronSSE3:
2573 case CK_Athlon64:
2574 case CK_Athlon64SSE3:
2575 case CK_AthlonFX:
2576 defineCPUMacros(Builder, "k8");
2577 break;
2578 case CK_AMDFAM10:
2579 defineCPUMacros(Builder, "amdfam10");
2580 break;
2581 case CK_BTVER1:
2582 defineCPUMacros(Builder, "btver1");
2583 break;
2584 case CK_BDVER1:
2585 defineCPUMacros(Builder, "bdver1");
2586 break;
2587 case CK_BDVER2:
2588 defineCPUMacros(Builder, "bdver2");
2589 break;
2590 case CK_Geode:
2591 defineCPUMacros(Builder, "geode");
2592 break;
2593 }
2594
2595 // Target properties.
2596 Builder.defineMacro("__LITTLE_ENDIAN__");
2597 Builder.defineMacro("__REGISTER_PREFIX__", "");
2598
2599 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
2600 // functions in glibc header files that use FP Stack inline asm which the
2601 // backend can't deal with (PR879).
2602 Builder.defineMacro("__NO_MATH_INLINES");
2603
2604 if (HasAES)
2605 Builder.defineMacro("__AES__");
2606
2607 if (HasPCLMUL)
2608 Builder.defineMacro("__PCLMUL__");
2609
2610 if (HasLZCNT)
2611 Builder.defineMacro("__LZCNT__");
2612
2613 if (HasRDRND)
2614 Builder.defineMacro("__RDRND__");
2615
2616 if (HasBMI)
2617 Builder.defineMacro("__BMI__");
2618
2619 if (HasBMI2)
2620 Builder.defineMacro("__BMI2__");
2621
2622 if (HasPOPCNT)
2623 Builder.defineMacro("__POPCNT__");
2624
2625 if (HasRTM)
2626 Builder.defineMacro("__RTM__");
2627
2628 if (HasSSE4a)
2629 Builder.defineMacro("__SSE4A__");
2630
2631 if (HasFMA4)
2632 Builder.defineMacro("__FMA4__");
2633
2634 if (HasFMA)
2635 Builder.defineMacro("__FMA__");
2636
2637 if (HasXOP)
2638 Builder.defineMacro("__XOP__");
2639
2640 if (HasF16C)
2641 Builder.defineMacro("__F16C__");
2642
2643 // Each case falls through to the previous one here.
2644 switch (SSELevel) {
2645 case AVX2:
2646 Builder.defineMacro("__AVX2__");
2647 case AVX:
2648 Builder.defineMacro("__AVX__");
2649 case SSE42:
2650 Builder.defineMacro("__SSE4_2__");
2651 case SSE41:
2652 Builder.defineMacro("__SSE4_1__");
2653 case SSSE3:
2654 Builder.defineMacro("__SSSE3__");
2655 case SSE3:
2656 Builder.defineMacro("__SSE3__");
2657 case SSE2:
2658 Builder.defineMacro("__SSE2__");
2659 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
2660 case SSE1:
2661 Builder.defineMacro("__SSE__");
2662 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
2663 case NoSSE:
2664 break;
2665 }
2666
2667 if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
2668 switch (SSELevel) {
2669 case AVX2:
2670 case AVX:
2671 case SSE42:
2672 case SSE41:
2673 case SSSE3:
2674 case SSE3:
2675 case SSE2:
2676 Builder.defineMacro("_M_IX86_FP", Twine(2));
2677 break;
2678 case SSE1:
2679 Builder.defineMacro("_M_IX86_FP", Twine(1));
2680 break;
2681 default:
2682 Builder.defineMacro("_M_IX86_FP", Twine(0));
2683 }
2684 }
2685
2686 // Each case falls through to the previous one here.
2687 switch (MMX3DNowLevel) {
2688 case AMD3DNowAthlon:
2689 Builder.defineMacro("__3dNOW_A__");
2690 case AMD3DNow:
2691 Builder.defineMacro("__3dNOW__");
2692 case MMX:
2693 Builder.defineMacro("__MMX__");
2694 case NoMMX3DNow:
2695 break;
2696 }
2697 }
2698
hasFeature(StringRef Feature) const2699 bool X86TargetInfo::hasFeature(StringRef Feature) const {
2700 return llvm::StringSwitch<bool>(Feature)
2701 .Case("aes", HasAES)
2702 .Case("avx", SSELevel >= AVX)
2703 .Case("avx2", SSELevel >= AVX2)
2704 .Case("bmi", HasBMI)
2705 .Case("bmi2", HasBMI2)
2706 .Case("fma", HasFMA)
2707 .Case("fma4", HasFMA4)
2708 .Case("lzcnt", HasLZCNT)
2709 .Case("rdrnd", HasRDRND)
2710 .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
2711 .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
2712 .Case("mmx", MMX3DNowLevel >= MMX)
2713 .Case("pclmul", HasPCLMUL)
2714 .Case("popcnt", HasPOPCNT)
2715 .Case("rtm", HasRTM)
2716 .Case("sse", SSELevel >= SSE1)
2717 .Case("sse2", SSELevel >= SSE2)
2718 .Case("sse3", SSELevel >= SSE3)
2719 .Case("ssse3", SSELevel >= SSSE3)
2720 .Case("sse41", SSELevel >= SSE41)
2721 .Case("sse42", SSELevel >= SSE42)
2722 .Case("sse4a", HasSSE4a)
2723 .Case("x86", true)
2724 .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
2725 .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
2726 .Case("xop", HasXOP)
2727 .Case("f16c", HasF16C)
2728 .Default(false);
2729 }
2730
2731 bool
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const2732 X86TargetInfo::validateAsmConstraint(const char *&Name,
2733 TargetInfo::ConstraintInfo &Info) const {
2734 switch (*Name) {
2735 default: return false;
2736 case 'Y': // first letter of a pair:
2737 switch (*(Name+1)) {
2738 default: return false;
2739 case '0': // First SSE register.
2740 case 't': // Any SSE register, when SSE2 is enabled.
2741 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
2742 case 'm': // any MMX register, when inter-unit moves enabled.
2743 break; // falls through to setAllowsRegister.
2744 }
2745 case 'a': // eax.
2746 case 'b': // ebx.
2747 case 'c': // ecx.
2748 case 'd': // edx.
2749 case 'S': // esi.
2750 case 'D': // edi.
2751 case 'A': // edx:eax.
2752 case 'f': // any x87 floating point stack register.
2753 case 't': // top of floating point stack.
2754 case 'u': // second from top of floating point stack.
2755 case 'q': // Any register accessible as [r]l: a, b, c, and d.
2756 case 'y': // Any MMX register.
2757 case 'x': // Any SSE register.
2758 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
2759 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
2760 case 'l': // "Index" registers: any general register that can be used as an
2761 // index in a base+index memory access.
2762 Info.setAllowsRegister();
2763 return true;
2764 case 'C': // SSE floating point constant.
2765 case 'G': // x87 floating point constant.
2766 case 'e': // 32-bit signed integer constant for use with zero-extending
2767 // x86_64 instructions.
2768 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
2769 // x86_64 instructions.
2770 return true;
2771 }
2772 }
2773
2774
2775 std::string
convertConstraint(const char * & Constraint) const2776 X86TargetInfo::convertConstraint(const char *&Constraint) const {
2777 switch (*Constraint) {
2778 case 'a': return std::string("{ax}");
2779 case 'b': return std::string("{bx}");
2780 case 'c': return std::string("{cx}");
2781 case 'd': return std::string("{dx}");
2782 case 'S': return std::string("{si}");
2783 case 'D': return std::string("{di}");
2784 case 'p': // address
2785 return std::string("im");
2786 case 't': // top of floating point stack.
2787 return std::string("{st}");
2788 case 'u': // second from top of floating point stack.
2789 return std::string("{st(1)}"); // second from top of floating point stack.
2790 default:
2791 return std::string(1, *Constraint);
2792 }
2793 }
2794 } // end anonymous namespace
2795
2796 namespace {
2797 // X86-32 generic target
2798 class X86_32TargetInfo : public X86TargetInfo {
2799 public:
X86_32TargetInfo(const std::string & triple)2800 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
2801 DoubleAlign = LongLongAlign = 32;
2802 LongDoubleWidth = 96;
2803 LongDoubleAlign = 32;
2804 SuitableAlign = 128;
2805 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
2806 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
2807 "a0:0:64-f80:32:32-n8:16:32-S128";
2808 SizeType = UnsignedInt;
2809 PtrDiffType = SignedInt;
2810 IntPtrType = SignedInt;
2811 RegParmMax = 3;
2812
2813 // Use fpret for all types.
2814 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
2815 (1 << TargetInfo::Double) |
2816 (1 << TargetInfo::LongDouble));
2817
2818 // x86-32 has atomics up to 8 bytes
2819 // FIXME: Check that we actually have cmpxchg8b before setting
2820 // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
2821 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
2822 }
getBuiltinVaListKind() const2823 virtual BuiltinVaListKind getBuiltinVaListKind() const {
2824 return TargetInfo::CharPtrBuiltinVaList;
2825 }
2826
getEHDataRegisterNumber(unsigned RegNo) const2827 int getEHDataRegisterNumber(unsigned RegNo) const {
2828 if (RegNo == 0) return 0;
2829 if (RegNo == 1) return 2;
2830 return -1;
2831 }
validateInputSize(StringRef Constraint,unsigned Size) const2832 virtual bool validateInputSize(StringRef Constraint,
2833 unsigned Size) const {
2834 switch (Constraint[0]) {
2835 default: break;
2836 case 'a':
2837 case 'b':
2838 case 'c':
2839 case 'd':
2840 return Size <= 32;
2841 }
2842
2843 return true;
2844 }
2845 };
2846 } // end anonymous namespace
2847
2848 namespace {
2849 class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
2850 public:
NetBSDI386TargetInfo(const std::string & triple)2851 NetBSDI386TargetInfo(const std::string &triple) :
2852 NetBSDTargetInfo<X86_32TargetInfo>(triple) {
2853 }
2854
getFloatEvalMethod() const2855 virtual unsigned getFloatEvalMethod() const {
2856 // NetBSD defaults to "double" rounding
2857 return 1;
2858 }
2859 };
2860 } // end anonymous namespace
2861
2862 namespace {
2863 class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
2864 public:
OpenBSDI386TargetInfo(const std::string & triple)2865 OpenBSDI386TargetInfo(const std::string& triple) :
2866 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
2867 SizeType = UnsignedLong;
2868 IntPtrType = SignedLong;
2869 PtrDiffType = SignedLong;
2870 }
2871 };
2872 } // end anonymous namespace
2873
2874 namespace {
2875 class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
2876 public:
BitrigI386TargetInfo(const std::string & triple)2877 BitrigI386TargetInfo(const std::string& triple) :
2878 BitrigTargetInfo<X86_32TargetInfo>(triple) {
2879 SizeType = UnsignedLong;
2880 IntPtrType = SignedLong;
2881 PtrDiffType = SignedLong;
2882 }
2883 };
2884 } // end anonymous namespace
2885
2886 namespace {
2887 class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
2888 public:
DarwinI386TargetInfo(const std::string & triple)2889 DarwinI386TargetInfo(const std::string& triple) :
2890 DarwinTargetInfo<X86_32TargetInfo>(triple) {
2891 LongDoubleWidth = 128;
2892 LongDoubleAlign = 128;
2893 SuitableAlign = 128;
2894 MaxVectorAlign = 256;
2895 SizeType = UnsignedLong;
2896 IntPtrType = SignedLong;
2897 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
2898 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
2899 "a0:0:64-f80:128:128-n8:16:32-S128";
2900 HasAlignMac68kSupport = true;
2901 }
2902
2903 };
2904 } // end anonymous namespace
2905
2906 namespace {
2907 // x86-32 Windows target
2908 class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
2909 public:
WindowsX86_32TargetInfo(const std::string & triple)2910 WindowsX86_32TargetInfo(const std::string& triple)
2911 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
2912 TLSSupported = false;
2913 WCharType = UnsignedShort;
2914 DoubleAlign = LongLongAlign = 64;
2915 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
2916 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
2917 "v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32";
2918 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2919 virtual void getTargetDefines(const LangOptions &Opts,
2920 MacroBuilder &Builder) const {
2921 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
2922 }
2923 };
2924 } // end anonymous namespace
2925
2926 namespace {
2927
2928 // x86-32 Windows Visual Studio target
2929 class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
2930 public:
VisualStudioWindowsX86_32TargetInfo(const std::string & triple)2931 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
2932 : WindowsX86_32TargetInfo(triple) {
2933 LongDoubleWidth = LongDoubleAlign = 64;
2934 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
2935 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2936 virtual void getTargetDefines(const LangOptions &Opts,
2937 MacroBuilder &Builder) const {
2938 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
2939 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
2940 // The value of the following reflects processor type.
2941 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
2942 // We lost the original triple, so we use the default.
2943 Builder.defineMacro("_M_IX86", "600");
2944 }
2945 };
2946 } // end anonymous namespace
2947
2948 namespace {
2949 // x86-32 MinGW target
2950 class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
2951 public:
MinGWX86_32TargetInfo(const std::string & triple)2952 MinGWX86_32TargetInfo(const std::string& triple)
2953 : WindowsX86_32TargetInfo(triple) {
2954 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2955 virtual void getTargetDefines(const LangOptions &Opts,
2956 MacroBuilder &Builder) const {
2957 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
2958 DefineStd(Builder, "WIN32", Opts);
2959 DefineStd(Builder, "WINNT", Opts);
2960 Builder.defineMacro("_X86_");
2961 Builder.defineMacro("__MSVCRT__");
2962 Builder.defineMacro("__MINGW32__");
2963
2964 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
2965 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
2966 if (Opts.MicrosoftExt)
2967 // Provide "as-is" __declspec.
2968 Builder.defineMacro("__declspec", "__declspec");
2969 else
2970 // Provide alias of __attribute__ like mingw32-gcc.
2971 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
2972 }
2973 };
2974 } // end anonymous namespace
2975
2976 namespace {
2977 // x86-32 Cygwin target
2978 class CygwinX86_32TargetInfo : public X86_32TargetInfo {
2979 public:
CygwinX86_32TargetInfo(const std::string & triple)2980 CygwinX86_32TargetInfo(const std::string& triple)
2981 : X86_32TargetInfo(triple) {
2982 TLSSupported = false;
2983 WCharType = UnsignedShort;
2984 DoubleAlign = LongLongAlign = 64;
2985 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
2986 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
2987 "a0:0:64-f80:32:32-n8:16:32-S32";
2988 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const2989 virtual void getTargetDefines(const LangOptions &Opts,
2990 MacroBuilder &Builder) const {
2991 X86_32TargetInfo::getTargetDefines(Opts, Builder);
2992 Builder.defineMacro("_X86_");
2993 Builder.defineMacro("__CYGWIN__");
2994 Builder.defineMacro("__CYGWIN32__");
2995 DefineStd(Builder, "unix", Opts);
2996 if (Opts.CPlusPlus)
2997 Builder.defineMacro("_GNU_SOURCE");
2998 }
2999 };
3000 } // end anonymous namespace
3001
3002 namespace {
3003 // x86-32 Haiku target
3004 class HaikuX86_32TargetInfo : public X86_32TargetInfo {
3005 public:
HaikuX86_32TargetInfo(const std::string & triple)3006 HaikuX86_32TargetInfo(const std::string& triple)
3007 : X86_32TargetInfo(triple) {
3008 SizeType = UnsignedLong;
3009 IntPtrType = SignedLong;
3010 PtrDiffType = SignedLong;
3011 ProcessIDType = SignedLong;
3012 this->UserLabelPrefix = "";
3013 this->TLSSupported = false;
3014 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3015 virtual void getTargetDefines(const LangOptions &Opts,
3016 MacroBuilder &Builder) const {
3017 X86_32TargetInfo::getTargetDefines(Opts, Builder);
3018 Builder.defineMacro("__INTEL__");
3019 Builder.defineMacro("__HAIKU__");
3020 }
3021 };
3022 } // end anonymous namespace
3023
3024 // RTEMS Target
3025 template<typename Target>
3026 class RTEMSTargetInfo : public OSTargetInfo<Target> {
3027 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const3028 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
3029 MacroBuilder &Builder) const {
3030 // RTEMS defines; list based off of gcc output
3031
3032 Builder.defineMacro("__rtems__");
3033 Builder.defineMacro("__ELF__");
3034 }
3035 public:
RTEMSTargetInfo(const std::string & triple)3036 RTEMSTargetInfo(const std::string &triple)
3037 : OSTargetInfo<Target>(triple) {
3038 this->UserLabelPrefix = "";
3039
3040 llvm::Triple Triple(triple);
3041 switch (Triple.getArch()) {
3042 default:
3043 case llvm::Triple::x86:
3044 // this->MCountName = ".mcount";
3045 break;
3046 case llvm::Triple::mips:
3047 case llvm::Triple::mipsel:
3048 case llvm::Triple::ppc:
3049 case llvm::Triple::ppc64:
3050 // this->MCountName = "_mcount";
3051 break;
3052 case llvm::Triple::arm:
3053 // this->MCountName = "__mcount";
3054 break;
3055 }
3056
3057 }
3058 };
3059
3060 namespace {
3061 // x86-32 RTEMS target
3062 class RTEMSX86_32TargetInfo : public X86_32TargetInfo {
3063 public:
RTEMSX86_32TargetInfo(const std::string & triple)3064 RTEMSX86_32TargetInfo(const std::string& triple)
3065 : X86_32TargetInfo(triple) {
3066 SizeType = UnsignedLong;
3067 IntPtrType = SignedLong;
3068 PtrDiffType = SignedLong;
3069 this->UserLabelPrefix = "";
3070 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3071 virtual void getTargetDefines(const LangOptions &Opts,
3072 MacroBuilder &Builder) const {
3073 X86_32TargetInfo::getTargetDefines(Opts, Builder);
3074 Builder.defineMacro("__INTEL__");
3075 Builder.defineMacro("__rtems__");
3076 }
3077 };
3078 } // end anonymous namespace
3079
3080 namespace {
3081 // x86-64 generic target
3082 class X86_64TargetInfo : public X86TargetInfo {
3083 public:
X86_64TargetInfo(const std::string & triple)3084 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
3085 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
3086 LongDoubleWidth = 128;
3087 LongDoubleAlign = 128;
3088 LargeArrayMinWidth = 128;
3089 LargeArrayAlign = 128;
3090 SuitableAlign = 128;
3091 IntMaxType = SignedLong;
3092 UIntMaxType = UnsignedLong;
3093 Int64Type = SignedLong;
3094 RegParmMax = 6;
3095
3096 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3097 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
3098 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128";
3099
3100 // Use fpret only for long double.
3101 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
3102
3103 // Use fp2ret for _Complex long double.
3104 ComplexLongDoubleUsesFP2Ret = true;
3105
3106 // x86-64 has atomics up to 16 bytes.
3107 // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128
3108 // on CPUs with cmpxchg16b
3109 MaxAtomicPromoteWidth = 128;
3110 MaxAtomicInlineWidth = 64;
3111 }
getBuiltinVaListKind() const3112 virtual BuiltinVaListKind getBuiltinVaListKind() const {
3113 return TargetInfo::X86_64ABIBuiltinVaList;
3114 }
3115
getEHDataRegisterNumber(unsigned RegNo) const3116 int getEHDataRegisterNumber(unsigned RegNo) const {
3117 if (RegNo == 0) return 0;
3118 if (RegNo == 1) return 1;
3119 return -1;
3120 }
3121
checkCallingConvention(CallingConv CC) const3122 virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
3123 return (CC == CC_Default ||
3124 CC == CC_C ||
3125 CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
3126 }
3127
getDefaultCallingConv(CallingConvMethodType MT) const3128 virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
3129 return CC_C;
3130 }
3131
3132 };
3133 } // end anonymous namespace
3134
3135 namespace {
3136 // x86-64 Windows target
3137 class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
3138 public:
WindowsX86_64TargetInfo(const std::string & triple)3139 WindowsX86_64TargetInfo(const std::string& triple)
3140 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
3141 TLSSupported = false;
3142 WCharType = UnsignedShort;
3143 LongWidth = LongAlign = 32;
3144 DoubleAlign = LongLongAlign = 64;
3145 IntMaxType = SignedLongLong;
3146 UIntMaxType = UnsignedLongLong;
3147 Int64Type = SignedLongLong;
3148 SizeType = UnsignedLongLong;
3149 PtrDiffType = SignedLongLong;
3150 IntPtrType = SignedLongLong;
3151 this->UserLabelPrefix = "";
3152 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3153 virtual void getTargetDefines(const LangOptions &Opts,
3154 MacroBuilder &Builder) const {
3155 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
3156 Builder.defineMacro("_WIN64");
3157 }
getBuiltinVaListKind() const3158 virtual BuiltinVaListKind getBuiltinVaListKind() const {
3159 return TargetInfo::CharPtrBuiltinVaList;
3160 }
3161 };
3162 } // end anonymous namespace
3163
3164 namespace {
3165 // x86-64 Windows Visual Studio target
3166 class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
3167 public:
VisualStudioWindowsX86_64TargetInfo(const std::string & triple)3168 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
3169 : WindowsX86_64TargetInfo(triple) {
3170 LongDoubleWidth = LongDoubleAlign = 64;
3171 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
3172 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3173 virtual void getTargetDefines(const LangOptions &Opts,
3174 MacroBuilder &Builder) const {
3175 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
3176 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
3177 Builder.defineMacro("_M_X64");
3178 Builder.defineMacro("_M_AMD64");
3179 }
3180 };
3181 } // end anonymous namespace
3182
3183 namespace {
3184 // x86-64 MinGW target
3185 class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
3186 public:
MinGWX86_64TargetInfo(const std::string & triple)3187 MinGWX86_64TargetInfo(const std::string& triple)
3188 : WindowsX86_64TargetInfo(triple) {
3189 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3190 virtual void getTargetDefines(const LangOptions &Opts,
3191 MacroBuilder &Builder) const {
3192 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
3193 DefineStd(Builder, "WIN64", Opts);
3194 Builder.defineMacro("__MSVCRT__");
3195 Builder.defineMacro("__MINGW32__");
3196 Builder.defineMacro("__MINGW64__");
3197
3198 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
3199 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
3200 if (Opts.MicrosoftExt)
3201 // Provide "as-is" __declspec.
3202 Builder.defineMacro("__declspec", "__declspec");
3203 else
3204 // Provide alias of __attribute__ like mingw32-gcc.
3205 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
3206 }
3207 };
3208 } // end anonymous namespace
3209
3210 namespace {
3211 class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
3212 public:
DarwinX86_64TargetInfo(const std::string & triple)3213 DarwinX86_64TargetInfo(const std::string& triple)
3214 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
3215 Int64Type = SignedLongLong;
3216 MaxVectorAlign = 256;
3217 }
3218 };
3219 } // end anonymous namespace
3220
3221 namespace {
3222 class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
3223 public:
OpenBSDX86_64TargetInfo(const std::string & triple)3224 OpenBSDX86_64TargetInfo(const std::string& triple)
3225 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
3226 IntMaxType = SignedLongLong;
3227 UIntMaxType = UnsignedLongLong;
3228 Int64Type = SignedLongLong;
3229 }
3230 };
3231 } // end anonymous namespace
3232
3233 namespace {
3234 class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
3235 public:
BitrigX86_64TargetInfo(const std::string & triple)3236 BitrigX86_64TargetInfo(const std::string& triple)
3237 : BitrigTargetInfo<X86_64TargetInfo>(triple) {
3238 IntMaxType = SignedLongLong;
3239 UIntMaxType = UnsignedLongLong;
3240 Int64Type = SignedLongLong;
3241 }
3242 };
3243 }
3244
3245 namespace {
3246 class AArch64TargetInfo : public TargetInfo {
3247 static const char * const GCCRegNames[];
3248 static const TargetInfo::GCCRegAlias GCCRegAliases[];
3249 public:
AArch64TargetInfo(const std::string & triple)3250 AArch64TargetInfo(const std::string& triple) : TargetInfo(triple) {
3251 BigEndian = false;
3252 LongWidth = LongAlign = 64;
3253 LongDoubleWidth = LongDoubleAlign = 128;
3254 PointerWidth = PointerAlign = 64;
3255 SuitableAlign = 128;
3256 DescriptionString = "e-p:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3257 "i64:64:64-i128:128:128-f32:32:32-f64:64:64-"
3258 "f128:128:128-n32:64-S128";
3259
3260 WCharType = UnsignedInt;
3261 LongDoubleFormat = &llvm::APFloat::IEEEquad;
3262
3263 // AArch64 backend supports 64-bit operations at the moment. In principle
3264 // 128-bit is possible if register-pairs are used.
3265 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
3266
3267 TheCXXABI.set(TargetCXXABI::GenericAArch64);
3268 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3269 virtual void getTargetDefines(const LangOptions &Opts,
3270 MacroBuilder &Builder) const {
3271 // GCC defines theses currently
3272 Builder.defineMacro("__aarch64__");
3273 Builder.defineMacro("__AARCH64EL__");
3274
3275 // ACLE predefines. Many can only have one possible value on v8 AArch64.
3276
3277 // FIXME: these were written based on an unreleased version of a 32-bit ACLE
3278 // which was intended to be compatible with a 64-bit implementation. They
3279 // will need updating when a real 64-bit ACLE exists. Particularly pressing
3280 // instances are: __AARCH_ISA_A32, __AARCH_ISA_T32, __ARCH_PCS.
3281 Builder.defineMacro("__AARCH_ACLE", "101");
3282 Builder.defineMacro("__AARCH", "8");
3283 Builder.defineMacro("__AARCH_PROFILE", "'A'");
3284
3285 Builder.defineMacro("__AARCH_FEATURE_UNALIGNED");
3286 Builder.defineMacro("__AARCH_FEATURE_CLZ");
3287 Builder.defineMacro("__AARCH_FEATURE_FMA");
3288
3289 // FIXME: ACLE 1.1 reserves bit 4. Will almost certainly come to mean
3290 // 128-bit LDXP present, at which point this becomes 0x1f.
3291 Builder.defineMacro("__AARCH_FEATURE_LDREX", "0xf");
3292
3293 // 0xe implies support for half, single and double precision operations.
3294 Builder.defineMacro("__AARCH_FP", "0xe");
3295
3296 // PCS specifies this for SysV variants, which is all we support. Other ABIs
3297 // may choose __AARCH_FP16_FORMAT_ALTERNATIVE.
3298 Builder.defineMacro("__AARCH_FP16_FORMAT_IEEE");
3299
3300 if (Opts.FastMath || Opts.FiniteMathOnly)
3301 Builder.defineMacro("__AARCH_FP_FAST");
3302
3303 if ((Opts.C99 || Opts.C11) && !Opts.Freestanding)
3304 Builder.defineMacro("__AARCH_FP_FENV_ROUNDING");
3305
3306 Builder.defineMacro("__AARCH_SIZEOF_WCHAR_T",
3307 Opts.ShortWChar ? "2" : "4");
3308
3309 Builder.defineMacro("__AARCH_SIZEOF_MINIMAL_ENUM",
3310 Opts.ShortEnums ? "1" : "4");
3311
3312 if (BigEndian)
3313 Builder.defineMacro("__AARCH_BIG_ENDIAN");
3314 }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const3315 virtual void getTargetBuiltins(const Builtin::Info *&Records,
3316 unsigned &NumRecords) const {
3317 Records = 0;
3318 NumRecords = 0;
3319 }
hasFeature(StringRef Feature) const3320 virtual bool hasFeature(StringRef Feature) const {
3321 return Feature == "aarch64";
3322 }
3323 virtual void getGCCRegNames(const char * const *&Names,
3324 unsigned &NumNames) const;
3325 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
3326 unsigned &NumAliases) const;
3327
isCLZForZeroUndef() const3328 virtual bool isCLZForZeroUndef() const { return false; }
3329
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const3330 virtual bool validateAsmConstraint(const char *&Name,
3331 TargetInfo::ConstraintInfo &Info) const {
3332 switch (*Name) {
3333 default: return false;
3334 case 'w': // An FP/SIMD vector register
3335 Info.setAllowsRegister();
3336 return true;
3337 case 'I': // Constant that can be used with an ADD instruction
3338 case 'J': // Constant that can be used with a SUB instruction
3339 case 'K': // Constant that can be used with a 32-bit logical instruction
3340 case 'L': // Constant that can be used with a 64-bit logical instruction
3341 case 'M': // Constant that can be used as a 32-bit MOV immediate
3342 case 'N': // Constant that can be used as a 64-bit MOV immediate
3343 case 'Y': // Floating point constant zero
3344 case 'Z': // Integer constant zero
3345 return true;
3346 case 'Q': // A memory reference with base register and no offset
3347 Info.setAllowsMemory();
3348 return true;
3349 case 'S': // A symbolic address
3350 Info.setAllowsRegister();
3351 return true;
3352 case 'U':
3353 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be
3354 // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be
3355 // Usa: An absolute symbolic address
3356 // Ush: The high part (bits 32:12) of a pc-relative symbolic address
3357 llvm_unreachable("FIXME: Unimplemented support for bizarre constraints");
3358 }
3359 }
3360
getClobbers() const3361 virtual const char *getClobbers() const {
3362 // There are no AArch64 clobbers shared by all asm statements.
3363 return "";
3364 }
3365
getBuiltinVaListKind() const3366 virtual BuiltinVaListKind getBuiltinVaListKind() const {
3367 return TargetInfo::AArch64ABIBuiltinVaList;
3368 }
3369 };
3370
3371 const char * const AArch64TargetInfo::GCCRegNames[] = {
3372 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
3373 "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
3374 "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
3375 "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", "wzr",
3376
3377 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
3378 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
3379 "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
3380 "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", "xzr",
3381
3382 "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
3383 "b8", "b9", "b10", "b11", "b12", "b13", "b14", "b15",
3384 "b16", "b17", "b18", "b19", "b20", "b21", "b22", "b23",
3385 "b24", "b25", "b26", "b27", "b28", "b29", "b30", "b31",
3386
3387 "h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7",
3388 "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15",
3389 "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
3390 "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31",
3391
3392 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
3393 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
3394 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
3395 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
3396
3397 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
3398 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
3399 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
3400 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
3401
3402 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
3403 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
3404 "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
3405 "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
3406 };
3407
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const3408 void AArch64TargetInfo::getGCCRegNames(const char * const *&Names,
3409 unsigned &NumNames) const {
3410 Names = GCCRegNames;
3411 NumNames = llvm::array_lengthof(GCCRegNames);
3412 }
3413
3414 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
3415 { { "x16" }, "ip0"},
3416 { { "x17" }, "ip1"},
3417 { { "x29" }, "fp" },
3418 { { "x30" }, "lr" }
3419 };
3420
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const3421 void AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
3422 unsigned &NumAliases) const {
3423 Aliases = GCCRegAliases;
3424 NumAliases = llvm::array_lengthof(GCCRegAliases);
3425
3426 }
3427 } // end anonymous namespace
3428
3429 namespace {
3430 class ARMTargetInfo : public TargetInfo {
3431 // Possible FPU choices.
3432 enum FPUMode {
3433 VFP2FPU = (1 << 0),
3434 VFP3FPU = (1 << 1),
3435 VFP4FPU = (1 << 2),
3436 NeonFPU = (1 << 3)
3437 };
3438
FPUModeIsVFP(FPUMode Mode)3439 static bool FPUModeIsVFP(FPUMode Mode) {
3440 return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU);
3441 }
3442
3443 static const TargetInfo::GCCRegAlias GCCRegAliases[];
3444 static const char * const GCCRegNames[];
3445
3446 std::string ABI, CPU;
3447
3448 unsigned FPU : 4;
3449
3450 unsigned IsAAPCS : 1;
3451 unsigned IsThumb : 1;
3452
3453 // Initialized via features.
3454 unsigned SoftFloat : 1;
3455 unsigned SoftFloatABI : 1;
3456
3457 static const Builtin::Info BuiltinInfo[];
3458
3459 public:
ARMTargetInfo(const std::string & TripleStr)3460 ARMTargetInfo(const std::string &TripleStr)
3461 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s"), IsAAPCS(true)
3462 {
3463 BigEndian = false;
3464 SizeType = UnsignedInt;
3465 PtrDiffType = SignedInt;
3466 // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
3467 WCharType = UnsignedInt;
3468
3469 // {} in inline assembly are neon specifiers, not assembly variant
3470 // specifiers.
3471 NoAsmVariants = true;
3472
3473 // FIXME: Should we just treat this as a feature?
3474 IsThumb = getTriple().getArchName().startswith("thumb");
3475 if (IsThumb) {
3476 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
3477 // so set preferred for small types to 32.
3478 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
3479 "i64:64:64-f32:32:32-f64:64:64-"
3480 "v64:64:64-v128:64:128-a0:0:32-n32-S64");
3481 } else {
3482 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3483 "i64:64:64-f32:32:32-f64:64:64-"
3484 "v64:64:64-v128:64:128-a0:0:64-n32-S64");
3485 }
3486
3487 // ARM targets default to using the ARM C++ ABI.
3488 TheCXXABI.set(TargetCXXABI::GenericARM);
3489
3490 // ARM has atomics up to 8 bytes
3491 // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e
3492 MaxAtomicPromoteWidth = 64;
3493
3494 // Do force alignment of members that follow zero length bitfields. If
3495 // the alignment of the zero-length bitfield is greater than the member
3496 // that follows it, `bar', `bar' will be aligned as the type of the
3497 // zero length bitfield.
3498 UseZeroLengthBitfieldAlignment = true;
3499 }
getABI() const3500 virtual const char *getABI() const { return ABI.c_str(); }
setABI(const std::string & Name)3501 virtual bool setABI(const std::string &Name) {
3502 ABI = Name;
3503
3504 // The defaults (above) are for AAPCS, check if we need to change them.
3505 //
3506 // FIXME: We need support for -meabi... we could just mangle it into the
3507 // name.
3508 if (Name == "apcs-gnu") {
3509 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
3510 // size_t is unsigned int on FreeBSD.
3511 if (getTriple().getOS() != llvm::Triple::FreeBSD)
3512 SizeType = UnsignedLong;
3513
3514 // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
3515 WCharType = SignedInt;
3516
3517 // Do not respect the alignment of bit-field types when laying out
3518 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
3519 UseBitFieldTypeAlignment = false;
3520
3521 /// gcc forces the alignment to 4 bytes, regardless of the type of the
3522 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
3523 /// gcc.
3524 ZeroLengthBitfieldBoundary = 32;
3525
3526 IsAAPCS = false;
3527
3528 if (IsThumb) {
3529 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
3530 // so set preferred for small types to 32.
3531 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
3532 "i64:32:64-f32:32:32-f64:32:64-"
3533 "v64:32:64-v128:32:128-a0:0:32-n32-S32");
3534 } else {
3535 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
3536 "i64:32:64-f32:32:32-f64:32:64-"
3537 "v64:32:64-v128:32:128-a0:0:32-n32-S32");
3538 }
3539
3540 // FIXME: Override "preferred align" for double and long long.
3541 } else if (Name == "aapcs" || Name == "aapcs-vfp") {
3542 IsAAPCS = true;
3543 // FIXME: Enumerated types are variable width in straight AAPCS.
3544 } else if (Name == "aapcs-linux") {
3545 IsAAPCS = true;
3546 } else
3547 return false;
3548
3549 return true;
3550 }
3551
getDefaultFeatures(llvm::StringMap<bool> & Features) const3552 void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
3553 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
3554 Features["vfp2"] = true;
3555 else if (CPU == "cortex-a8" || CPU == "cortex-a15" ||
3556 CPU == "cortex-a9" || CPU == "cortex-a9-mp")
3557 Features["neon"] = true;
3558 else if (CPU == "swift" || CPU == "cortex-a7") {
3559 Features["vfp4"] = true;
3560 Features["neon"] = true;
3561 }
3562 }
3563
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const3564 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
3565 StringRef Name,
3566 bool Enabled) const {
3567 if (Name == "soft-float" || Name == "soft-float-abi" ||
3568 Name == "vfp2" || Name == "vfp3" || Name == "vfp4" || Name == "neon" ||
3569 Name == "d16" || Name == "neonfp" || Name == "long64") {
3570 Features[Name] = Enabled;
3571 } else
3572 return false;
3573
3574 return true;
3575 }
3576
HandleTargetFeatures(std::vector<std::string> & Features)3577 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
3578 FPU = 0;
3579 SoftFloat = SoftFloatABI = false;
3580 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
3581 if (Features[i] == "+soft-float")
3582 SoftFloat = true;
3583 else if (Features[i] == "+soft-float-abi")
3584 SoftFloatABI = true;
3585 else if (Features[i] == "+vfp2")
3586 FPU |= VFP2FPU;
3587 else if (Features[i] == "+vfp3")
3588 FPU |= VFP3FPU;
3589 else if (Features[i] == "+vfp4")
3590 FPU |= VFP4FPU;
3591 else if (Features[i] == "+neon")
3592 FPU |= NeonFPU;
3593 else if (Features[i] == "+long64")
3594 LongWidth = LongAlign = 64; // RenderScript uses a 64-bit long type
3595 }
3596
3597 // Remove front-end specific options which the backend handles differently.
3598 std::vector<std::string>::iterator it;
3599 it = std::find(Features.begin(), Features.end(), "+soft-float");
3600 if (it != Features.end())
3601 Features.erase(it);
3602 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
3603 if (it != Features.end())
3604 Features.erase(it);
3605 }
3606
hasFeature(StringRef Feature) const3607 virtual bool hasFeature(StringRef Feature) const {
3608 return llvm::StringSwitch<bool>(Feature)
3609 .Case("arm", true)
3610 .Case("softfloat", SoftFloat)
3611 .Case("thumb", IsThumb)
3612 .Case("neon", FPU == NeonFPU && !SoftFloat &&
3613 StringRef(getCPUDefineSuffix(CPU)).startswith("7"))
3614 .Default(false);
3615 }
3616 // FIXME: Should we actually have some table instead of these switches?
getCPUDefineSuffix(StringRef Name)3617 static const char *getCPUDefineSuffix(StringRef Name) {
3618 return llvm::StringSwitch<const char*>(Name)
3619 .Cases("arm8", "arm810", "4")
3620 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
3621 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
3622 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
3623 .Case("ep9312", "4T")
3624 .Cases("arm10tdmi", "arm1020t", "5T")
3625 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
3626 .Case("arm926ej-s", "5TEJ")
3627 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
3628 .Cases("xscale", "iwmmxt", "5TE")
3629 .Case("arm1136j-s", "6J")
3630 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
3631 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
3632 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
3633 .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
3634 .Cases("cortex-a9", "cortex-a15", "7A")
3635 .Case("cortex-r5", "7R")
3636 .Case("cortex-a9-mp", "7F")
3637 .Case("swift", "7S")
3638 .Cases("cortex-m3", "cortex-m4", "7M")
3639 .Case("cortex-m0", "6M")
3640 .Default(0);
3641 }
getCPUProfile(StringRef Name)3642 static const char *getCPUProfile(StringRef Name) {
3643 return llvm::StringSwitch<const char*>(Name)
3644 .Cases("cortex-a8", "cortex-a9", "A")
3645 .Cases("cortex-m3", "cortex-m4", "cortex-m0", "M")
3646 .Case("cortex-r5", "R")
3647 .Default("");
3648 }
setCPU(const std::string & Name)3649 virtual bool setCPU(const std::string &Name) {
3650 if (!getCPUDefineSuffix(Name))
3651 return false;
3652
3653 CPU = Name;
3654 return true;
3655 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3656 virtual void getTargetDefines(const LangOptions &Opts,
3657 MacroBuilder &Builder) const {
3658 // Target identification.
3659 Builder.defineMacro("__arm");
3660 Builder.defineMacro("__arm__");
3661
3662 // Target properties.
3663 Builder.defineMacro("__ARMEL__");
3664 Builder.defineMacro("__LITTLE_ENDIAN__");
3665 Builder.defineMacro("__REGISTER_PREFIX__", "");
3666
3667 StringRef CPUArch = getCPUDefineSuffix(CPU);
3668 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
3669 Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
3670 StringRef CPUProfile = getCPUProfile(CPU);
3671 if (!CPUProfile.empty())
3672 Builder.defineMacro("__ARM_ARCH_PROFILE", CPUProfile);
3673
3674 // Subtarget options.
3675
3676 // FIXME: It's more complicated than this and we don't really support
3677 // interworking.
3678 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
3679 Builder.defineMacro("__THUMB_INTERWORK__");
3680
3681 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
3682 // M-class CPUs on Darwin follow AAPCS, but not EABI.
3683 if (!(getTriple().isOSDarwin() && CPUProfile == "M"))
3684 Builder.defineMacro("__ARM_EABI__");
3685 Builder.defineMacro("__ARM_PCS", "1");
3686
3687 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp")
3688 Builder.defineMacro("__ARM_PCS_VFP", "1");
3689 }
3690
3691 if (SoftFloat)
3692 Builder.defineMacro("__SOFTFP__");
3693
3694 if (CPU == "xscale")
3695 Builder.defineMacro("__XSCALE__");
3696
3697 bool IsARMv7 = CPUArch.startswith("7");
3698 if (IsThumb) {
3699 Builder.defineMacro("__THUMBEL__");
3700 Builder.defineMacro("__thumb__");
3701 if (CPUArch == "6T2" || IsARMv7)
3702 Builder.defineMacro("__thumb2__");
3703 }
3704
3705 // Note, this is always on in gcc, even though it doesn't make sense.
3706 Builder.defineMacro("__APCS_32__");
3707
3708 if (FPUModeIsVFP((FPUMode) FPU)) {
3709 Builder.defineMacro("__VFP_FP__");
3710 if (FPU & VFP2FPU)
3711 Builder.defineMacro("__ARM_VFPV2__");
3712 if (FPU & VFP3FPU)
3713 Builder.defineMacro("__ARM_VFPV3__");
3714 if (FPU & VFP4FPU)
3715 Builder.defineMacro("__ARM_VFPV4__");
3716 }
3717
3718 // This only gets set when Neon instructions are actually available, unlike
3719 // the VFP define, hence the soft float and arch check. This is subtly
3720 // different from gcc, we follow the intent which was that it should be set
3721 // when Neon instructions are actually available.
3722 if ((FPU & NeonFPU) && !SoftFloat && IsARMv7)
3723 Builder.defineMacro("__ARM_NEON__");
3724 }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const3725 virtual void getTargetBuiltins(const Builtin::Info *&Records,
3726 unsigned &NumRecords) const {
3727 Records = BuiltinInfo;
3728 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
3729 }
isCLZForZeroUndef() const3730 virtual bool isCLZForZeroUndef() const { return false; }
getBuiltinVaListKind() const3731 virtual BuiltinVaListKind getBuiltinVaListKind() const {
3732 return IsAAPCS ? AAPCSABIBuiltinVaList : TargetInfo::VoidPtrBuiltinVaList;
3733 }
3734 virtual void getGCCRegNames(const char * const *&Names,
3735 unsigned &NumNames) const;
3736 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
3737 unsigned &NumAliases) const;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const3738 virtual bool validateAsmConstraint(const char *&Name,
3739 TargetInfo::ConstraintInfo &Info) const {
3740 switch (*Name) {
3741 default: break;
3742 case 'l': // r0-r7
3743 case 'h': // r8-r15
3744 case 'w': // VFP Floating point register single precision
3745 case 'P': // VFP Floating point register double precision
3746 Info.setAllowsRegister();
3747 return true;
3748 case 'Q': // A memory address that is a single base register.
3749 Info.setAllowsMemory();
3750 return true;
3751 case 'U': // a memory reference...
3752 switch (Name[1]) {
3753 case 'q': // ...ARMV4 ldrsb
3754 case 'v': // ...VFP load/store (reg+constant offset)
3755 case 'y': // ...iWMMXt load/store
3756 case 't': // address valid for load/store opaque types wider
3757 // than 128-bits
3758 case 'n': // valid address for Neon doubleword vector load/store
3759 case 'm': // valid address for Neon element and structure load/store
3760 case 's': // valid address for non-offset loads/stores of quad-word
3761 // values in four ARM registers
3762 Info.setAllowsMemory();
3763 Name++;
3764 return true;
3765 }
3766 }
3767 return false;
3768 }
convertConstraint(const char * & Constraint) const3769 virtual std::string convertConstraint(const char *&Constraint) const {
3770 std::string R;
3771 switch (*Constraint) {
3772 case 'U': // Two-character constraint; add "^" hint for later parsing.
3773 R = std::string("^") + std::string(Constraint, 2);
3774 Constraint++;
3775 break;
3776 case 'p': // 'p' should be translated to 'r' by default.
3777 R = std::string("r");
3778 break;
3779 default:
3780 return std::string(1, *Constraint);
3781 }
3782 return R;
3783 }
validateConstraintModifier(StringRef Constraint,const char Modifier,unsigned Size) const3784 virtual bool validateConstraintModifier(StringRef Constraint,
3785 const char Modifier,
3786 unsigned Size) const {
3787 bool isOutput = (Constraint[0] == '=');
3788 bool isInOut = (Constraint[0] == '+');
3789
3790 // Strip off constraint modifiers.
3791 while (Constraint[0] == '=' ||
3792 Constraint[0] == '+' ||
3793 Constraint[0] == '&')
3794 Constraint = Constraint.substr(1);
3795
3796 switch (Constraint[0]) {
3797 default: break;
3798 case 'r': {
3799 switch (Modifier) {
3800 default:
3801 return isInOut || (isOutput && Size >= 32) ||
3802 (!isOutput && !isInOut && Size <= 32);
3803 case 'q':
3804 // A register of size 32 cannot fit a vector type.
3805 return false;
3806 }
3807 }
3808 }
3809
3810 return true;
3811 }
getClobbers() const3812 virtual const char *getClobbers() const {
3813 // FIXME: Is this really right?
3814 return "";
3815 }
3816
checkCallingConvention(CallingConv CC) const3817 virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
3818 return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning;
3819 }
3820
getEHDataRegisterNumber(unsigned RegNo) const3821 virtual int getEHDataRegisterNumber(unsigned RegNo) const {
3822 if (RegNo == 0) return 0;
3823 if (RegNo == 1) return 1;
3824 return -1;
3825 }
3826 };
3827
3828 const char * const ARMTargetInfo::GCCRegNames[] = {
3829 // Integer registers
3830 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3831 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
3832
3833 // Float registers
3834 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
3835 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
3836 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
3837 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
3838
3839 // Double registers
3840 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
3841 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
3842 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
3843 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
3844
3845 // Quad registers
3846 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
3847 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
3848 };
3849
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const3850 void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
3851 unsigned &NumNames) const {
3852 Names = GCCRegNames;
3853 NumNames = llvm::array_lengthof(GCCRegNames);
3854 }
3855
3856 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
3857 { { "a1" }, "r0" },
3858 { { "a2" }, "r1" },
3859 { { "a3" }, "r2" },
3860 { { "a4" }, "r3" },
3861 { { "v1" }, "r4" },
3862 { { "v2" }, "r5" },
3863 { { "v3" }, "r6" },
3864 { { "v4" }, "r7" },
3865 { { "v5" }, "r8" },
3866 { { "v6", "rfp" }, "r9" },
3867 { { "sl" }, "r10" },
3868 { { "fp" }, "r11" },
3869 { { "ip" }, "r12" },
3870 { { "r13" }, "sp" },
3871 { { "r14" }, "lr" },
3872 { { "r15" }, "pc" },
3873 // The S, D and Q registers overlap, but aren't really aliases; we
3874 // don't want to substitute one of these for a different-sized one.
3875 };
3876
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const3877 void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
3878 unsigned &NumAliases) const {
3879 Aliases = GCCRegAliases;
3880 NumAliases = llvm::array_lengthof(GCCRegAliases);
3881 }
3882
3883 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
3884 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
3885 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
3886 ALL_LANGUAGES },
3887 #include "clang/Basic/BuiltinsARM.def"
3888 };
3889 } // end anonymous namespace.
3890
3891 namespace {
3892 class DarwinARMTargetInfo :
3893 public DarwinTargetInfo<ARMTargetInfo> {
3894 protected:
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const3895 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
3896 MacroBuilder &Builder) const {
3897 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
3898 }
3899
3900 public:
DarwinARMTargetInfo(const std::string & triple)3901 DarwinARMTargetInfo(const std::string& triple)
3902 : DarwinTargetInfo<ARMTargetInfo>(triple) {
3903 HasAlignMac68kSupport = true;
3904 // iOS always has 64-bit atomic instructions.
3905 // FIXME: This should be based off of the target features in ARMTargetInfo.
3906 MaxAtomicInlineWidth = 64;
3907
3908 // Darwin on iOS uses a variant of the ARM C++ ABI.
3909 TheCXXABI.set(TargetCXXABI::iOS);
3910 }
3911 };
3912 } // end anonymous namespace.
3913
3914
3915 namespace {
3916 // Hexagon abstract base class
3917 class HexagonTargetInfo : public TargetInfo {
3918 static const Builtin::Info BuiltinInfo[];
3919 static const char * const GCCRegNames[];
3920 static const TargetInfo::GCCRegAlias GCCRegAliases[];
3921 std::string CPU;
3922 public:
HexagonTargetInfo(const std::string & triple)3923 HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) {
3924 BigEndian = false;
3925 DescriptionString = ("e-p:32:32:32-"
3926 "i64:64:64-i32:32:32-i16:16:16-i1:32:32-"
3927 "f64:64:64-f32:32:32-a0:0-n32");
3928
3929 // {} in inline assembly are packet specifiers, not assembly variant
3930 // specifiers.
3931 NoAsmVariants = true;
3932 }
3933
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const3934 virtual void getTargetBuiltins(const Builtin::Info *&Records,
3935 unsigned &NumRecords) const {
3936 Records = BuiltinInfo;
3937 NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin;
3938 }
3939
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const3940 virtual bool validateAsmConstraint(const char *&Name,
3941 TargetInfo::ConstraintInfo &Info) const {
3942 return true;
3943 }
3944
3945 virtual void getTargetDefines(const LangOptions &Opts,
3946 MacroBuilder &Builder) const;
3947
hasFeature(StringRef Feature) const3948 virtual bool hasFeature(StringRef Feature) const {
3949 return Feature == "hexagon";
3950 }
3951
getBuiltinVaListKind() const3952 virtual BuiltinVaListKind getBuiltinVaListKind() const {
3953 return TargetInfo::CharPtrBuiltinVaList;
3954 }
3955 virtual void getGCCRegNames(const char * const *&Names,
3956 unsigned &NumNames) const;
3957 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
3958 unsigned &NumAliases) const;
getClobbers() const3959 virtual const char *getClobbers() const {
3960 return "";
3961 }
3962
getHexagonCPUSuffix(StringRef Name)3963 static const char *getHexagonCPUSuffix(StringRef Name) {
3964 return llvm::StringSwitch<const char*>(Name)
3965 .Case("hexagonv4", "4")
3966 .Case("hexagonv5", "5")
3967 .Default(0);
3968 }
3969
setCPU(const std::string & Name)3970 virtual bool setCPU(const std::string &Name) {
3971 if (!getHexagonCPUSuffix(Name))
3972 return false;
3973
3974 CPU = Name;
3975 return true;
3976 }
3977 };
3978
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3979 void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
3980 MacroBuilder &Builder) const {
3981 Builder.defineMacro("qdsp6");
3982 Builder.defineMacro("__qdsp6", "1");
3983 Builder.defineMacro("__qdsp6__", "1");
3984
3985 Builder.defineMacro("hexagon");
3986 Builder.defineMacro("__hexagon", "1");
3987 Builder.defineMacro("__hexagon__", "1");
3988
3989 if(CPU == "hexagonv1") {
3990 Builder.defineMacro("__HEXAGON_V1__");
3991 Builder.defineMacro("__HEXAGON_ARCH__", "1");
3992 if(Opts.HexagonQdsp6Compat) {
3993 Builder.defineMacro("__QDSP6_V1__");
3994 Builder.defineMacro("__QDSP6_ARCH__", "1");
3995 }
3996 }
3997 else if(CPU == "hexagonv2") {
3998 Builder.defineMacro("__HEXAGON_V2__");
3999 Builder.defineMacro("__HEXAGON_ARCH__", "2");
4000 if(Opts.HexagonQdsp6Compat) {
4001 Builder.defineMacro("__QDSP6_V2__");
4002 Builder.defineMacro("__QDSP6_ARCH__", "2");
4003 }
4004 }
4005 else if(CPU == "hexagonv3") {
4006 Builder.defineMacro("__HEXAGON_V3__");
4007 Builder.defineMacro("__HEXAGON_ARCH__", "3");
4008 if(Opts.HexagonQdsp6Compat) {
4009 Builder.defineMacro("__QDSP6_V3__");
4010 Builder.defineMacro("__QDSP6_ARCH__", "3");
4011 }
4012 }
4013 else if(CPU == "hexagonv4") {
4014 Builder.defineMacro("__HEXAGON_V4__");
4015 Builder.defineMacro("__HEXAGON_ARCH__", "4");
4016 if(Opts.HexagonQdsp6Compat) {
4017 Builder.defineMacro("__QDSP6_V4__");
4018 Builder.defineMacro("__QDSP6_ARCH__", "4");
4019 }
4020 }
4021 else if(CPU == "hexagonv5") {
4022 Builder.defineMacro("__HEXAGON_V5__");
4023 Builder.defineMacro("__HEXAGON_ARCH__", "5");
4024 if(Opts.HexagonQdsp6Compat) {
4025 Builder.defineMacro("__QDSP6_V5__");
4026 Builder.defineMacro("__QDSP6_ARCH__", "5");
4027 }
4028 }
4029 }
4030
4031 const char * const HexagonTargetInfo::GCCRegNames[] = {
4032 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
4033 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
4034 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
4035 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
4036 "p0", "p1", "p2", "p3",
4037 "sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
4038 };
4039
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4040 void HexagonTargetInfo::getGCCRegNames(const char * const *&Names,
4041 unsigned &NumNames) const {
4042 Names = GCCRegNames;
4043 NumNames = llvm::array_lengthof(GCCRegNames);
4044 }
4045
4046
4047 const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
4048 { { "sp" }, "r29" },
4049 { { "fp" }, "r30" },
4050 { { "lr" }, "r31" },
4051 };
4052
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4053 void HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
4054 unsigned &NumAliases) const {
4055 Aliases = GCCRegAliases;
4056 NumAliases = llvm::array_lengthof(GCCRegAliases);
4057 }
4058
4059
4060 const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
4061 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4062 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
4063 ALL_LANGUAGES },
4064 #include "clang/Basic/BuiltinsHexagon.def"
4065 };
4066 }
4067
4068
4069 namespace {
4070 class SparcV8TargetInfo : public TargetInfo {
4071 static const TargetInfo::GCCRegAlias GCCRegAliases[];
4072 static const char * const GCCRegNames[];
4073 bool SoftFloat;
4074 public:
SparcV8TargetInfo(const std::string & triple)4075 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
4076 // FIXME: Support Sparc quad-precision long double?
4077 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
4078 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
4079 }
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const4080 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
4081 StringRef Name,
4082 bool Enabled) const {
4083 if (Name == "soft-float")
4084 Features[Name] = Enabled;
4085 else
4086 return false;
4087
4088 return true;
4089 }
HandleTargetFeatures(std::vector<std::string> & Features)4090 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
4091 SoftFloat = false;
4092 for (unsigned i = 0, e = Features.size(); i != e; ++i)
4093 if (Features[i] == "+soft-float")
4094 SoftFloat = true;
4095 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4096 virtual void getTargetDefines(const LangOptions &Opts,
4097 MacroBuilder &Builder) const {
4098 DefineStd(Builder, "sparc", Opts);
4099 Builder.defineMacro("__sparcv8");
4100 Builder.defineMacro("__REGISTER_PREFIX__", "");
4101
4102 if (SoftFloat)
4103 Builder.defineMacro("SOFT_FLOAT", "1");
4104 }
4105
hasFeature(StringRef Feature) const4106 virtual bool hasFeature(StringRef Feature) const {
4107 return llvm::StringSwitch<bool>(Feature)
4108 .Case("softfloat", SoftFloat)
4109 .Case("sparc", true)
4110 .Default(false);
4111 }
4112
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4113 virtual void getTargetBuiltins(const Builtin::Info *&Records,
4114 unsigned &NumRecords) const {
4115 // FIXME: Implement!
4116 }
getBuiltinVaListKind() const4117 virtual BuiltinVaListKind getBuiltinVaListKind() const {
4118 return TargetInfo::VoidPtrBuiltinVaList;
4119 }
4120 virtual void getGCCRegNames(const char * const *&Names,
4121 unsigned &NumNames) const;
4122 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4123 unsigned &NumAliases) const;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const4124 virtual bool validateAsmConstraint(const char *&Name,
4125 TargetInfo::ConstraintInfo &info) const {
4126 // FIXME: Implement!
4127 return false;
4128 }
getClobbers() const4129 virtual const char *getClobbers() const {
4130 // FIXME: Implement!
4131 return "";
4132 }
4133 };
4134
4135 const char * const SparcV8TargetInfo::GCCRegNames[] = {
4136 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
4137 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
4138 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
4139 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
4140 };
4141
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4142 void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
4143 unsigned &NumNames) const {
4144 Names = GCCRegNames;
4145 NumNames = llvm::array_lengthof(GCCRegNames);
4146 }
4147
4148 const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
4149 { { "g0" }, "r0" },
4150 { { "g1" }, "r1" },
4151 { { "g2" }, "r2" },
4152 { { "g3" }, "r3" },
4153 { { "g4" }, "r4" },
4154 { { "g5" }, "r5" },
4155 { { "g6" }, "r6" },
4156 { { "g7" }, "r7" },
4157 { { "o0" }, "r8" },
4158 { { "o1" }, "r9" },
4159 { { "o2" }, "r10" },
4160 { { "o3" }, "r11" },
4161 { { "o4" }, "r12" },
4162 { { "o5" }, "r13" },
4163 { { "o6", "sp" }, "r14" },
4164 { { "o7" }, "r15" },
4165 { { "l0" }, "r16" },
4166 { { "l1" }, "r17" },
4167 { { "l2" }, "r18" },
4168 { { "l3" }, "r19" },
4169 { { "l4" }, "r20" },
4170 { { "l5" }, "r21" },
4171 { { "l6" }, "r22" },
4172 { { "l7" }, "r23" },
4173 { { "i0" }, "r24" },
4174 { { "i1" }, "r25" },
4175 { { "i2" }, "r26" },
4176 { { "i3" }, "r27" },
4177 { { "i4" }, "r28" },
4178 { { "i5" }, "r29" },
4179 { { "i6", "fp" }, "r30" },
4180 { { "i7" }, "r31" },
4181 };
4182
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4183 void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
4184 unsigned &NumAliases) const {
4185 Aliases = GCCRegAliases;
4186 NumAliases = llvm::array_lengthof(GCCRegAliases);
4187 }
4188 } // end anonymous namespace.
4189
4190 namespace {
4191 class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
4192 public:
AuroraUXSparcV8TargetInfo(const std::string & triple)4193 AuroraUXSparcV8TargetInfo(const std::string& triple) :
4194 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
4195 SizeType = UnsignedInt;
4196 PtrDiffType = SignedInt;
4197 }
4198 };
4199 class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
4200 public:
SolarisSparcV8TargetInfo(const std::string & triple)4201 SolarisSparcV8TargetInfo(const std::string& triple) :
4202 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
4203 SizeType = UnsignedInt;
4204 PtrDiffType = SignedInt;
4205 }
4206 };
4207 } // end anonymous namespace.
4208
4209 namespace {
4210 class MSP430TargetInfo : public TargetInfo {
4211 static const char * const GCCRegNames[];
4212 public:
MSP430TargetInfo(const std::string & triple)4213 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
4214 BigEndian = false;
4215 TLSSupported = false;
4216 IntWidth = 16; IntAlign = 16;
4217 LongWidth = 32; LongLongWidth = 64;
4218 LongAlign = LongLongAlign = 16;
4219 PointerWidth = 16; PointerAlign = 16;
4220 SuitableAlign = 16;
4221 SizeType = UnsignedInt;
4222 IntMaxType = SignedLong;
4223 UIntMaxType = UnsignedLong;
4224 IntPtrType = SignedShort;
4225 PtrDiffType = SignedInt;
4226 SigAtomicType = SignedLong;
4227 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
4228 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4229 virtual void getTargetDefines(const LangOptions &Opts,
4230 MacroBuilder &Builder) const {
4231 Builder.defineMacro("MSP430");
4232 Builder.defineMacro("__MSP430__");
4233 // FIXME: defines for different 'flavours' of MCU
4234 }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4235 virtual void getTargetBuiltins(const Builtin::Info *&Records,
4236 unsigned &NumRecords) const {
4237 // FIXME: Implement.
4238 Records = 0;
4239 NumRecords = 0;
4240 }
hasFeature(StringRef Feature) const4241 virtual bool hasFeature(StringRef Feature) const {
4242 return Feature == "msp430";
4243 }
4244 virtual void getGCCRegNames(const char * const *&Names,
4245 unsigned &NumNames) const;
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4246 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4247 unsigned &NumAliases) const {
4248 // No aliases.
4249 Aliases = 0;
4250 NumAliases = 0;
4251 }
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const4252 virtual bool validateAsmConstraint(const char *&Name,
4253 TargetInfo::ConstraintInfo &info) const {
4254 // No target constraints for now.
4255 return false;
4256 }
getClobbers() const4257 virtual const char *getClobbers() const {
4258 // FIXME: Is this really right?
4259 return "";
4260 }
getBuiltinVaListKind() const4261 virtual BuiltinVaListKind getBuiltinVaListKind() const {
4262 // FIXME: implement
4263 return TargetInfo::CharPtrBuiltinVaList;
4264 }
4265 };
4266
4267 const char * const MSP430TargetInfo::GCCRegNames[] = {
4268 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
4269 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
4270 };
4271
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4272 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
4273 unsigned &NumNames) const {
4274 Names = GCCRegNames;
4275 NumNames = llvm::array_lengthof(GCCRegNames);
4276 }
4277 }
4278
4279 namespace {
4280
4281 // LLVM and Clang cannot be used directly to output native binaries for
4282 // target, but is used to compile C code to llvm bitcode with correct
4283 // type and alignment information.
4284 //
4285 // TCE uses the llvm bitcode as input and uses it for generating customized
4286 // target processor and program binary. TCE co-design environment is
4287 // publicly available in http://tce.cs.tut.fi
4288
4289 static const unsigned TCEOpenCLAddrSpaceMap[] = {
4290 3, // opencl_global
4291 4, // opencl_local
4292 5, // opencl_constant
4293 0, // cuda_device
4294 0, // cuda_constant
4295 0 // cuda_shared
4296 };
4297
4298 class TCETargetInfo : public TargetInfo{
4299 public:
TCETargetInfo(const std::string & triple)4300 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
4301 TLSSupported = false;
4302 IntWidth = 32;
4303 LongWidth = LongLongWidth = 32;
4304 PointerWidth = 32;
4305 IntAlign = 32;
4306 LongAlign = LongLongAlign = 32;
4307 PointerAlign = 32;
4308 SuitableAlign = 32;
4309 SizeType = UnsignedInt;
4310 IntMaxType = SignedLong;
4311 UIntMaxType = UnsignedLong;
4312 IntPtrType = SignedInt;
4313 PtrDiffType = SignedInt;
4314 FloatWidth = 32;
4315 FloatAlign = 32;
4316 DoubleWidth = 32;
4317 DoubleAlign = 32;
4318 LongDoubleWidth = 32;
4319 LongDoubleAlign = 32;
4320 FloatFormat = &llvm::APFloat::IEEEsingle;
4321 DoubleFormat = &llvm::APFloat::IEEEsingle;
4322 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
4323 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
4324 "i16:16:32-i32:32:32-i64:32:32-"
4325 "f32:32:32-f64:32:32-v64:32:32-"
4326 "v128:32:32-a0:0:32-n32";
4327 AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
4328 }
4329
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4330 virtual void getTargetDefines(const LangOptions &Opts,
4331 MacroBuilder &Builder) const {
4332 DefineStd(Builder, "tce", Opts);
4333 Builder.defineMacro("__TCE__");
4334 Builder.defineMacro("__TCE_V1__");
4335 }
hasFeature(StringRef Feature) const4336 virtual bool hasFeature(StringRef Feature) const {
4337 return Feature == "tce";
4338 }
4339
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4340 virtual void getTargetBuiltins(const Builtin::Info *&Records,
4341 unsigned &NumRecords) const {}
getClobbers() const4342 virtual const char *getClobbers() const {
4343 return "";
4344 }
getBuiltinVaListKind() const4345 virtual BuiltinVaListKind getBuiltinVaListKind() const {
4346 return TargetInfo::VoidPtrBuiltinVaList;
4347 }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4348 virtual void getGCCRegNames(const char * const *&Names,
4349 unsigned &NumNames) const {}
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const4350 virtual bool validateAsmConstraint(const char *&Name,
4351 TargetInfo::ConstraintInfo &info) const {
4352 return true;
4353 }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4354 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4355 unsigned &NumAliases) const {}
4356 };
4357 }
4358
4359 namespace {
4360 class MipsTargetInfoBase : public TargetInfo {
4361 static const Builtin::Info BuiltinInfo[];
4362 std::string CPU;
4363 bool IsMips16;
4364 enum MipsFloatABI {
4365 HardFloat, SingleFloat, SoftFloat
4366 } FloatABI;
4367 enum DspRevEnum {
4368 NoDSP, DSP1, DSP2
4369 } DspRev;
4370
4371 protected:
4372 std::string ABI;
4373
4374 public:
MipsTargetInfoBase(const std::string & triple,const std::string & ABIStr,const std::string & CPUStr)4375 MipsTargetInfoBase(const std::string& triple,
4376 const std::string& ABIStr,
4377 const std::string& CPUStr)
4378 : TargetInfo(triple),
4379 CPU(CPUStr),
4380 IsMips16(false),
4381 FloatABI(HardFloat),
4382 DspRev(NoDSP),
4383 ABI(ABIStr)
4384 {}
4385
getABI() const4386 virtual const char *getABI() const { return ABI.c_str(); }
4387 virtual bool setABI(const std::string &Name) = 0;
setCPU(const std::string & Name)4388 virtual bool setCPU(const std::string &Name) {
4389 CPU = Name;
4390 return true;
4391 }
getDefaultFeatures(llvm::StringMap<bool> & Features) const4392 void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
4393 Features[ABI] = true;
4394 Features[CPU] = true;
4395 }
4396
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4397 virtual void getTargetDefines(const LangOptions &Opts,
4398 MacroBuilder &Builder) const {
4399 DefineStd(Builder, "mips", Opts);
4400 Builder.defineMacro("_mips");
4401 Builder.defineMacro("__REGISTER_PREFIX__", "");
4402
4403 switch (FloatABI) {
4404 case HardFloat:
4405 Builder.defineMacro("__mips_hard_float", Twine(1));
4406 break;
4407 case SingleFloat:
4408 Builder.defineMacro("__mips_hard_float", Twine(1));
4409 Builder.defineMacro("__mips_single_float", Twine(1));
4410 break;
4411 case SoftFloat:
4412 Builder.defineMacro("__mips_soft_float", Twine(1));
4413 break;
4414 }
4415
4416 if (IsMips16)
4417 Builder.defineMacro("__mips16", Twine(1));
4418
4419 switch (DspRev) {
4420 default:
4421 break;
4422 case DSP1:
4423 Builder.defineMacro("__mips_dsp_rev", Twine(1));
4424 Builder.defineMacro("__mips_dsp", Twine(1));
4425 break;
4426 case DSP2:
4427 Builder.defineMacro("__mips_dsp_rev", Twine(2));
4428 Builder.defineMacro("__mips_dspr2", Twine(1));
4429 Builder.defineMacro("__mips_dsp", Twine(1));
4430 break;
4431 }
4432
4433 Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
4434 Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
4435 Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
4436
4437 Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
4438 Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
4439 }
4440
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4441 virtual void getTargetBuiltins(const Builtin::Info *&Records,
4442 unsigned &NumRecords) const {
4443 Records = BuiltinInfo;
4444 NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
4445 }
hasFeature(StringRef Feature) const4446 virtual bool hasFeature(StringRef Feature) const {
4447 return Feature == "mips";
4448 }
getBuiltinVaListKind() const4449 virtual BuiltinVaListKind getBuiltinVaListKind() const {
4450 return TargetInfo::VoidPtrBuiltinVaList;
4451 }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4452 virtual void getGCCRegNames(const char * const *&Names,
4453 unsigned &NumNames) const {
4454 static const char * const GCCRegNames[] = {
4455 // CPU register names
4456 // Must match second column of GCCRegAliases
4457 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
4458 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
4459 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
4460 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
4461 // Floating point register names
4462 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
4463 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
4464 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
4465 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
4466 // Hi/lo and condition register names
4467 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
4468 "$fcc5","$fcc6","$fcc7"
4469 };
4470 Names = GCCRegNames;
4471 NumNames = llvm::array_lengthof(GCCRegNames);
4472 }
4473 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4474 unsigned &NumAliases) const = 0;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const4475 virtual bool validateAsmConstraint(const char *&Name,
4476 TargetInfo::ConstraintInfo &Info) const {
4477 switch (*Name) {
4478 default:
4479 return false;
4480
4481 case 'r': // CPU registers.
4482 case 'd': // Equivalent to "r" unless generating MIPS16 code.
4483 case 'y': // Equivalent to "r", backwards compatibility only.
4484 case 'f': // floating-point registers.
4485 case 'c': // $25 for indirect jumps
4486 case 'l': // lo register
4487 case 'x': // hilo register pair
4488 Info.setAllowsRegister();
4489 return true;
4490 case 'R': // An address that can be used in a non-macro load or store
4491 Info.setAllowsMemory();
4492 return true;
4493 }
4494 }
4495
getClobbers() const4496 virtual const char *getClobbers() const {
4497 // FIXME: Implement!
4498 return "";
4499 }
4500
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const4501 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
4502 StringRef Name,
4503 bool Enabled) const {
4504 if (Name == "soft-float" || Name == "single-float" ||
4505 Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" ||
4506 Name == "mips32" || Name == "mips32r2" ||
4507 Name == "mips64" || Name == "mips64r2" ||
4508 Name == "mips16" || Name == "dsp" || Name == "dspr2") {
4509 Features[Name] = Enabled;
4510 return true;
4511 } else if (Name == "32") {
4512 Features["o32"] = Enabled;
4513 return true;
4514 } else if (Name == "64") {
4515 Features["n64"] = Enabled;
4516 return true;
4517 }
4518 return false;
4519 }
4520
HandleTargetFeatures(std::vector<std::string> & Features)4521 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
4522 IsMips16 = false;
4523 FloatABI = HardFloat;
4524 DspRev = NoDSP;
4525
4526 for (std::vector<std::string>::iterator it = Features.begin(),
4527 ie = Features.end(); it != ie; ++it) {
4528 if (*it == "+single-float")
4529 FloatABI = SingleFloat;
4530 else if (*it == "+soft-float")
4531 FloatABI = SoftFloat;
4532 else if (*it == "+mips16")
4533 IsMips16 = true;
4534 else if (*it == "+dsp")
4535 DspRev = std::max(DspRev, DSP1);
4536 else if (*it == "+dspr2")
4537 DspRev = std::max(DspRev, DSP2);
4538 }
4539
4540 // Remove front-end specific option.
4541 std::vector<std::string>::iterator it =
4542 std::find(Features.begin(), Features.end(), "+soft-float");
4543 if (it != Features.end())
4544 Features.erase(it);
4545 }
4546
getEHDataRegisterNumber(unsigned RegNo) const4547 virtual int getEHDataRegisterNumber(unsigned RegNo) const {
4548 if (RegNo == 0) return 4;
4549 if (RegNo == 1) return 5;
4550 return -1;
4551 }
4552 };
4553
4554 const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
4555 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
4556 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
4557 ALL_LANGUAGES },
4558 #include "clang/Basic/BuiltinsMips.def"
4559 };
4560
4561 class Mips32TargetInfoBase : public MipsTargetInfoBase {
4562 public:
Mips32TargetInfoBase(const std::string & triple)4563 Mips32TargetInfoBase(const std::string& triple) :
4564 MipsTargetInfoBase(triple, "o32", "mips32") {
4565 SizeType = UnsignedInt;
4566 PtrDiffType = SignedInt;
4567 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
4568 }
setABI(const std::string & Name)4569 virtual bool setABI(const std::string &Name) {
4570 if ((Name == "o32") || (Name == "eabi")) {
4571 ABI = Name;
4572 return true;
4573 } else if (Name == "32") {
4574 ABI = "o32";
4575 return true;
4576 } else
4577 return false;
4578 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4579 virtual void getTargetDefines(const LangOptions &Opts,
4580 MacroBuilder &Builder) const {
4581 MipsTargetInfoBase::getTargetDefines(Opts, Builder);
4582
4583 if (ABI == "o32") {
4584 Builder.defineMacro("__mips_o32");
4585 Builder.defineMacro("_ABIO32", "1");
4586 Builder.defineMacro("_MIPS_SIM", "_ABIO32");
4587 }
4588 else if (ABI == "eabi")
4589 Builder.defineMacro("__mips_eabi");
4590 else
4591 llvm_unreachable("Invalid ABI for Mips32.");
4592 }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4593 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4594 unsigned &NumAliases) const {
4595 static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
4596 { { "at" }, "$1" },
4597 { { "v0" }, "$2" },
4598 { { "v1" }, "$3" },
4599 { { "a0" }, "$4" },
4600 { { "a1" }, "$5" },
4601 { { "a2" }, "$6" },
4602 { { "a3" }, "$7" },
4603 { { "t0" }, "$8" },
4604 { { "t1" }, "$9" },
4605 { { "t2" }, "$10" },
4606 { { "t3" }, "$11" },
4607 { { "t4" }, "$12" },
4608 { { "t5" }, "$13" },
4609 { { "t6" }, "$14" },
4610 { { "t7" }, "$15" },
4611 { { "s0" }, "$16" },
4612 { { "s1" }, "$17" },
4613 { { "s2" }, "$18" },
4614 { { "s3" }, "$19" },
4615 { { "s4" }, "$20" },
4616 { { "s5" }, "$21" },
4617 { { "s6" }, "$22" },
4618 { { "s7" }, "$23" },
4619 { { "t8" }, "$24" },
4620 { { "t9" }, "$25" },
4621 { { "k0" }, "$26" },
4622 { { "k1" }, "$27" },
4623 { { "gp" }, "$28" },
4624 { { "sp","$sp" }, "$29" },
4625 { { "fp","$fp" }, "$30" },
4626 { { "ra" }, "$31" }
4627 };
4628 Aliases = GCCRegAliases;
4629 NumAliases = llvm::array_lengthof(GCCRegAliases);
4630 }
4631 };
4632
4633 class Mips32EBTargetInfo : public Mips32TargetInfoBase {
4634 public:
Mips32EBTargetInfo(const std::string & triple)4635 Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
4636 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4637 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
4638 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4639 virtual void getTargetDefines(const LangOptions &Opts,
4640 MacroBuilder &Builder) const {
4641 DefineStd(Builder, "MIPSEB", Opts);
4642 Builder.defineMacro("_MIPSEB");
4643 Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
4644 }
4645 };
4646
4647 class Mips32ELTargetInfo : public Mips32TargetInfoBase {
4648 public:
Mips32ELTargetInfo(const std::string & triple)4649 Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
4650 BigEndian = false;
4651 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4652 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
4653 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4654 virtual void getTargetDefines(const LangOptions &Opts,
4655 MacroBuilder &Builder) const {
4656 DefineStd(Builder, "MIPSEL", Opts);
4657 Builder.defineMacro("_MIPSEL");
4658 Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
4659 }
4660 };
4661
4662 class Mips64TargetInfoBase : public MipsTargetInfoBase {
4663 virtual void SetDescriptionString(const std::string &Name) = 0;
4664 public:
Mips64TargetInfoBase(const std::string & triple)4665 Mips64TargetInfoBase(const std::string& triple) :
4666 MipsTargetInfoBase(triple, "n64", "mips64") {
4667 LongWidth = LongAlign = 64;
4668 PointerWidth = PointerAlign = 64;
4669 LongDoubleWidth = LongDoubleAlign = 128;
4670 LongDoubleFormat = &llvm::APFloat::IEEEquad;
4671 if (getTriple().getOS() == llvm::Triple::FreeBSD) {
4672 LongDoubleWidth = LongDoubleAlign = 64;
4673 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
4674 }
4675 SuitableAlign = 128;
4676 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
4677 }
setABI(const std::string & Name)4678 virtual bool setABI(const std::string &Name) {
4679 SetDescriptionString(Name);
4680 if (Name == "n32") {
4681 LongWidth = LongAlign = 32;
4682 PointerWidth = PointerAlign = 32;
4683 ABI = Name;
4684 return true;
4685 } else if (Name == "n64") {
4686 ABI = Name;
4687 return true;
4688 } else if (Name == "64") {
4689 ABI = "n64";
4690 return true;
4691 } else
4692 return false;
4693 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4694 virtual void getTargetDefines(const LangOptions &Opts,
4695 MacroBuilder &Builder) const {
4696 MipsTargetInfoBase::getTargetDefines(Opts, Builder);
4697
4698 Builder.defineMacro("__mips64");
4699 Builder.defineMacro("__mips64__");
4700
4701 if (ABI == "n32") {
4702 Builder.defineMacro("__mips_n32");
4703 Builder.defineMacro("_ABIN32", "2");
4704 Builder.defineMacro("_MIPS_SIM", "_ABIN32");
4705 }
4706 else if (ABI == "n64") {
4707 Builder.defineMacro("__mips_n64");
4708 Builder.defineMacro("_ABI64", "3");
4709 Builder.defineMacro("_MIPS_SIM", "_ABI64");
4710 }
4711 else
4712 llvm_unreachable("Invalid ABI for Mips64.");
4713 }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4714 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4715 unsigned &NumAliases) const {
4716 static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
4717 { { "at" }, "$1" },
4718 { { "v0" }, "$2" },
4719 { { "v1" }, "$3" },
4720 { { "a0" }, "$4" },
4721 { { "a1" }, "$5" },
4722 { { "a2" }, "$6" },
4723 { { "a3" }, "$7" },
4724 { { "a4" }, "$8" },
4725 { { "a5" }, "$9" },
4726 { { "a6" }, "$10" },
4727 { { "a7" }, "$11" },
4728 { { "t0" }, "$12" },
4729 { { "t1" }, "$13" },
4730 { { "t2" }, "$14" },
4731 { { "t3" }, "$15" },
4732 { { "s0" }, "$16" },
4733 { { "s1" }, "$17" },
4734 { { "s2" }, "$18" },
4735 { { "s3" }, "$19" },
4736 { { "s4" }, "$20" },
4737 { { "s5" }, "$21" },
4738 { { "s6" }, "$22" },
4739 { { "s7" }, "$23" },
4740 { { "t8" }, "$24" },
4741 { { "t9" }, "$25" },
4742 { { "k0" }, "$26" },
4743 { { "k1" }, "$27" },
4744 { { "gp" }, "$28" },
4745 { { "sp","$sp" }, "$29" },
4746 { { "fp","$fp" }, "$30" },
4747 { { "ra" }, "$31" }
4748 };
4749 Aliases = GCCRegAliases;
4750 NumAliases = llvm::array_lengthof(GCCRegAliases);
4751 }
4752 };
4753
4754 class Mips64EBTargetInfo : public Mips64TargetInfoBase {
SetDescriptionString(const std::string & Name)4755 virtual void SetDescriptionString(const std::string &Name) {
4756 // Change DescriptionString only if ABI is n32.
4757 if (Name == "n32")
4758 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4759 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
4760 "v64:64:64-n32:64-S128";
4761 }
4762 public:
Mips64EBTargetInfo(const std::string & triple)4763 Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
4764 // Default ABI is n64.
4765 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4766 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
4767 "v64:64:64-n32:64-S128";
4768 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4769 virtual void getTargetDefines(const LangOptions &Opts,
4770 MacroBuilder &Builder) const {
4771 DefineStd(Builder, "MIPSEB", Opts);
4772 Builder.defineMacro("_MIPSEB");
4773 Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
4774 }
4775 };
4776
4777 class Mips64ELTargetInfo : public Mips64TargetInfoBase {
SetDescriptionString(const std::string & Name)4778 virtual void SetDescriptionString(const std::string &Name) {
4779 // Change DescriptionString only if ABI is n32.
4780 if (Name == "n32")
4781 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4782 "i64:64:64-f32:32:32-f64:64:64-f128:128:128"
4783 "-v64:64:64-n32:64-S128";
4784 }
4785 public:
Mips64ELTargetInfo(const std::string & triple)4786 Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
4787 // Default ABI is n64.
4788 BigEndian = false;
4789 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
4790 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
4791 "v64:64:64-n32:64-S128";
4792 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4793 virtual void getTargetDefines(const LangOptions &Opts,
4794 MacroBuilder &Builder) const {
4795 DefineStd(Builder, "MIPSEL", Opts);
4796 Builder.defineMacro("_MIPSEL");
4797 Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
4798 }
4799 };
4800 } // end anonymous namespace.
4801
4802 namespace {
4803 class PNaClTargetInfo : public TargetInfo {
4804 public:
PNaClTargetInfo(const std::string & triple)4805 PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) {
4806 BigEndian = false;
4807 this->UserLabelPrefix = "";
4808 this->LongAlign = 32;
4809 this->LongWidth = 32;
4810 this->PointerAlign = 32;
4811 this->PointerWidth = 32;
4812 this->IntMaxType = TargetInfo::SignedLongLong;
4813 this->UIntMaxType = TargetInfo::UnsignedLongLong;
4814 this->Int64Type = TargetInfo::SignedLongLong;
4815 this->DoubleAlign = 64;
4816 this->LongDoubleWidth = 64;
4817 this->LongDoubleAlign = 64;
4818 this->SizeType = TargetInfo::UnsignedInt;
4819 this->PtrDiffType = TargetInfo::SignedInt;
4820 this->IntPtrType = TargetInfo::SignedInt;
4821 this->RegParmMax = 2;
4822 DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
4823 "f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
4824 }
4825
getDefaultFeatures(llvm::StringMap<bool> & Features) const4826 void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
4827 }
getArchDefines(const LangOptions & Opts,MacroBuilder & Builder) const4828 virtual void getArchDefines(const LangOptions &Opts,
4829 MacroBuilder &Builder) const {
4830 Builder.defineMacro("__le32__");
4831 Builder.defineMacro("__pnacl__");
4832 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4833 virtual void getTargetDefines(const LangOptions &Opts,
4834 MacroBuilder &Builder) const {
4835 Builder.defineMacro("__LITTLE_ENDIAN__");
4836 getArchDefines(Opts, Builder);
4837 }
hasFeature(StringRef Feature) const4838 virtual bool hasFeature(StringRef Feature) const {
4839 return Feature == "pnacl";
4840 }
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4841 virtual void getTargetBuiltins(const Builtin::Info *&Records,
4842 unsigned &NumRecords) const {
4843 }
getBuiltinVaListKind() const4844 virtual BuiltinVaListKind getBuiltinVaListKind() const {
4845 return TargetInfo::PNaClABIBuiltinVaList;
4846 }
4847 virtual void getGCCRegNames(const char * const *&Names,
4848 unsigned &NumNames) const;
4849 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4850 unsigned &NumAliases) const;
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const4851 virtual bool validateAsmConstraint(const char *&Name,
4852 TargetInfo::ConstraintInfo &Info) const {
4853 return false;
4854 }
4855
getClobbers() const4856 virtual const char *getClobbers() const {
4857 return "";
4858 }
4859 };
4860
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4861 void PNaClTargetInfo::getGCCRegNames(const char * const *&Names,
4862 unsigned &NumNames) const {
4863 Names = NULL;
4864 NumNames = 0;
4865 }
4866
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4867 void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
4868 unsigned &NumAliases) const {
4869 Aliases = NULL;
4870 NumAliases = 0;
4871 }
4872 } // end anonymous namespace.
4873
4874 namespace {
4875 static const unsigned SPIRAddrSpaceMap[] = {
4876 1, // opencl_global
4877 3, // opencl_local
4878 2, // opencl_constant
4879 0, // cuda_device
4880 0, // cuda_constant
4881 0 // cuda_shared
4882 };
4883 class SPIRTargetInfo : public TargetInfo {
4884 static const char * const GCCRegNames[];
4885 static const Builtin::Info BuiltinInfo[];
4886 std::vector<StringRef> AvailableFeatures;
4887 public:
SPIRTargetInfo(const std::string & triple)4888 SPIRTargetInfo(const std::string& triple) : TargetInfo(triple) {
4889 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
4890 "SPIR target must use unknown OS");
4891 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
4892 "SPIR target must use unknown environment type");
4893 BigEndian = false;
4894 TLSSupported = false;
4895 LongWidth = LongAlign = 64;
4896 AddrSpaceMap = &SPIRAddrSpaceMap;
4897 // Define available target features
4898 // These must be defined in sorted order!
4899 NoAsmVariants = true;
4900 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4901 virtual void getTargetDefines(const LangOptions &Opts,
4902 MacroBuilder &Builder) const {
4903 DefineStd(Builder, "SPIR", Opts);
4904 }
hasFeature(StringRef Feature) const4905 virtual bool hasFeature(StringRef Feature) const {
4906 return Feature == "spir";
4907 }
4908
getTargetBuiltins(const Builtin::Info * & Records,unsigned & NumRecords) const4909 virtual void getTargetBuiltins(const Builtin::Info *&Records,
4910 unsigned &NumRecords) const {}
getClobbers() const4911 virtual const char *getClobbers() const {
4912 return "";
4913 }
getGCCRegNames(const char * const * & Names,unsigned & NumNames) const4914 virtual void getGCCRegNames(const char * const *&Names,
4915 unsigned &NumNames) const {}
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info) const4916 virtual bool validateAsmConstraint(const char *&Name,
4917 TargetInfo::ConstraintInfo &info) const {
4918 return true;
4919 }
getGCCRegAliases(const GCCRegAlias * & Aliases,unsigned & NumAliases) const4920 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
4921 unsigned &NumAliases) const {}
getBuiltinVaListKind() const4922 virtual BuiltinVaListKind getBuiltinVaListKind() const {
4923 return TargetInfo::VoidPtrBuiltinVaList;
4924 }
4925 };
4926
4927
4928 class SPIR32TargetInfo : public SPIRTargetInfo {
4929 public:
SPIR32TargetInfo(const std::string & triple)4930 SPIR32TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) {
4931 PointerWidth = PointerAlign = 32;
4932 SizeType = TargetInfo::UnsignedInt;
4933 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
4934 DescriptionString
4935 = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
4936 "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-"
4937 "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-"
4938 "v512:512:512-v1024:1024:1024";
4939 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4940 virtual void getTargetDefines(const LangOptions &Opts,
4941 MacroBuilder &Builder) const {
4942 DefineStd(Builder, "SPIR32", Opts);
4943 }
4944 };
4945
4946 class SPIR64TargetInfo : public SPIRTargetInfo {
4947 public:
SPIR64TargetInfo(const std::string & triple)4948 SPIR64TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) {
4949 PointerWidth = PointerAlign = 64;
4950 SizeType = TargetInfo::UnsignedLong;
4951 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
4952 DescriptionString
4953 = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
4954 "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-"
4955 "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-"
4956 "v512:512:512-v1024:1024:1024";
4957 }
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const4958 virtual void getTargetDefines(const LangOptions &Opts,
4959 MacroBuilder &Builder) const {
4960 DefineStd(Builder, "SPIR64", Opts);
4961 }
4962 };
4963 }
4964
4965
4966 //===----------------------------------------------------------------------===//
4967 // Driver code
4968 //===----------------------------------------------------------------------===//
4969
AllocateTarget(const std::string & T)4970 static TargetInfo *AllocateTarget(const std::string &T) {
4971 llvm::Triple Triple(T);
4972 llvm::Triple::OSType os = Triple.getOS();
4973
4974 switch (Triple.getArch()) {
4975 default:
4976 return NULL;
4977
4978 case llvm::Triple::hexagon:
4979 return new HexagonTargetInfo(T);
4980
4981 case llvm::Triple::aarch64:
4982 switch (os) {
4983 case llvm::Triple::Linux:
4984 return new LinuxTargetInfo<AArch64TargetInfo>(T);
4985 default:
4986 return new AArch64TargetInfo(T);
4987 }
4988
4989 case llvm::Triple::arm:
4990 case llvm::Triple::thumb:
4991 if (Triple.isOSDarwin())
4992 return new DarwinARMTargetInfo(T);
4993
4994 switch (os) {
4995 case llvm::Triple::Linux:
4996 return new LinuxTargetInfo<ARMTargetInfo>(T);
4997 case llvm::Triple::FreeBSD:
4998 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
4999 case llvm::Triple::NetBSD:
5000 return new NetBSDTargetInfo<ARMTargetInfo>(T);
5001 case llvm::Triple::OpenBSD:
5002 return new OpenBSDTargetInfo<ARMTargetInfo>(T);
5003 case llvm::Triple::Bitrig:
5004 return new BitrigTargetInfo<ARMTargetInfo>(T);
5005 case llvm::Triple::RTEMS:
5006 return new RTEMSTargetInfo<ARMTargetInfo>(T);
5007 case llvm::Triple::NaCl:
5008 return new NaClTargetInfo<ARMTargetInfo>(T);
5009 default:
5010 return new ARMTargetInfo(T);
5011 }
5012
5013 case llvm::Triple::msp430:
5014 return new MSP430TargetInfo(T);
5015
5016 case llvm::Triple::mips:
5017 switch (os) {
5018 case llvm::Triple::Linux:
5019 return new LinuxTargetInfo<Mips32EBTargetInfo>(T);
5020 case llvm::Triple::RTEMS:
5021 return new RTEMSTargetInfo<Mips32EBTargetInfo>(T);
5022 case llvm::Triple::FreeBSD:
5023 return new FreeBSDTargetInfo<Mips32EBTargetInfo>(T);
5024 case llvm::Triple::NetBSD:
5025 return new NetBSDTargetInfo<Mips32EBTargetInfo>(T);
5026 default:
5027 return new Mips32EBTargetInfo(T);
5028 }
5029
5030 case llvm::Triple::mipsel:
5031 switch (os) {
5032 case llvm::Triple::Linux:
5033 return new LinuxTargetInfo<Mips32ELTargetInfo>(T);
5034 case llvm::Triple::RTEMS:
5035 return new RTEMSTargetInfo<Mips32ELTargetInfo>(T);
5036 case llvm::Triple::FreeBSD:
5037 return new FreeBSDTargetInfo<Mips32ELTargetInfo>(T);
5038 case llvm::Triple::NetBSD:
5039 return new NetBSDTargetInfo<Mips32ELTargetInfo>(T);
5040 default:
5041 return new Mips32ELTargetInfo(T);
5042 }
5043
5044 case llvm::Triple::mips64:
5045 switch (os) {
5046 case llvm::Triple::Linux:
5047 return new LinuxTargetInfo<Mips64EBTargetInfo>(T);
5048 case llvm::Triple::RTEMS:
5049 return new RTEMSTargetInfo<Mips64EBTargetInfo>(T);
5050 case llvm::Triple::FreeBSD:
5051 return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T);
5052 case llvm::Triple::NetBSD:
5053 return new NetBSDTargetInfo<Mips64EBTargetInfo>(T);
5054 case llvm::Triple::OpenBSD:
5055 return new OpenBSDTargetInfo<Mips64EBTargetInfo>(T);
5056 default:
5057 return new Mips64EBTargetInfo(T);
5058 }
5059
5060 case llvm::Triple::mips64el:
5061 switch (os) {
5062 case llvm::Triple::Linux:
5063 return new LinuxTargetInfo<Mips64ELTargetInfo>(T);
5064 case llvm::Triple::RTEMS:
5065 return new RTEMSTargetInfo<Mips64ELTargetInfo>(T);
5066 case llvm::Triple::FreeBSD:
5067 return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T);
5068 case llvm::Triple::NetBSD:
5069 return new NetBSDTargetInfo<Mips64ELTargetInfo>(T);
5070 case llvm::Triple::OpenBSD:
5071 return new OpenBSDTargetInfo<Mips64ELTargetInfo>(T);
5072 default:
5073 return new Mips64ELTargetInfo(T);
5074 }
5075
5076 case llvm::Triple::le32:
5077 switch (os) {
5078 case llvm::Triple::NaCl:
5079 return new NaClTargetInfo<PNaClTargetInfo>(T);
5080 default:
5081 return NULL;
5082 }
5083
5084 case llvm::Triple::ppc:
5085 if (Triple.isOSDarwin())
5086 return new DarwinPPC32TargetInfo(T);
5087 switch (os) {
5088 case llvm::Triple::Linux:
5089 return new LinuxTargetInfo<PPC32TargetInfo>(T);
5090 case llvm::Triple::FreeBSD:
5091 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
5092 case llvm::Triple::NetBSD:
5093 return new NetBSDTargetInfo<PPC32TargetInfo>(T);
5094 case llvm::Triple::OpenBSD:
5095 return new OpenBSDTargetInfo<PPC32TargetInfo>(T);
5096 case llvm::Triple::RTEMS:
5097 return new RTEMSTargetInfo<PPC32TargetInfo>(T);
5098 default:
5099 return new PPC32TargetInfo(T);
5100 }
5101
5102 case llvm::Triple::ppc64:
5103 if (Triple.isOSDarwin())
5104 return new DarwinPPC64TargetInfo(T);
5105 switch (os) {
5106 case llvm::Triple::Linux:
5107 return new LinuxTargetInfo<PPC64TargetInfo>(T);
5108 case llvm::Triple::Lv2:
5109 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
5110 case llvm::Triple::FreeBSD:
5111 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
5112 case llvm::Triple::NetBSD:
5113 return new NetBSDTargetInfo<PPC64TargetInfo>(T);
5114 default:
5115 return new PPC64TargetInfo(T);
5116 }
5117
5118 case llvm::Triple::nvptx:
5119 return new NVPTX32TargetInfo(T);
5120 case llvm::Triple::nvptx64:
5121 return new NVPTX64TargetInfo(T);
5122
5123 case llvm::Triple::mblaze:
5124 return new MBlazeTargetInfo(T);
5125
5126 case llvm::Triple::r600:
5127 return new R600TargetInfo(T);
5128
5129 case llvm::Triple::sparc:
5130 switch (os) {
5131 case llvm::Triple::Linux:
5132 return new LinuxTargetInfo<SparcV8TargetInfo>(T);
5133 case llvm::Triple::AuroraUX:
5134 return new AuroraUXSparcV8TargetInfo(T);
5135 case llvm::Triple::Solaris:
5136 return new SolarisSparcV8TargetInfo(T);
5137 case llvm::Triple::NetBSD:
5138 return new NetBSDTargetInfo<SparcV8TargetInfo>(T);
5139 case llvm::Triple::OpenBSD:
5140 return new OpenBSDTargetInfo<SparcV8TargetInfo>(T);
5141 case llvm::Triple::RTEMS:
5142 return new RTEMSTargetInfo<SparcV8TargetInfo>(T);
5143 default:
5144 return new SparcV8TargetInfo(T);
5145 }
5146
5147 case llvm::Triple::tce:
5148 return new TCETargetInfo(T);
5149
5150 case llvm::Triple::x86:
5151 if (Triple.isOSDarwin())
5152 return new DarwinI386TargetInfo(T);
5153
5154 switch (os) {
5155 case llvm::Triple::AuroraUX:
5156 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
5157 case llvm::Triple::Linux:
5158 return new LinuxTargetInfo<X86_32TargetInfo>(T);
5159 case llvm::Triple::DragonFly:
5160 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
5161 case llvm::Triple::NetBSD:
5162 return new NetBSDI386TargetInfo(T);
5163 case llvm::Triple::OpenBSD:
5164 return new OpenBSDI386TargetInfo(T);
5165 case llvm::Triple::Bitrig:
5166 return new BitrigI386TargetInfo(T);
5167 case llvm::Triple::FreeBSD:
5168 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
5169 case llvm::Triple::Minix:
5170 return new MinixTargetInfo<X86_32TargetInfo>(T);
5171 case llvm::Triple::Solaris:
5172 return new SolarisTargetInfo<X86_32TargetInfo>(T);
5173 case llvm::Triple::Cygwin:
5174 return new CygwinX86_32TargetInfo(T);
5175 case llvm::Triple::MinGW32:
5176 return new MinGWX86_32TargetInfo(T);
5177 case llvm::Triple::Win32:
5178 return new VisualStudioWindowsX86_32TargetInfo(T);
5179 case llvm::Triple::Haiku:
5180 return new HaikuX86_32TargetInfo(T);
5181 case llvm::Triple::RTEMS:
5182 return new RTEMSX86_32TargetInfo(T);
5183 case llvm::Triple::NaCl:
5184 return new NaClTargetInfo<X86_32TargetInfo>(T);
5185 default:
5186 return new X86_32TargetInfo(T);
5187 }
5188
5189 case llvm::Triple::x86_64:
5190 if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
5191 return new DarwinX86_64TargetInfo(T);
5192
5193 switch (os) {
5194 case llvm::Triple::AuroraUX:
5195 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
5196 case llvm::Triple::Linux:
5197 return new LinuxTargetInfo<X86_64TargetInfo>(T);
5198 case llvm::Triple::DragonFly:
5199 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
5200 case llvm::Triple::NetBSD:
5201 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
5202 case llvm::Triple::OpenBSD:
5203 return new OpenBSDX86_64TargetInfo(T);
5204 case llvm::Triple::Bitrig:
5205 return new BitrigX86_64TargetInfo(T);
5206 case llvm::Triple::FreeBSD:
5207 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
5208 case llvm::Triple::Solaris:
5209 return new SolarisTargetInfo<X86_64TargetInfo>(T);
5210 case llvm::Triple::MinGW32:
5211 return new MinGWX86_64TargetInfo(T);
5212 case llvm::Triple::Win32: // This is what Triple.h supports now.
5213 return new VisualStudioWindowsX86_64TargetInfo(T);
5214 case llvm::Triple::NaCl:
5215 return new NaClTargetInfo<X86_64TargetInfo>(T);
5216 default:
5217 return new X86_64TargetInfo(T);
5218 }
5219
5220 case llvm::Triple::spir: {
5221 llvm::Triple Triple(T);
5222 if (Triple.getOS() != llvm::Triple::UnknownOS ||
5223 Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
5224 return NULL;
5225 return new SPIR32TargetInfo(T);
5226 }
5227 case llvm::Triple::spir64: {
5228 llvm::Triple Triple(T);
5229 if (Triple.getOS() != llvm::Triple::UnknownOS ||
5230 Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
5231 return NULL;
5232 return new SPIR64TargetInfo(T);
5233 }
5234 }
5235 }
5236
5237 /// CreateTargetInfo - Return the target info object for the specified target
5238 /// triple.
CreateTargetInfo(DiagnosticsEngine & Diags,TargetOptions * Opts)5239 TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
5240 TargetOptions *Opts) {
5241 llvm::Triple Triple(Opts->Triple);
5242
5243 // Construct the target
5244 OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
5245 if (!Target) {
5246 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
5247 return 0;
5248 }
5249 Target->setTargetOpts(Opts);
5250
5251 // Set the target CPU if specified.
5252 if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
5253 Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
5254 return 0;
5255 }
5256
5257 // Set the target ABI if specified.
5258 if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
5259 Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
5260 return 0;
5261 }
5262
5263 // Set the target C++ ABI.
5264 if (!Opts->CXXABI.empty() && !Target->setCXXABI(Opts->CXXABI)) {
5265 Diags.Report(diag::err_target_unknown_cxxabi) << Opts->CXXABI;
5266 return 0;
5267 }
5268
5269 // Compute the default target features, we need the target to handle this
5270 // because features may have dependencies on one another.
5271 llvm::StringMap<bool> Features;
5272 Target->getDefaultFeatures(Features);
5273
5274 // Apply the user specified deltas.
5275 // First the enables.
5276 for (std::vector<std::string>::const_iterator
5277 it = Opts->FeaturesAsWritten.begin(),
5278 ie = Opts->FeaturesAsWritten.end();
5279 it != ie; ++it) {
5280 const char *Name = it->c_str();
5281
5282 if (Name[0] != '+')
5283 continue;
5284
5285 // Apply the feature via the target.
5286 if (!Target->setFeatureEnabled(Features, Name + 1, true)) {
5287 Diags.Report(diag::err_target_invalid_feature) << Name;
5288 return 0;
5289 }
5290 }
5291
5292 // Then the disables.
5293 for (std::vector<std::string>::const_iterator
5294 it = Opts->FeaturesAsWritten.begin(),
5295 ie = Opts->FeaturesAsWritten.end();
5296 it != ie; ++it) {
5297 const char *Name = it->c_str();
5298
5299 if (Name[0] == '+')
5300 continue;
5301
5302 // Apply the feature via the target.
5303 if (Name[0] != '-' ||
5304 !Target->setFeatureEnabled(Features, Name + 1, false)) {
5305 Diags.Report(diag::err_target_invalid_feature) << Name;
5306 return 0;
5307 }
5308 }
5309
5310 // Add the features to the compile options.
5311 //
5312 // FIXME: If we are completely confident that we have the right set, we only
5313 // need to pass the minuses.
5314 Opts->Features.clear();
5315 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
5316 ie = Features.end(); it != ie; ++it)
5317 Opts->Features.push_back((it->second ? "+" : "-") + it->first().str());
5318 Target->HandleTargetFeatures(Opts->Features);
5319
5320 return Target.take();
5321 }
5322