| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/base/cpu.h" | 5 #include "src/base/cpu.h" |
| 6 | 6 |
| 7 #if V8_LIBC_MSVCRT | 7 #if V8_LIBC_MSVCRT |
| 8 #include <intrin.h> // __cpuid() | 8 #include <intrin.h> // __cpuid() |
| 9 #endif | 9 #endif |
| 10 #if V8_OS_LINUX | 10 #if V8_OS_LINUX |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 namespace base { | 45 namespace base { |
| 46 | 46 |
| 47 #if defined(__pnacl__) | 47 #if defined(__pnacl__) |
| 48 // Portable host shouldn't do feature detection. | 48 // Portable host shouldn't do feature detection. |
| 49 #elif V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | 49 #elif V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
| 50 | 50 |
| 51 // Define __cpuid() for non-MSVC libraries. | 51 // Define __cpuid() for non-MSVC libraries. |
| 52 #if !V8_LIBC_MSVCRT | 52 #if !V8_LIBC_MSVCRT |
| 53 | 53 |
| 54 static V8_INLINE void __cpuid(int cpu_info[4], int info_type) { | 54 static V8_INLINE void __cpuid(int cpu_info[4], int info_type) { |
| 55 // Clear ecx to align with __cpuid() of MSVC: |
| 56 // https://msdn.microsoft.com/en-us/library/hskdteyh.aspx |
| 55 #if defined(__i386__) && defined(__pic__) | 57 #if defined(__i386__) && defined(__pic__) |
| 56 // Make sure to preserve ebx, which contains the pointer | 58 // Make sure to preserve ebx, which contains the pointer |
| 57 // to the GOT in case we're generating PIC. | 59 // to the GOT in case we're generating PIC. |
| 58 __asm__ volatile ( | 60 __asm__ volatile( |
| 59 "mov %%ebx, %%edi\n\t" | 61 "mov %%ebx, %%edi\n\t" |
| 60 "cpuid\n\t" | 62 "cpuid\n\t" |
| 61 "xchg %%edi, %%ebx\n\t" | 63 "xchg %%edi, %%ebx\n\t" |
| 62 : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) | 64 : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), |
| 63 : "a"(info_type) | 65 "=d"(cpu_info[3]) |
| 64 ); | 66 : "a"(info_type), "c"(0)); |
| 65 #else | 67 #else |
| 66 __asm__ volatile ( | 68 __asm__ volatile("cpuid \n\t" |
| 67 "cpuid \n\t" | 69 : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), |
| 68 : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) | 70 "=d"(cpu_info[3]) |
| 69 : "a"(info_type) | 71 : "a"(info_type), "c"(0)); |
| 70 ); | |
| 71 #endif // defined(__i386__) && defined(__pic__) | 72 #endif // defined(__i386__) && defined(__pic__) |
| 72 } | 73 } |
| 73 | 74 |
| 74 #endif // !V8_LIBC_MSVCRT | 75 #endif // !V8_LIBC_MSVCRT |
| 75 | 76 |
| 76 #elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64 \ | 77 #elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64 \ |
| 77 || V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64 | 78 || V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64 |
| 78 | 79 |
| 79 #if V8_OS_LINUX | 80 #if V8_OS_LINUX |
| 80 | 81 |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 has_sse_(false), | 319 has_sse_(false), |
| 319 has_sse2_(false), | 320 has_sse2_(false), |
| 320 has_sse3_(false), | 321 has_sse3_(false), |
| 321 has_ssse3_(false), | 322 has_ssse3_(false), |
| 322 has_sse41_(false), | 323 has_sse41_(false), |
| 323 has_sse42_(false), | 324 has_sse42_(false), |
| 324 is_atom_(false), | 325 is_atom_(false), |
| 325 has_osxsave_(false), | 326 has_osxsave_(false), |
| 326 has_avx_(false), | 327 has_avx_(false), |
| 327 has_fma3_(false), | 328 has_fma3_(false), |
| 329 has_bmi1_(false), |
| 330 has_bmi2_(false), |
| 331 has_lzcnt_(false), |
| 332 has_popcnt_(false), |
| 328 has_idiva_(false), | 333 has_idiva_(false), |
| 329 has_neon_(false), | 334 has_neon_(false), |
| 330 has_thumb2_(false), | 335 has_thumb2_(false), |
| 331 has_vfp_(false), | 336 has_vfp_(false), |
| 332 has_vfp3_(false), | 337 has_vfp3_(false), |
| 333 has_vfp3_d32_(false), | 338 has_vfp3_d32_(false), |
| 334 is_fp64_mode_(false) { | 339 is_fp64_mode_(false) { |
| 335 memcpy(vendor_, "Unknown", 8); | 340 memcpy(vendor_, "Unknown", 8); |
| 336 #if V8_OS_NACL | 341 #if V8_OS_NACL |
| 337 // Portable host shouldn't do feature detection. | 342 // Portable host shouldn't do feature detection. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 364 ext_family_ = (cpu_info[0] >> 20) & 0xff; | 369 ext_family_ = (cpu_info[0] >> 20) & 0xff; |
| 365 has_fpu_ = (cpu_info[3] & 0x00000001) != 0; | 370 has_fpu_ = (cpu_info[3] & 0x00000001) != 0; |
| 366 has_cmov_ = (cpu_info[3] & 0x00008000) != 0; | 371 has_cmov_ = (cpu_info[3] & 0x00008000) != 0; |
| 367 has_mmx_ = (cpu_info[3] & 0x00800000) != 0; | 372 has_mmx_ = (cpu_info[3] & 0x00800000) != 0; |
| 368 has_sse_ = (cpu_info[3] & 0x02000000) != 0; | 373 has_sse_ = (cpu_info[3] & 0x02000000) != 0; |
| 369 has_sse2_ = (cpu_info[3] & 0x04000000) != 0; | 374 has_sse2_ = (cpu_info[3] & 0x04000000) != 0; |
| 370 has_sse3_ = (cpu_info[2] & 0x00000001) != 0; | 375 has_sse3_ = (cpu_info[2] & 0x00000001) != 0; |
| 371 has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; | 376 has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; |
| 372 has_sse41_ = (cpu_info[2] & 0x00080000) != 0; | 377 has_sse41_ = (cpu_info[2] & 0x00080000) != 0; |
| 373 has_sse42_ = (cpu_info[2] & 0x00100000) != 0; | 378 has_sse42_ = (cpu_info[2] & 0x00100000) != 0; |
| 379 has_popcnt_ = (cpu_info[2] & 0x00800000) != 0; |
| 374 has_osxsave_ = (cpu_info[2] & 0x08000000) != 0; | 380 has_osxsave_ = (cpu_info[2] & 0x08000000) != 0; |
| 375 has_avx_ = (cpu_info[2] & 0x10000000) != 0; | 381 has_avx_ = (cpu_info[2] & 0x10000000) != 0; |
| 376 has_fma3_ = (cpu_info[2] & 0x00001000) != 0; | 382 has_fma3_ = (cpu_info[2] & 0x00001000) != 0; |
| 377 | 383 |
| 378 if (family_ == 0x6) { | 384 if (family_ == 0x6) { |
| 379 switch (model_) { | 385 switch (model_) { |
| 380 case 0x1c: // SLT | 386 case 0x1c: // SLT |
| 381 case 0x26: | 387 case 0x26: |
| 382 case 0x36: | 388 case 0x36: |
| 383 case 0x27: | 389 case 0x27: |
| 384 case 0x35: | 390 case 0x35: |
| 385 case 0x37: // SLM | 391 case 0x37: // SLM |
| 386 case 0x4a: | 392 case 0x4a: |
| 387 case 0x4d: | 393 case 0x4d: |
| 388 case 0x4c: // AMT | 394 case 0x4c: // AMT |
| 389 case 0x6e: | 395 case 0x6e: |
| 390 is_atom_ = true; | 396 is_atom_ = true; |
| 391 } | 397 } |
| 392 } | 398 } |
| 393 } | 399 } |
| 394 | 400 |
| 395 #if V8_HOST_ARCH_IA32 | 401 // There are separate feature flags for VEX-encoded GPR instructions. |
| 396 // SAHF is always available in compat/legacy mode, | 402 if (num_ids >= 7) { |
| 397 has_sahf_ = true; | 403 __cpuid(cpu_info, 7); |
| 398 #else | 404 has_bmi1_ = (cpu_info[1] & 0x00000008) != 0; |
| 405 has_bmi2_ = (cpu_info[1] & 0x00000100) != 0; |
| 406 } |
| 407 |
| 399 // Query extended IDs. | 408 // Query extended IDs. |
| 400 __cpuid(cpu_info, 0x80000000); | 409 __cpuid(cpu_info, 0x80000000); |
| 401 unsigned num_ext_ids = cpu_info[0]; | 410 unsigned num_ext_ids = cpu_info[0]; |
| 402 | 411 |
| 403 // Interpret extended CPU feature information. | 412 // Interpret extended CPU feature information. |
| 404 if (num_ext_ids > 0x80000000) { | 413 if (num_ext_ids > 0x80000000) { |
| 405 __cpuid(cpu_info, 0x80000001); | 414 __cpuid(cpu_info, 0x80000001); |
| 415 has_lzcnt_ = (cpu_info[2] & 0x00000020) != 0; |
| 406 // SAHF must be probed in long mode. | 416 // SAHF must be probed in long mode. |
| 407 has_sahf_ = (cpu_info[2] & 0x00000001) != 0; | 417 has_sahf_ = (cpu_info[2] & 0x00000001) != 0; |
| 408 } | 418 } |
| 409 #endif | |
| 410 | 419 |
| 411 #elif V8_HOST_ARCH_ARM | 420 #elif V8_HOST_ARCH_ARM |
| 412 | 421 |
| 413 #if V8_OS_LINUX | 422 #if V8_OS_LINUX |
| 414 | 423 |
| 415 CPUInfo cpu_info; | 424 CPUInfo cpu_info; |
| 416 | 425 |
| 417 // Extract implementor from the "CPU implementer" field. | 426 // Extract implementor from the "CPU implementer" field. |
| 418 char* implementer = cpu_info.ExtractField("CPU implementer"); | 427 char* implementer = cpu_info.ExtractField("CPU implementer"); |
| 419 if (implementer != NULL) { | 428 if (implementer != NULL) { |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 case POWER_5: | 685 case POWER_5: |
| 677 part_ = PPC_POWER5; | 686 part_ = PPC_POWER5; |
| 678 break; | 687 break; |
| 679 } | 688 } |
| 680 #endif // V8_OS_AIX | 689 #endif // V8_OS_AIX |
| 681 #endif // !USE_SIMULATOR | 690 #endif // !USE_SIMULATOR |
| 682 #endif // V8_HOST_ARCH_PPC | 691 #endif // V8_HOST_ARCH_PPC |
| 683 } | 692 } |
| 684 | 693 |
| 685 } } // namespace v8::base | 694 } } // namespace v8::base |
| OLD | NEW |