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 |