226 static int _model; |
226 static int _model; |
227 static int _stepping; |
227 static int _stepping; |
228 static int _cpuFeatures; // features returned by the "cpuid" instruction |
228 static int _cpuFeatures; // features returned by the "cpuid" instruction |
229 // 0 if this instruction is not available |
229 // 0 if this instruction is not available |
230 static const char* _features_str; |
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 the one which causes SEGV |
231 |
234 |
232 enum { |
235 enum { |
233 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) |
236 CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX) |
234 CPU_CMOV = (1 << 1), |
237 CPU_CMOV = (1 << 1), |
235 CPU_FXSR = (1 << 2), |
238 CPU_FXSR = (1 << 2), |
359 uint32_t ext_cpuid8_edx; // reserved |
362 uint32_t ext_cpuid8_edx; // reserved |
360 |
363 |
361 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register) |
364 // extended control register XCR0 (the XFEATURE_ENABLED_MASK register) |
362 XemXcr0Eax xem_xcr0_eax; |
365 XemXcr0Eax xem_xcr0_eax; |
363 uint32_t xem_xcr0_edx; // reserved |
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 |
364 }; |
370 }; |
365 |
371 |
366 // The actual cpuid info block |
372 // The actual cpuid info block |
367 static CpuidInfo _cpuid_info; |
373 static CpuidInfo _cpuid_info; |
368 |
374 |
458 } |
464 } |
459 |
465 |
460 return result; |
466 return result; |
461 } |
467 } |
462 |
468 |
|
469 static bool os_supports_avx_vectors() { |
|
470 if (!supports_avx()) { |
|
471 return false; |
|
472 } |
|
473 // Verify that OS save/restore all bits of AVX registers |
|
474 // during signal processing. |
|
475 int nreg = 2 LP64_ONLY(+2); |
|
476 for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register |
|
477 if (_cpuid_info.ymm_save[i] != ymm_test_value()) { |
|
478 return false; |
|
479 } |
|
480 } |
|
481 return true; |
|
482 } |
|
483 |
463 static void get_processor_features(); |
484 static void get_processor_features(); |
464 |
485 |
465 public: |
486 public: |
466 // Offsets for cpuid asm stub |
487 // Offsets for cpuid asm stub |
467 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); } |
488 static ByteSize std_cpuid0_offset() { return byte_offset_of(CpuidInfo, std_max_function); } |
474 static ByteSize ext_cpuid8_offset() { return byte_offset_of(CpuidInfo, ext_cpuid8_eax); } |
495 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); } |
496 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); } |
497 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); } |
498 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); } |
499 static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); } |
|
500 static ByteSize ymm_save_offset() { return byte_offset_of(CpuidInfo, ymm_save); } |
|
501 |
|
502 // The value used to check ymm register after signal handle |
|
503 static int ymm_test_value() { return 0xCAFEBABE; } |
|
504 |
|
505 static void set_cpuinfo_segv_addr(address pc) { _cpuinfo_segv_addr = pc; } |
|
506 static bool is_cpuinfo_segv_addr(address pc) { return _cpuinfo_segv_addr == pc; } |
|
507 static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; } |
|
508 static address cpuinfo_cont_addr() { return _cpuinfo_cont_addr; } |
|
509 |
|
510 static void clean_cpuFeatures() { _cpuFeatures = 0; } |
|
511 static void set_avx_cpuFeatures() { _cpuFeatures = (CPU_SSE | CPU_SSE2 | CPU_AVX); } |
|
512 |
479 |
513 |
480 // Initialization |
514 // Initialization |
481 static void initialize(); |
515 static void initialize(); |
482 |
516 |
483 // Asserts |
517 // Asserts |