Some Intel Penryn CPUs come with SSE4 disabled. Detect them as core 2.
[oota-llvm.git] / lib / Support / Host.cpp
1 //===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===//
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 header file implements the operating system Host concept.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Support/Host.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Config/config.h"
20 #include "llvm/Support/DataStream.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <string.h>
24
25 // Include the platform-specific parts of this class.
26 #ifdef LLVM_ON_UNIX
27 #include "Unix/Host.inc"
28 #endif
29 #ifdef LLVM_ON_WIN32
30 #include "Windows/Host.inc"
31 #endif
32 #ifdef _MSC_VER
33 #include <intrin.h>
34 #endif
35 #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
36 #include <mach/mach.h>
37 #include <mach/mach_host.h>
38 #include <mach/host_info.h>
39 #include <mach/machine.h>
40 #endif
41
42 //===----------------------------------------------------------------------===//
43 //
44 //  Implementations of the CPU detection routines
45 //
46 //===----------------------------------------------------------------------===//
47
48 using namespace llvm;
49
50 #if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\
51  || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
52
53 /// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
54 /// specified arguments.  If we can't run cpuid on the host, return true.
55 static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX,
56                             unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
57 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
58   #if defined(__GNUC__)
59     // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
60     asm ("movq\t%%rbx, %%rsi\n\t"
61          "cpuid\n\t"
62          "xchgq\t%%rbx, %%rsi\n\t"
63          : "=a" (*rEAX),
64            "=S" (*rEBX),
65            "=c" (*rECX),
66            "=d" (*rEDX)
67          :  "a" (value));
68     return false;
69   #elif defined(_MSC_VER)
70     int registers[4];
71     __cpuid(registers, value);
72     *rEAX = registers[0];
73     *rEBX = registers[1];
74     *rECX = registers[2];
75     *rEDX = registers[3];
76     return false;
77   #else
78     return true;
79   #endif
80 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
81   #if defined(__GNUC__)
82     asm ("movl\t%%ebx, %%esi\n\t"
83          "cpuid\n\t"
84          "xchgl\t%%ebx, %%esi\n\t"
85          : "=a" (*rEAX),
86            "=S" (*rEBX),
87            "=c" (*rECX),
88            "=d" (*rEDX)
89          :  "a" (value));
90     return false;
91   #elif defined(_MSC_VER)
92     __asm {
93       mov   eax,value
94       cpuid
95       mov   esi,rEAX
96       mov   dword ptr [esi],eax
97       mov   esi,rEBX
98       mov   dword ptr [esi],ebx
99       mov   esi,rECX
100       mov   dword ptr [esi],ecx
101       mov   esi,rEDX
102       mov   dword ptr [esi],edx
103     }
104     return false;
105 // pedantic #else returns to appease -Wunreachable-code (so we don't generate
106 // postprocessed code that looks like "return true; return false;")
107   #else
108     return true;
109   #endif
110 #else
111   return true;
112 #endif
113 }
114
115 static bool OSHasAVXSupport() {
116 #if defined(__GNUC__)
117   // Check xgetbv; this uses a .byte sequence instead of the instruction
118   // directly because older assemblers do not include support for xgetbv and
119   // there is no easy way to conditionally compile based on the assembler used.
120   int rEAX, rEDX;
121   __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (rEAX), "=d" (rEDX) : "c" (0));
122 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
123   unsigned long long rEAX = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
124 #else
125   int rEAX = 0; // Ensures we return false
126 #endif
127   return (rEAX & 6) == 6;
128 }
129
130 static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
131                                  unsigned &Model) {
132   Family = (EAX >> 8) & 0xf; // Bits 8 - 11
133   Model  = (EAX >> 4) & 0xf; // Bits 4 - 7
134   if (Family == 6 || Family == 0xf) {
135     if (Family == 0xf)
136       // Examine extended family ID if family ID is F.
137       Family += (EAX >> 20) & 0xff;    // Bits 20 - 27
138     // Examine extended model ID if family ID is 6 or F.
139     Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
140   }
141 }
142
143 std::string sys::getHostCPUName() {
144   unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
145   if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
146     return "generic";
147   unsigned Family = 0;
148   unsigned Model  = 0;
149   DetectX86FamilyModel(EAX, Family, Model);
150
151   bool HasSSE3 = (ECX & 0x1);
152   bool HasSSE41 = (ECX & 0x80000);
153   // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 
154   // indicates that the AVX registers will be saved and restored on context
155   // switch, then we have full AVX support.
156   const unsigned AVXBits = (1 << 27) | (1 << 28);
157   bool HasAVX = ((ECX & AVXBits) == AVXBits) && OSHasAVXSupport();
158   GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
159   bool Em64T = (EDX >> 29) & 0x1;
160
161   union {
162     unsigned u[3];
163     char     c[12];
164   } text;
165
166   GetX86CpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1);
167   if (memcmp(text.c, "GenuineIntel", 12) == 0) {
168     switch (Family) {
169     case 3:
170       return "i386";
171     case 4:
172       switch (Model) {
173       case 0: // Intel486 DX processors
174       case 1: // Intel486 DX processors
175       case 2: // Intel486 SX processors
176       case 3: // Intel487 processors, IntelDX2 OverDrive processors,
177               // IntelDX2 processors
178       case 4: // Intel486 SL processor
179       case 5: // IntelSX2 processors
180       case 7: // Write-Back Enhanced IntelDX2 processors
181       case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
182       default: return "i486";
183       }
184     case 5:
185       switch (Model) {
186       case  1: // Pentium OverDrive processor for Pentium processor (60, 66),
187                // Pentium processors (60, 66)
188       case  2: // Pentium OverDrive processor for Pentium processor (75, 90,
189                // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
190                // 150, 166, 200)
191       case  3: // Pentium OverDrive processors for Intel486 processor-based
192                // systems
193         return "pentium";
194
195       case  4: // Pentium OverDrive processor with MMX technology for Pentium
196                // processor (75, 90, 100, 120, 133), Pentium processor with
197                // MMX technology (166, 200)
198         return "pentium-mmx";
199
200       default: return "pentium";
201       }
202     case 6:
203       switch (Model) {
204       case  1: // Pentium Pro processor
205         return "pentiumpro";
206
207       case  3: // Intel Pentium II OverDrive processor, Pentium II processor,
208                // model 03
209       case  5: // Pentium II processor, model 05, Pentium II Xeon processor,
210                // model 05, and Intel Celeron processor, model 05
211       case  6: // Celeron processor, model 06
212         return "pentium2";
213
214       case  7: // Pentium III processor, model 07, and Pentium III Xeon
215                // processor, model 07
216       case  8: // Pentium III processor, model 08, Pentium III Xeon processor,
217                // model 08, and Celeron processor, model 08
218       case 10: // Pentium III Xeon processor, model 0Ah
219       case 11: // Pentium III processor, model 0Bh
220         return "pentium3";
221
222       case  9: // Intel Pentium M processor, Intel Celeron M processor model 09.
223       case 13: // Intel Pentium M processor, Intel Celeron M processor, model
224                // 0Dh. All processors are manufactured using the 90 nm process.
225         return "pentium-m";
226
227       case 14: // Intel Core Duo processor, Intel Core Solo processor, model
228                // 0Eh. All processors are manufactured using the 65 nm process.
229         return "yonah";
230
231       case 15: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
232                // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
233                // mobile processor, Intel Core 2 Extreme processor, Intel
234                // Pentium Dual-Core processor, Intel Xeon processor, model
235                // 0Fh. All processors are manufactured using the 65 nm process.
236       case 22: // Intel Celeron processor model 16h. All processors are
237                // manufactured using the 65 nm process
238         return "core2";
239
240       case 21: // Intel EP80579 Integrated Processor and Intel EP80579
241                // Integrated Processor with Intel QuickAssist Technology
242         return "i686"; // FIXME: ???
243
244       case 23: // Intel Core 2 Extreme processor, Intel Xeon processor, model
245                // 17h. All processors are manufactured using the 45 nm process.
246                //
247                // 45nm: Penryn , Wolfdale, Yorkfield (XE)
248         // Not all Penryn processors support SSE 4.1 (such as the Pentium brand)
249         return HasSSE41 ? "penryn" : "core2";
250
251       case 26: // Intel Core i7 processor and Intel Xeon processor. All
252                // processors are manufactured using the 45 nm process.
253       case 29: // Intel Xeon processor MP. All processors are manufactured using
254                // the 45 nm process.
255       case 30: // Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz.
256                // As found in a Summer 2010 model iMac.
257       case 37: // Intel Core i7, laptop version.
258       case 44: // Intel Core i7 processor and Intel Xeon processor. All
259                // processors are manufactured using the 32 nm process.
260       case 46: // Nehalem EX
261       case 47: // Westmere EX
262         return "corei7";
263
264       // SandyBridge:
265       case 42: // Intel Core i7 processor. All processors are manufactured
266                // using the 32 nm process.
267       case 45:
268         // Not all Sandy Bridge processors support AVX (such as the Pentium
269         // versions instead of the i7 versions).
270         return HasAVX ? "corei7-avx" : "corei7";
271
272       // Ivy Bridge:
273       case 58:
274         // Not all Ivy Bridge processors support AVX (such as the Pentium
275         // versions instead of the i7 versions).
276         return HasAVX ? "core-avx-i" : "corei7";
277
278       case 28: // Most 45 nm Intel Atom processors
279       case 38: // 45 nm Atom Lincroft
280       case 39: // 32 nm Atom Medfield
281       case 53: // 32 nm Atom Midview
282       case 54: // 32 nm Atom Midview
283         return "atom";
284
285       default: return (Em64T) ? "x86-64" : "i686";
286       }
287     case 15: {
288       switch (Model) {
289       case  0: // Pentium 4 processor, Intel Xeon processor. All processors are
290                // model 00h and manufactured using the 0.18 micron process.
291       case  1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
292                // processor MP, and Intel Celeron processor. All processors are
293                // model 01h and manufactured using the 0.18 micron process.
294       case  2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
295                // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
296                // processor, and Mobile Intel Celeron processor. All processors
297                // are model 02h and manufactured using the 0.13 micron process.
298         return (Em64T) ? "x86-64" : "pentium4";
299
300       case  3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
301                // processor. All processors are model 03h and manufactured using
302                // the 90 nm process.
303       case  4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
304                // Pentium D processor, Intel Xeon processor, Intel Xeon
305                // processor MP, Intel Celeron D processor. All processors are
306                // model 04h and manufactured using the 90 nm process.
307       case  6: // Pentium 4 processor, Pentium D processor, Pentium processor
308                // Extreme Edition, Intel Xeon processor, Intel Xeon processor
309                // MP, Intel Celeron D processor. All processors are model 06h
310                // and manufactured using the 65 nm process.
311         return (Em64T) ? "nocona" : "prescott";
312
313       default:
314         return (Em64T) ? "x86-64" : "pentium4";
315       }
316     }
317
318     default:
319       return "generic";
320     }
321   } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
322     // FIXME: this poorly matches the generated SubtargetFeatureKV table.  There
323     // appears to be no way to generate the wide variety of AMD-specific targets
324     // from the information returned from CPUID.
325     switch (Family) {
326       case 4:
327         return "i486";
328       case 5:
329         switch (Model) {
330         case 6:
331         case 7:  return "k6";
332         case 8:  return "k6-2";
333         case 9:
334         case 13: return "k6-3";
335         case 10: return "geode";
336         default: return "pentium";
337         }
338       case 6:
339         switch (Model) {
340         case 4:  return "athlon-tbird";
341         case 6:
342         case 7:
343         case 8:  return "athlon-mp";
344         case 10: return "athlon-xp";
345         default: return "athlon";
346         }
347       case 15:
348         if (HasSSE3)
349           return "k8-sse3";
350         switch (Model) {
351         case 1:  return "opteron";
352         case 5:  return "athlon-fx"; // also opteron
353         default: return "athlon64";
354         }
355       case 16:
356         return "amdfam10";
357       case 20:
358         return "btver1";
359       case 21:
360         if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
361           return "btver1";
362         if (Model > 15 && Model <= 31)
363           return "bdver2";
364         return "bdver1";
365       case 22:
366         if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
367           return "btver1";
368         return "btver2";
369     default:
370       return "generic";
371     }
372   }
373   return "generic";
374 }
375 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
376 std::string sys::getHostCPUName() {
377   host_basic_info_data_t hostInfo;
378   mach_msg_type_number_t infoCount;
379
380   infoCount = HOST_BASIC_INFO_COUNT;
381   host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, 
382             &infoCount);
383             
384   if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic";
385
386   switch(hostInfo.cpu_subtype) {
387   case CPU_SUBTYPE_POWERPC_601:   return "601";
388   case CPU_SUBTYPE_POWERPC_602:   return "602";
389   case CPU_SUBTYPE_POWERPC_603:   return "603";
390   case CPU_SUBTYPE_POWERPC_603e:  return "603e";
391   case CPU_SUBTYPE_POWERPC_603ev: return "603ev";
392   case CPU_SUBTYPE_POWERPC_604:   return "604";
393   case CPU_SUBTYPE_POWERPC_604e:  return "604e";
394   case CPU_SUBTYPE_POWERPC_620:   return "620";
395   case CPU_SUBTYPE_POWERPC_750:   return "750";
396   case CPU_SUBTYPE_POWERPC_7400:  return "7400";
397   case CPU_SUBTYPE_POWERPC_7450:  return "7450";
398   case CPU_SUBTYPE_POWERPC_970:   return "970";
399   default: ;
400   }
401   
402   return "generic";
403 }
404 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
405 std::string sys::getHostCPUName() {
406   // Access to the Processor Version Register (PVR) on PowerPC is privileged,
407   // and so we must use an operating-system interface to determine the current
408   // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
409   const char *generic = "generic";
410
411   // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
412   // memory buffer because the 'file' has 0 size (it can be read from only
413   // as a stream).
414
415   std::string Err;
416   DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
417   if (!DS) {
418     DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
419     return generic;
420   }
421
422   // The cpu line is second (after the 'processor: 0' line), so if this
423   // buffer is too small then something has changed (or is wrong).
424   char buffer[1024];
425   size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
426   delete DS;
427
428   const char *CPUInfoStart = buffer;
429   const char *CPUInfoEnd = buffer + CPUInfoSize;
430
431   const char *CIP = CPUInfoStart;
432
433   const char *CPUStart = 0;
434   size_t CPULen = 0;
435
436   // We need to find the first line which starts with cpu, spaces, and a colon.
437   // After the colon, there may be some additional spaces and then the cpu type.
438   while (CIP < CPUInfoEnd && CPUStart == 0) {
439     if (CIP < CPUInfoEnd && *CIP == '\n')
440       ++CIP;
441
442     if (CIP < CPUInfoEnd && *CIP == 'c') {
443       ++CIP;
444       if (CIP < CPUInfoEnd && *CIP == 'p') {
445         ++CIP;
446         if (CIP < CPUInfoEnd && *CIP == 'u') {
447           ++CIP;
448           while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
449             ++CIP;
450   
451           if (CIP < CPUInfoEnd && *CIP == ':') {
452             ++CIP;
453             while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
454               ++CIP;
455   
456             if (CIP < CPUInfoEnd) {
457               CPUStart = CIP;
458               while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
459                                           *CIP != ',' && *CIP != '\n'))
460                 ++CIP;
461               CPULen = CIP - CPUStart;
462             }
463           }
464         }
465       }
466     }
467
468     if (CPUStart == 0)
469       while (CIP < CPUInfoEnd && *CIP != '\n')
470         ++CIP;
471   }
472
473   if (CPUStart == 0)
474     return generic;
475
476   return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
477     .Case("604e", "604e")
478     .Case("604", "604")
479     .Case("7400", "7400")
480     .Case("7410", "7400")
481     .Case("7447", "7400")
482     .Case("7455", "7450")
483     .Case("G4", "g4")
484     .Case("POWER4", "970")
485     .Case("PPC970FX", "970")
486     .Case("PPC970MP", "970")
487     .Case("G5", "g5")
488     .Case("POWER5", "g5")
489     .Case("A2", "a2")
490     .Case("POWER6", "pwr6")
491     .Case("POWER7", "pwr7")
492     .Default(generic);
493 }
494 #elif defined(__linux__) && defined(__arm__)
495 std::string sys::getHostCPUName() {
496   // The cpuid register on arm is not accessible from user space. On Linux,
497   // it is exposed through the /proc/cpuinfo file.
498   // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
499   // memory buffer because the 'file' has 0 size (it can be read from only
500   // as a stream).
501
502   std::string Err;
503   DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
504   if (!DS) {
505     DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
506     return "generic";
507   }
508
509   // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
510   // in all cases.
511   char buffer[1024];
512   size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
513   delete DS;
514
515   StringRef Str(buffer, CPUInfoSize);
516
517   SmallVector<StringRef, 32> Lines;
518   Str.split(Lines, "\n");
519
520   // Look for the CPU implementer line.
521   StringRef Implementer;
522   for (unsigned I = 0, E = Lines.size(); I != E; ++I)
523     if (Lines[I].startswith("CPU implementer"))
524       Implementer = Lines[I].substr(15).ltrim("\t :");
525
526   if (Implementer == "0x41") // ARM Ltd.
527     // Look for the CPU part line.
528     for (unsigned I = 0, E = Lines.size(); I != E; ++I)
529       if (Lines[I].startswith("CPU part"))
530         // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
531         // values correspond to the "Part number" in the CP15/c0 register. The
532         // contents are specified in the various processor manuals.
533         return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
534           .Case("0x926", "arm926ej-s")
535           .Case("0xb02", "mpcore")
536           .Case("0xb36", "arm1136j-s")
537           .Case("0xb56", "arm1156t2-s")
538           .Case("0xb76", "arm1176jz-s")
539           .Case("0xc08", "cortex-a8")
540           .Case("0xc09", "cortex-a9")
541           .Case("0xc0f", "cortex-a15")
542           .Case("0xc20", "cortex-m0")
543           .Case("0xc23", "cortex-m3")
544           .Case("0xc24", "cortex-m4")
545           .Default("generic");
546
547   return "generic";
548 }
549 #else
550 std::string sys::getHostCPUName() {
551   return "generic";
552 }
553 #endif
554
555 #if defined(__linux__) && defined(__arm__)
556 bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
557   std::string Err;
558   DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
559   if (!DS) {
560     DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
561     return false;
562   }
563
564   // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
565   // in all cases.
566   char buffer[1024];
567   size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
568   delete DS;
569
570   StringRef Str(buffer, CPUInfoSize);
571
572   SmallVector<StringRef, 32> Lines;
573   Str.split(Lines, "\n");
574
575   SmallVector<StringRef, 32> CPUFeatures;
576
577   // Look for the CPU features.
578   for (unsigned I = 0, E = Lines.size(); I != E; ++I)
579     if (Lines[I].startswith("Features")) {
580       Lines[I].split(CPUFeatures, " ");
581       break;
582     }
583
584   for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
585     StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
586       .Case("half", "fp16")
587       .Case("neon", "neon")
588       .Case("vfpv3", "vfp3")
589       .Case("vfpv3d16", "d16")
590       .Case("vfpv4", "vfp4")
591       .Case("idiva", "hwdiv-arm")
592       .Case("idivt", "hwdiv")
593       .Default("");
594
595     if (LLVMFeatureStr != "")
596       Features.GetOrCreateValue(LLVMFeatureStr).setValue(true);
597   }
598
599   return true;
600 }
601 #else
602 bool sys::getHostCPUFeatures(StringMap<bool> &Features){
603   return false;
604 }
605 #endif
606
607 std::string sys::getProcessTriple() {
608   Triple PT(Triple::normalize(LLVM_HOST_TRIPLE));
609
610   if (sizeof(void *) == 8 && PT.isArch32Bit())
611     PT = PT.get64BitArchVariant();
612   if (sizeof(void *) == 4 && PT.isArch64Bit())
613     PT = PT.get32BitArchVariant();
614
615   return PT.str();
616 }