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_POSIX | 10 #if V8_OS_POSIX |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 break; | 108 break; |
109 } | 109 } |
110 } | 110 } |
111 fclose(fp); | 111 fclose(fp); |
112 } | 112 } |
113 return result; | 113 return result; |
114 } | 114 } |
115 | 115 |
116 #endif // V8_HOST_ARCH_ARM | 116 #endif // V8_HOST_ARCH_ARM |
117 | 117 |
| 118 #if V8_HOST_ARCH_MIPS |
| 119 int __detect_fp64_mode(void) { |
| 120 double result = 0; |
| 121 // Bit representation of (double)1 is 0x3FF0000000000000. |
| 122 asm( |
| 123 "lui $t0, 0x3FF0\n\t" |
| 124 "ldc1 $f0, %0\n\t" |
| 125 "mtc1 $t0, $f1\n\t" |
| 126 "sdc1 $f0, %0\n\t" |
| 127 : "+m" (result) |
| 128 : : "t0", "$f0", "$f1", "memory"); |
| 129 |
| 130 return !(result == 1); |
| 131 } |
| 132 |
| 133 |
| 134 int __detect_mips_arch_revision(void) { |
| 135 // TODO(dusmil): Do the specific syscall as soon as it is implemented in mips |
| 136 // kernel. Currently fail-back to the least common denominator which is |
| 137 // mips32 revision 1. |
| 138 return 1; |
| 139 } |
| 140 #endif |
| 141 |
118 // Extract the information exposed by the kernel via /proc/cpuinfo. | 142 // Extract the information exposed by the kernel via /proc/cpuinfo. |
119 class CPUInfo V8_FINAL { | 143 class CPUInfo V8_FINAL { |
120 public: | 144 public: |
121 CPUInfo() : datalen_(0) { | 145 CPUInfo() : datalen_(0) { |
122 // Get the size of the cpuinfo file by reading it until the end. This is | 146 // Get the size of the cpuinfo file by reading it until the end. This is |
123 // required because files under /proc do not always return a valid size | 147 // required because files under /proc do not always return a valid size |
124 // when using fseek(0, SEEK_END) + ftell(). Nor can the be mmap()-ed. | 148 // when using fseek(0, SEEK_END) + ftell(). Nor can the be mmap()-ed. |
125 static const char PATHNAME[] = "/proc/cpuinfo"; | 149 static const char PATHNAME[] = "/proc/cpuinfo"; |
126 FILE* fp = fopen(PATHNAME, "r"); | 150 FILE* fp = fopen(PATHNAME, "r"); |
127 if (fp != NULL) { | 151 if (fp != NULL) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 has_sse2_(false), | 280 has_sse2_(false), |
257 has_sse3_(false), | 281 has_sse3_(false), |
258 has_ssse3_(false), | 282 has_ssse3_(false), |
259 has_sse41_(false), | 283 has_sse41_(false), |
260 has_sse42_(false), | 284 has_sse42_(false), |
261 has_idiva_(false), | 285 has_idiva_(false), |
262 has_neon_(false), | 286 has_neon_(false), |
263 has_thumb2_(false), | 287 has_thumb2_(false), |
264 has_vfp_(false), | 288 has_vfp_(false), |
265 has_vfp3_(false), | 289 has_vfp3_(false), |
266 has_vfp3_d32_(false) { | 290 has_vfp3_d32_(false), |
| 291 is_fp64_mode_(false) { |
267 memcpy(vendor_, "Unknown", 8); | 292 memcpy(vendor_, "Unknown", 8); |
268 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | 293 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
269 int cpu_info[4]; | 294 int cpu_info[4]; |
270 | 295 |
271 // __cpuid with an InfoType argument of 0 returns the number of | 296 // __cpuid with an InfoType argument of 0 returns the number of |
272 // valid Ids in CPUInfo[0] and the CPU identification string in | 297 // valid Ids in CPUInfo[0] and the CPU identification string in |
273 // the other three array elements. The CPU identification string is | 298 // the other three array elements. The CPU identification string is |
274 // not in linear order. The code below arranges the information | 299 // not in linear order. The code below arranges the information |
275 // in a human readable form. The human readable order is CPUInfo[1] | | 300 // in a human readable form. The human readable order is CPUInfo[1] | |
276 // CPUInfo[3] | CPUInfo[2]. CPUInfo[2] and CPUInfo[3] are swapped | 301 // CPUInfo[3] | CPUInfo[2]. CPUInfo[2] and CPUInfo[3] are swapped |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 | 484 |
460 // Simple detection of FPU at runtime for Linux. | 485 // Simple detection of FPU at runtime for Linux. |
461 // It is based on /proc/cpuinfo, which reveals hardware configuration | 486 // It is based on /proc/cpuinfo, which reveals hardware configuration |
462 // to user-space applications. According to MIPS (early 2010), no similar | 487 // to user-space applications. According to MIPS (early 2010), no similar |
463 // facility is universally available on the MIPS architectures, | 488 // facility is universally available on the MIPS architectures, |
464 // so it's up to individual OSes to provide such. | 489 // so it's up to individual OSes to provide such. |
465 CPUInfo cpu_info; | 490 CPUInfo cpu_info; |
466 char* cpu_model = cpu_info.ExtractField("cpu model"); | 491 char* cpu_model = cpu_info.ExtractField("cpu model"); |
467 has_fpu_ = HasListItem(cpu_model, "FPU"); | 492 has_fpu_ = HasListItem(cpu_model, "FPU"); |
468 delete[] cpu_model; | 493 delete[] cpu_model; |
| 494 #ifdef V8_HOST_ARCH_MIPS |
| 495 is_fp64_mode_ = __detect_fp64_mode(); |
| 496 architecture_ = __detect_mips_arch_revision(); |
| 497 #endif |
469 | 498 |
470 #elif V8_HOST_ARCH_ARM64 | 499 #elif V8_HOST_ARCH_ARM64 |
471 | 500 |
472 CPUInfo cpu_info; | 501 CPUInfo cpu_info; |
473 | 502 |
474 // Extract implementor from the "CPU implementer" field. | 503 // Extract implementor from the "CPU implementer" field. |
475 char* implementer = cpu_info.ExtractField("CPU implementer"); | 504 char* implementer = cpu_info.ExtractField("CPU implementer"); |
476 if (implementer != NULL) { | 505 if (implementer != NULL) { |
477 char* end ; | 506 char* end ; |
478 implementer_ = strtol(implementer, &end, 0); | 507 implementer_ = strtol(implementer, &end, 0); |
(...skipping 11 matching lines...) Expand all Loading... |
490 if (end == part) { | 519 if (end == part) { |
491 part_ = 0; | 520 part_ = 0; |
492 } | 521 } |
493 delete[] part; | 522 delete[] part; |
494 } | 523 } |
495 | 524 |
496 #endif | 525 #endif |
497 } | 526 } |
498 | 527 |
499 } } // namespace v8::base | 528 } } // namespace v8::base |
OLD | NEW |