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 } 617