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