Chromium Code Reviews| 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/cpu.h" | 5 #include "src/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_POSIX | 10 #if V8_OS_POSIX |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 has_sahf_(false), | 252 has_sahf_(false), |
| 253 has_mmx_(false), | 253 has_mmx_(false), |
| 254 has_sse_(false), | 254 has_sse_(false), |
| 255 has_sse2_(false), | 255 has_sse2_(false), |
| 256 has_sse3_(false), | 256 has_sse3_(false), |
| 257 has_ssse3_(false), | 257 has_ssse3_(false), |
| 258 has_sse41_(false), | 258 has_sse41_(false), |
| 259 has_sse42_(false), | 259 has_sse42_(false), |
| 260 has_idiva_(false), | 260 has_idiva_(false), |
| 261 has_neon_(false), | 261 has_neon_(false), |
| 262 has_thumbee_(false), | 262 has_thumb2_(false), |
| 263 has_vfp_(false), | 263 has_vfp_(false), |
| 264 has_vfp3_(false), | 264 has_vfp3_(false), |
| 265 has_vfp3_d32_(false) { | 265 has_vfp3_d32_(false) { |
| 266 memcpy(vendor_, "Unknown", 8); | 266 memcpy(vendor_, "Unknown", 8); |
| 267 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | 267 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
| 268 int cpu_info[4]; | 268 int cpu_info[4]; |
| 269 | 269 |
| 270 // __cpuid with an InfoType argument of 0 returns the number of | 270 // __cpuid with an InfoType argument of 0 returns the number of |
| 271 // valid Ids in CPUInfo[0] and the CPU identification string in | 271 // valid Ids in CPUInfo[0] and the CPU identification string in |
| 272 // the other three array elements. The CPU identification string is | 272 // the other three array elements. The CPU identification string is |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 } | 376 } |
| 377 delete[] processor; | 377 delete[] processor; |
| 378 } | 378 } |
| 379 } | 379 } |
| 380 | 380 |
| 381 // Try to extract the list of CPU features from ELF hwcaps. | 381 // Try to extract the list of CPU features from ELF hwcaps. |
| 382 uint32_t hwcaps = ReadELFHWCaps(); | 382 uint32_t hwcaps = ReadELFHWCaps(); |
| 383 if (hwcaps != 0) { | 383 if (hwcaps != 0) { |
| 384 has_idiva_ = (hwcaps & HWCAP_IDIVA) != 0; | 384 has_idiva_ = (hwcaps & HWCAP_IDIVA) != 0; |
| 385 has_neon_ = (hwcaps & HWCAP_NEON) != 0; | 385 has_neon_ = (hwcaps & HWCAP_NEON) != 0; |
| 386 has_thumbee_ = (hwcaps & HWCAP_THUMBEE) != 0; | |
| 387 has_vfp_ = (hwcaps & HWCAP_VFP) != 0; | 386 has_vfp_ = (hwcaps & HWCAP_VFP) != 0; |
| 388 has_vfp3_ = (hwcaps & (HWCAP_VFPv3 | HWCAP_VFPv3D16 | HWCAP_VFPv4)) != 0; | 387 has_vfp3_ = (hwcaps & (HWCAP_VFPv3 | HWCAP_VFPv3D16 | HWCAP_VFPv4)) != 0; |
| 389 has_vfp3_d32_ = (has_vfp3_ && ((hwcaps & HWCAP_VFPv3D16) == 0 || | 388 has_vfp3_d32_ = (has_vfp3_ && ((hwcaps & HWCAP_VFPv3D16) == 0 || |
| 390 (hwcaps & HWCAP_VFPD32) != 0)); | 389 (hwcaps & HWCAP_VFPD32) != 0)); |
| 391 } else { | 390 } else { |
| 392 // Try to fallback to "Features" CPUInfo field. | 391 // Try to fallback to "Features" CPUInfo field. |
| 393 char* features = cpu_info.ExtractField("Features"); | 392 char* features = cpu_info.ExtractField("Features"); |
| 394 has_idiva_ = HasListItem(features, "idiva"); | 393 has_idiva_ = HasListItem(features, "idiva"); |
| 395 has_neon_ = HasListItem(features, "neon"); | 394 has_neon_ = HasListItem(features, "neon"); |
| 396 has_thumbee_ = HasListItem(features, "thumbee"); | 395 has_thumb2_ = HasListItem(features, "thumb2"); |
|
Rodolph Perfetta
2014/06/13 10:38:23
thumb2 doesn't get reported as such in cpuinfo:
*
Sven Panne
2014/06/13 10:49:57
This was proposed by Benedikt. We can simplify thi
| |
| 397 has_vfp_ = HasListItem(features, "vfp"); | 396 has_vfp_ = HasListItem(features, "vfp"); |
| 398 if (HasListItem(features, "vfpv3d16")) { | 397 if (HasListItem(features, "vfpv3d16")) { |
| 399 has_vfp3_ = true; | 398 has_vfp3_ = true; |
| 400 } else if (HasListItem(features, "vfpv3")) { | 399 } else if (HasListItem(features, "vfpv3")) { |
| 401 has_vfp3_ = true; | 400 has_vfp3_ = true; |
| 402 has_vfp3_d32_ = true; | 401 has_vfp3_d32_ = true; |
| 403 } | 402 } |
| 404 delete[] features; | 403 delete[] features; |
| 405 } | 404 } |
| 406 | 405 |
| 407 // Some old kernels will report vfp not vfpv3. Here we make an attempt | 406 // Some old kernels will report vfp not vfpv3. Here we make an attempt |
| 408 // to detect vfpv3 by checking for vfp *and* neon, since neon is only | 407 // to detect vfpv3 by checking for vfp *and* neon, since neon is only |
| 409 // available on architectures with vfpv3. Checking neon on its own is | 408 // available on architectures with vfpv3. Checking neon on its own is |
| 410 // not enough as it is possible to have neon without vfp. | 409 // not enough as it is possible to have neon without vfp. |
| 411 if (has_vfp_ && has_neon_) { | 410 if (has_vfp_ && has_neon_) { |
| 412 has_vfp3_ = true; | 411 has_vfp3_ = true; |
| 413 } | 412 } |
| 414 | 413 |
| 415 // VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. | 414 // VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. |
| 416 if (architecture_ < 7 && has_vfp3_) { | 415 if (architecture_ < 7 && has_vfp3_) { |
| 417 architecture_ = 7; | 416 architecture_ = 7; |
| 418 } | 417 } |
| 419 | 418 |
| 420 // ARMv7 implies ThumbEE. | 419 // ARMv7 implies Thumb2. |
| 421 if (architecture_ >= 7) { | 420 if (architecture_ >= 7) { |
| 422 has_thumbee_ = true; | 421 has_thumb2_ = true; |
| 423 } | 422 } |
| 424 | 423 |
| 425 // The earliest architecture with ThumbEE is ARMv6T2. | 424 // The earliest architecture with Thumb2 is ARMv6T2. |
| 426 if (has_thumbee_ && architecture_ < 6) { | 425 if (has_thumb2_ && architecture_ < 6) { |
| 427 architecture_ = 6; | 426 architecture_ = 6; |
| 428 } | 427 } |
| 429 | 428 |
| 430 // We don't support any FPUs other than VFP. | 429 // We don't support any FPUs other than VFP. |
| 431 has_fpu_ = has_vfp_; | 430 has_fpu_ = has_vfp_; |
| 432 | 431 |
| 433 #elif V8_OS_QNX | 432 #elif V8_OS_QNX |
| 434 | 433 |
| 435 uint32_t cpu_flags = SYSPAGE_ENTRY(cpuinfo)->flags; | 434 uint32_t cpu_flags = SYSPAGE_ENTRY(cpuinfo)->flags; |
| 436 if (cpu_flags & ARM_CPU_FLAG_V7) { | 435 if (cpu_flags & ARM_CPU_FLAG_V7) { |
| 437 architecture_ = 7; | 436 architecture_ = 7; |
| 438 has_thumbee_ = true; | 437 has_thumb2_ = true; |
| 439 } else if (cpu_flags & ARM_CPU_FLAG_V6) { | 438 } else if (cpu_flags & ARM_CPU_FLAG_V6) { |
| 440 architecture_ = 6; | 439 architecture_ = 6; |
| 441 // QNX doesn't say if ThumbEE is available. | 440 // QNX doesn't say if Thumb2 is available. |
| 442 // Assume false for the architectures older than ARMv7. | 441 // Assume false for the architectures older than ARMv7. |
| 443 } | 442 } |
| 444 ASSERT(architecture_ >= 6); | 443 ASSERT(architecture_ >= 6); |
| 445 has_fpu_ = (cpu_flags & CPU_FLAG_FPU) != 0; | 444 has_fpu_ = (cpu_flags & CPU_FLAG_FPU) != 0; |
| 446 has_vfp_ = has_fpu_; | 445 has_vfp_ = has_fpu_; |
| 447 if (cpu_flags & ARM_CPU_FLAG_NEON) { | 446 if (cpu_flags & ARM_CPU_FLAG_NEON) { |
| 448 has_neon_ = true; | 447 has_neon_ = true; |
| 449 has_vfp3_ = has_vfp_; | 448 has_vfp3_ = has_vfp_; |
| 450 #ifdef ARM_CPU_FLAG_VFP_D32 | 449 #ifdef ARM_CPU_FLAG_VFP_D32 |
| 451 has_vfp3_d32_ = (cpu_flags & ARM_CPU_FLAG_VFP_D32) != 0; | 450 has_vfp3_d32_ = (cpu_flags & ARM_CPU_FLAG_VFP_D32) != 0; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 if (end == part) { | 489 if (end == part) { |
| 491 part_ = 0; | 490 part_ = 0; |
| 492 } | 491 } |
| 493 delete[] part; | 492 delete[] part; |
| 494 } | 493 } |
| 495 | 494 |
| 496 #endif | 495 #endif |
| 497 } | 496 } |
| 498 | 497 |
| 499 } } // namespace v8::internal | 498 } } // namespace v8::internal |
| OLD | NEW |