212 }; 213 214 union XemXcr0Eax { 215 uint32_t value; 216 struct { 217 uint32_t x87 : 1, 218 sse : 1, 219 ymm : 1, 220 : 29; 221 } bits; 222 }; 223 224 protected: 225 static int _cpu; 226 static int _model; 227 static int _stepping; 228 static int _cpuFeatures; // features returned by the "cpuid" instruction 229 // 0 if this instruction is not available 230 static const char* _features_str; 231 232 enum { 233 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) 234 CPU_CMOV = (1 << 1), 235 CPU_FXSR = (1 << 2), 236 CPU_HT = (1 << 3), 237 CPU_MMX = (1 << 4), 238 CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions 239 // may not necessarily support other 3dnow instructions 240 CPU_SSE = (1 << 6), 241 CPU_SSE2 = (1 << 7), 242 CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX) 243 CPU_SSSE3 = (1 << 9), 244 CPU_SSE4A = (1 << 10), 245 CPU_SSE4_1 = (1 << 11), 246 CPU_SSE4_2 = (1 << 12), 247 CPU_POPCNT = (1 << 13), 248 CPU_LZCNT = (1 << 14), 249 CPU_TSC = (1 << 15), 250 CPU_TSCINV = (1 << 16), 251 CPU_AVX = (1 << 17), 344 uint32_t ext_cpuid5_eax; // unused currently 345 uint32_t ext_cpuid5_ebx; // reserved 346 ExtCpuid5Ex ext_cpuid5_ecx; // L1 data cache info (AMD) 347 ExtCpuid5Ex ext_cpuid5_edx; // L1 instruction cache info (AMD) 348 349 // cpuid function 0x80000007 350 uint32_t ext_cpuid7_eax; // reserved 351 uint32_t ext_cpuid7_ebx; // reserved 352 uint32_t ext_cpuid7_ecx; // reserved 353 ExtCpuid7Edx ext_cpuid7_edx; // tscinv 354 355 // cpuid function 0x80000008 356 uint32_t ext_cpuid8_eax; // unused currently 357 uint32_t ext_cpuid8_ebx; // reserved 358 ExtCpuid8Ecx ext_cpuid8_ecx; 359 uint32_t ext_cpuid8_edx; // reserved 360 361 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register) 362 XemXcr0Eax xem_xcr0_eax; 363 uint32_t xem_xcr0_edx; // reserved 364 }; 365 366 // The actual cpuid info block 367 static CpuidInfo _cpuid_info; 368 369 // Extractors and predicates 370 static uint32_t extended_cpu_family() { 371 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.family; 372 result += _cpuid_info.std_cpuid1_eax.bits.ext_family; 373 return result; 374 } 375 376 static uint32_t extended_cpu_model() { 377 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.model; 378 result |= _cpuid_info.std_cpuid1_eax.bits.ext_model << 4; 379 return result; 380 } 381 382 static uint32_t cpu_stepping() { 383 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.stepping; 443 if (is_amd()) { 444 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) || 445 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0)) 446 result |= CPU_3DNOW_PREFETCH; 447 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) 448 result |= CPU_LZCNT; 449 if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0) 450 result |= CPU_SSE4A; 451 } 452 // Intel features. 453 if(is_intel()) { 454 if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0) 455 result |= CPU_BMI2; 456 if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) 457 result |= CPU_LZCNT; 458 } 459 460 return result; 461 } 462 463 static void get_processor_features(); 464 465 public: 466 // Offsets for cpuid asm stub 467 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); } 468 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); } 469 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } 470 static ByteSize sef_cpuid7_offset() { return byte_offset_of(CpuidInfo, sef_cpuid7_eax); } 471 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } 472 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } 473 static ByteSize ext_cpuid7_offset() { return byte_offset_of(CpuidInfo, ext_cpuid7_eax); } 474 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } 475 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } 476 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } 477 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } 478 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } 479 480 // Initialization 481 static void initialize(); 482 483 // Asserts 484 static void assert_is_initialized() { 485 assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized"); 486 } 487 488 // 489 // Processor family: 490 // 3 - 386 491 // 4 - 486 492 // 5 - Pentium 493 // 6 - PentiumPro, Pentium II, Celeron, Xeon, Pentium III, Athlon, 494 // Pentium M, Core Solo, Core Duo, Core2 Duo 495 // family 6 model: 9, 13, 14, 15 496 // 0x0f - Pentium 4, Opteron 497 // 498 // Note: The cpu family should be used to select between | 212 }; 213 214 union XemXcr0Eax { 215 uint32_t value; 216 struct { 217 uint32_t x87 : 1, 218 sse : 1, 219 ymm : 1, 220 : 29; 221 } bits; 222 }; 223 224 protected: 225 static int _cpu; 226 static int _model; 227 static int _stepping; 228 static int _cpuFeatures; // features returned by the "cpuid" instruction 229 // 0 if this instruction is not available 230 static const char* _features_str; 231 232 static address _cpuinfo_segv_addr; // address of instruction which causes SEGV 233 static address _cpuinfo_cont_addr; // address of instruction after SEGV processed 234 235 enum { 236 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) 237 CPU_CMOV = (1 << 1), 238 CPU_FXSR = (1 << 2), 239 CPU_HT = (1 << 3), 240 CPU_MMX = (1 << 4), 241 CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions 242 // may not necessarily support other 3dnow instructions 243 CPU_SSE = (1 << 6), 244 CPU_SSE2 = (1 << 7), 245 CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX) 246 CPU_SSSE3 = (1 << 9), 247 CPU_SSE4A = (1 << 10), 248 CPU_SSE4_1 = (1 << 11), 249 CPU_SSE4_2 = (1 << 12), 250 CPU_POPCNT = (1 << 13), 251 CPU_LZCNT = (1 << 14), 252 CPU_TSC = (1 << 15), 253 CPU_TSCINV = (1 << 16), 254 CPU_AVX = (1 << 17), 347 uint32_t ext_cpuid5_eax; // unused currently 348 uint32_t ext_cpuid5_ebx; // reserved 349 ExtCpuid5Ex ext_cpuid5_ecx; // L1 data cache info (AMD) 350 ExtCpuid5Ex ext_cpuid5_edx; // L1 instruction cache info (AMD) 351 352 // cpuid function 0x80000007 353 uint32_t ext_cpuid7_eax; // reserved 354 uint32_t ext_cpuid7_ebx; // reserved 355 uint32_t ext_cpuid7_ecx; // reserved 356 ExtCpuid7Edx ext_cpuid7_edx; // tscinv 357 358 // cpuid function 0x80000008 359 uint32_t ext_cpuid8_eax; // unused currently 360 uint32_t ext_cpuid8_ebx; // reserved 361 ExtCpuid8Ecx ext_cpuid8_ecx; 362 uint32_t ext_cpuid8_edx; // reserved 363 364 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register) 365 XemXcr0Eax xem_xcr0_eax; 366 uint32_t xem_xcr0_edx; // reserved 367 368 // Space to save ymm registers after signal handle 369 int ymm_save[8*4]; // Save ymm0, ymm7, ymm8, ymm15 370 }; 371 372 // The actual cpuid info block 373 static CpuidInfo _cpuid_info; 374 375 // Extractors and predicates 376 static uint32_t extended_cpu_family() { 377 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.family; 378 result += _cpuid_info.std_cpuid1_eax.bits.ext_family; 379 return result; 380 } 381 382 static uint32_t extended_cpu_model() { 383 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.model; 384 result |= _cpuid_info.std_cpuid1_eax.bits.ext_model << 4; 385 return result; 386 } 387 388 static uint32_t cpu_stepping() { 389 uint32_t result = _cpuid_info.std_cpuid1_eax.bits.stepping; 449 if (is_amd()) { 450 if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) || 451 (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0)) 452 result |= CPU_3DNOW_PREFETCH; 453 if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) 454 result |= CPU_LZCNT; 455 if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0) 456 result |= CPU_SSE4A; 457 } 458 // Intel features. 459 if(is_intel()) { 460 if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0) 461 result |= CPU_BMI2; 462 if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) 463 result |= CPU_LZCNT; 464 } 465 466 return result; 467 } 468 469 static bool os_supports_avx_vectors() { 470 if (!supports_avx()) { 471 return false; 472 } 473 int nreg = 2 LP64_ONLY(+2); 474 for (int i = 0; i < 8 * nreg; i++) { // 32 bytes 4 ymm registers 475 if (_cpuid_info.ymm_save[i] != ymm_test_value()) { 476 return false; 477 } 478 } 479 return true; 480 } 481 482 static void get_processor_features(); 483 484 public: 485 // Offsets for cpuid asm stub 486 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); } 487 static ByteSize std_cpuid1_offset() { return byte_offset_of(CpuidInfo, std_cpuid1_eax); } 488 static ByteSize dcp_cpuid4_offset() { return byte_offset_of(CpuidInfo, dcp_cpuid4_eax); } 489 static ByteSize sef_cpuid7_offset() { return byte_offset_of(CpuidInfo, sef_cpuid7_eax); } 490 static ByteSize ext_cpuid1_offset() { return byte_offset_of(CpuidInfo, ext_cpuid1_eax); } 491 static ByteSize ext_cpuid5_offset() { return byte_offset_of(CpuidInfo, ext_cpuid5_eax); } 492 static ByteSize ext_cpuid7_offset() { return byte_offset_of(CpuidInfo, ext_cpuid7_eax); } 493 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } 494 static ByteSize tpl_cpuidB0_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB0_eax); } 495 static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); } 496 static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); } 497 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } 498 static ByteSize ymm_save_offset() { return byte_offset_of(CpuidInfo, ymm_save); } 499 500 // The value used to check ymm register after signal handle 501 static int ymm_test_value() { return 0xCAFEBABE; } 502 503 static void set_cpuinfo_segv_addr(address pc) { _cpuinfo_segv_addr = pc; } 504 static bool is_cpuinfo_segv_addr(address pc) { return _cpuinfo_segv_addr == pc; } 505 static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; } 506 static address cpuinfo_cont_addr() { return _cpuinfo_cont_addr; } 507 508 static void clean_cpuFeatures() { _cpuFeatures = 0; } 509 static void set_avx_cpuFeatures() { _cpuFeatures = (CPU_SSE | CPU_SSE2 | CPU_AVX); } 510 511 512 // Initialization 513 static void initialize(); 514 515 // Asserts 516 static void assert_is_initialized() { 517 assert(_cpuid_info.std_cpuid1_eax.bits.family != 0, "VM_Version not initialized"); 518 } 519 520 // 521 // Processor family: 522 // 3 - 386 523 // 4 - 486 524 // 5 - Pentium 525 // 6 - PentiumPro, Pentium II, Celeron, Xeon, Pentium III, Athlon, 526 // Pentium M, Core Solo, Core Duo, Core2 Duo 527 // family 6 model: 9, 13, 14, 15 528 // 0x0f - Pentium 4, Opteron 529 // 530 // Note: The cpu family should be used to select between |