17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef CPU_X86_VM_VERSION_X86_HPP
26 #define CPU_X86_VM_VERSION_X86_HPP
27
28 #include "runtime/abstract_vm_version.hpp"
29 #include "utilities/debug.hpp"
30 #include "utilities/macros.hpp"
31 #include "utilities/sizes.hpp"
32
33 class stringStream;
34
35 class VM_Version : public Abstract_VM_Version {
36 friend class VMStructs;
37 friend class JVMCIVMStructs;
38
39 public:
40 // cpuid result register layouts. These are all unions of a uint32_t
41 // (in case anyone wants access to the register as a whole) and a bitfield.
42
43 union StdCpuid1Eax {
44 uint32_t value;
45 struct {
46 uint32_t stepping : 4,
47 model : 4,
48 family : 4,
49 proc_type : 2,
50 : 2,
51 ext_model : 4,
52 ext_family : 8,
53 : 4;
54 } bits;
55 };
56
57 union StdCpuid1Ebx { // example, unused
356 apx_f : 1,
357 : 12;
358 } bits;
359 };
360
361 protected:
362 static int _cpu;
363 static int _model;
364 static int _stepping;
365
366 static bool _has_intel_jcc_erratum;
367
368 static address _cpuinfo_segv_addr; // address of instruction which causes SEGV
369 static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV
370 static address _cpuinfo_segv_addr_apx; // address of instruction which causes APX specific SEGV
371 static address _cpuinfo_cont_addr_apx; // address of instruction after the one which causes APX specific SEGV
372
373 /*
374 * Update following files when declaring new flags:
375 * test/lib-test/jdk/test/whitebox/CPUInfoTest.java
376 * src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/amd64/AMD64.java
377 */
378 enum Feature_Flag {
379 #define CPU_FEATURE_FLAGS(decl) \
380 decl(CX8, cx8 ) /* next bits are from cpuid 1 (EDX) */ \
381 decl(CMOV, cmov ) \
382 decl(FXSR, fxsr ) \
383 decl(HT, ht ) \
384 decl(3DNOW_PREFETCH, 3dnowpref ) /* Processor supports 3dnow prefetch and prefetchw instructions */ \
385 /* may not necessarily support other 3dnow instructions */ \
386 decl(SSE3, sse3 ) /* SSE3 comes from cpuid 1 (ECX) */ \
387 decl(SSSE3, ssse3 ) \
388 decl(SSE4A, sse4a ) \
389 decl(SSE4_1, sse4.1 ) \
390 decl(SSE4_2, sse4.2 ) \
391 decl(POPCNT, popcnt ) \
392 decl(LZCNT, lzcnt ) \
393 decl(TSC, tsc ) \
394 decl(TSCINV_BIT, tscinvbit ) \
395 decl(TSCINV, tscinv ) \
396 decl(AVX, avx ) \
432 decl(OSPKE, ospke ) /* OS enables protection keys */ \
433 decl(CET_IBT, cet_ibt ) /* Control Flow Enforcement - Indirect Branch Tracking */ \
434 decl(CET_SS, cet_ss ) /* Control Flow Enforcement - Shadow Stack */ \
435 decl(AVX512_IFMA, avx512_ifma ) /* Integer Vector FMA instructions*/ \
436 decl(AVX_IFMA, avx_ifma ) /* 256-bit VEX-coded variant of AVX512-IFMA*/ \
437 decl(APX_F, apx_f ) /* Intel Advanced Performance Extensions*/ \
438 decl(SHA512, sha512 ) /* SHA512 instructions*/ \
439 decl(AVX512_FP16, avx512_fp16 ) /* AVX512 FP16 ISA support*/ \
440 decl(AVX10_1, avx10_1 ) /* AVX10 512 bit vector ISA Version 1 support*/ \
441 decl(AVX10_2, avx10_2 ) /* AVX10 512 bit vector ISA Version 2 support*/ \
442 decl(HYBRID, hybrid ) /* Hybrid architecture */
443
444 #define DECLARE_CPU_FEATURE_FLAG(id, name) CPU_##id,
445 CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
446 #undef DECLARE_CPU_FEATURE_FLAG
447 MAX_CPU_FEATURES
448 };
449
450 class VM_Features {
451 friend class VMStructs;
452 friend class JVMCIVMStructs;
453
454 private:
455 uint64_t _features_bitmap[(MAX_CPU_FEATURES / BitsPerLong) + 1];
456
457 STATIC_ASSERT(sizeof(_features_bitmap) * BitsPerByte >= MAX_CPU_FEATURES);
458
459 // Number of 8-byte elements in _bitmap.
460 constexpr static int features_bitmap_element_count() {
461 return sizeof(_features_bitmap) / sizeof(uint64_t);
462 }
463
464 constexpr static int features_bitmap_element_shift_count() {
465 return LogBitsPerLong;
466 }
467
468 constexpr static uint64_t features_bitmap_element_mask() {
469 return (1ULL << features_bitmap_element_shift_count()) - 1;
470 }
471
472 static int index(Feature_Flag feature) {
473 int idx = feature >> features_bitmap_element_shift_count();
474 assert(idx < features_bitmap_element_count(), "Features array index out of bounds");
475 return idx;
476 }
477
478 static uint64_t bit_mask(Feature_Flag feature) {
479 return (1ULL << (feature & features_bitmap_element_mask()));
480 }
481
482 static int _features_bitmap_size; // for JVMCI purposes
483 public:
484 VM_Features() {
485 for (int i = 0; i < features_bitmap_element_count(); i++) {
486 _features_bitmap[i] = 0;
487 }
488 }
489
490 void set_feature(Feature_Flag feature) {
491 int idx = index(feature);
492 _features_bitmap[idx] |= bit_mask(feature);
493 }
494
495 void clear_feature(VM_Version::Feature_Flag feature) {
496 int idx = index(feature);
497 _features_bitmap[idx] &= ~bit_mask(feature);
498 }
499
500 bool supports_feature(VM_Version::Feature_Flag feature) {
501 int idx = index(feature);
502 return (_features_bitmap[idx] & bit_mask(feature)) != 0;
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef CPU_X86_VM_VERSION_X86_HPP
26 #define CPU_X86_VM_VERSION_X86_HPP
27
28 #include "runtime/abstract_vm_version.hpp"
29 #include "utilities/debug.hpp"
30 #include "utilities/macros.hpp"
31 #include "utilities/sizes.hpp"
32
33 class stringStream;
34
35 class VM_Version : public Abstract_VM_Version {
36 friend class VMStructs;
37
38 public:
39 // cpuid result register layouts. These are all unions of a uint32_t
40 // (in case anyone wants access to the register as a whole) and a bitfield.
41
42 union StdCpuid1Eax {
43 uint32_t value;
44 struct {
45 uint32_t stepping : 4,
46 model : 4,
47 family : 4,
48 proc_type : 2,
49 : 2,
50 ext_model : 4,
51 ext_family : 8,
52 : 4;
53 } bits;
54 };
55
56 union StdCpuid1Ebx { // example, unused
355 apx_f : 1,
356 : 12;
357 } bits;
358 };
359
360 protected:
361 static int _cpu;
362 static int _model;
363 static int _stepping;
364
365 static bool _has_intel_jcc_erratum;
366
367 static address _cpuinfo_segv_addr; // address of instruction which causes SEGV
368 static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV
369 static address _cpuinfo_segv_addr_apx; // address of instruction which causes APX specific SEGV
370 static address _cpuinfo_cont_addr_apx; // address of instruction after the one which causes APX specific SEGV
371
372 /*
373 * Update following files when declaring new flags:
374 * test/lib-test/jdk/test/whitebox/CPUInfoTest.java
375 */
376 enum Feature_Flag {
377 #define CPU_FEATURE_FLAGS(decl) \
378 decl(CX8, cx8 ) /* next bits are from cpuid 1 (EDX) */ \
379 decl(CMOV, cmov ) \
380 decl(FXSR, fxsr ) \
381 decl(HT, ht ) \
382 decl(3DNOW_PREFETCH, 3dnowpref ) /* Processor supports 3dnow prefetch and prefetchw instructions */ \
383 /* may not necessarily support other 3dnow instructions */ \
384 decl(SSE3, sse3 ) /* SSE3 comes from cpuid 1 (ECX) */ \
385 decl(SSSE3, ssse3 ) \
386 decl(SSE4A, sse4a ) \
387 decl(SSE4_1, sse4.1 ) \
388 decl(SSE4_2, sse4.2 ) \
389 decl(POPCNT, popcnt ) \
390 decl(LZCNT, lzcnt ) \
391 decl(TSC, tsc ) \
392 decl(TSCINV_BIT, tscinvbit ) \
393 decl(TSCINV, tscinv ) \
394 decl(AVX, avx ) \
430 decl(OSPKE, ospke ) /* OS enables protection keys */ \
431 decl(CET_IBT, cet_ibt ) /* Control Flow Enforcement - Indirect Branch Tracking */ \
432 decl(CET_SS, cet_ss ) /* Control Flow Enforcement - Shadow Stack */ \
433 decl(AVX512_IFMA, avx512_ifma ) /* Integer Vector FMA instructions*/ \
434 decl(AVX_IFMA, avx_ifma ) /* 256-bit VEX-coded variant of AVX512-IFMA*/ \
435 decl(APX_F, apx_f ) /* Intel Advanced Performance Extensions*/ \
436 decl(SHA512, sha512 ) /* SHA512 instructions*/ \
437 decl(AVX512_FP16, avx512_fp16 ) /* AVX512 FP16 ISA support*/ \
438 decl(AVX10_1, avx10_1 ) /* AVX10 512 bit vector ISA Version 1 support*/ \
439 decl(AVX10_2, avx10_2 ) /* AVX10 512 bit vector ISA Version 2 support*/ \
440 decl(HYBRID, hybrid ) /* Hybrid architecture */
441
442 #define DECLARE_CPU_FEATURE_FLAG(id, name) CPU_##id,
443 CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
444 #undef DECLARE_CPU_FEATURE_FLAG
445 MAX_CPU_FEATURES
446 };
447
448 class VM_Features {
449 friend class VMStructs;
450
451 private:
452 uint64_t _features_bitmap[(MAX_CPU_FEATURES / BitsPerLong) + 1];
453
454 STATIC_ASSERT(sizeof(_features_bitmap) * BitsPerByte >= MAX_CPU_FEATURES);
455
456 // Number of 8-byte elements in _bitmap.
457 constexpr static int features_bitmap_element_count() {
458 return sizeof(_features_bitmap) / sizeof(uint64_t);
459 }
460
461 constexpr static int features_bitmap_element_shift_count() {
462 return LogBitsPerLong;
463 }
464
465 constexpr static uint64_t features_bitmap_element_mask() {
466 return (1ULL << features_bitmap_element_shift_count()) - 1;
467 }
468
469 static int index(Feature_Flag feature) {
470 int idx = feature >> features_bitmap_element_shift_count();
471 assert(idx < features_bitmap_element_count(), "Features array index out of bounds");
472 return idx;
473 }
474
475 static uint64_t bit_mask(Feature_Flag feature) {
476 return (1ULL << (feature & features_bitmap_element_mask()));
477 }
478
479 public:
480 VM_Features() {
481 for (int i = 0; i < features_bitmap_element_count(); i++) {
482 _features_bitmap[i] = 0;
483 }
484 }
485
486 void set_feature(Feature_Flag feature) {
487 int idx = index(feature);
488 _features_bitmap[idx] |= bit_mask(feature);
489 }
490
491 void clear_feature(VM_Version::Feature_Flag feature) {
492 int idx = index(feature);
493 _features_bitmap[idx] &= ~bit_mask(feature);
494 }
495
496 bool supports_feature(VM_Version::Feature_Flag feature) {
497 int idx = index(feature);
498 return (_features_bitmap[idx] & bit_mask(feature)) != 0;
|