8172231: SPARC ISA/CPU feature detection is broken/insufficient (on Solaris)
Summary: Update for new platforms
Reviewed-by: kvn
Contributed-by: phedlin@oracle.com
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Tue Jun 27 15:27:54 2017 +0200
@@ -4613,7 +4613,7 @@
// Use BIS for zeroing (count is in bytes).
void MacroAssembler::bis_zeroing(Register to, Register count, Register temp, Label& Ldone) {
- assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing");
+ assert(UseBlockZeroing && VM_Version::has_blk_zeroing(), "only works with BIS zeroing");
Register end = count;
int cache_line_size = VM_Version::prefetch_data_size();
assert(cache_line_size > 0, "cache line size should be known for this code");
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Tue Jun 27 15:27:54 2017 +0200
@@ -1760,7 +1760,10 @@
return true;
}
-// USII supports fxtof through the whole range of number, USIII doesn't
+/* NOTE: All currently supported SPARC HW provides fast conversion.
+ *
+ * TODO: Clean-out code depending on 'has_fast_fxtof'.
+ */
const bool Matcher::convL2FSupported(void) {
return VM_Version::has_fast_fxtof();
}
@@ -1789,9 +1792,9 @@
// No additional cost for CMOVL.
const int Matcher::long_cmove_cost() { return 0; }
-// CMOVF/CMOVD are expensive on T4 and on SPARC64.
+// CMOVF/CMOVD are expensive on e.g., T4 and SPARC64.
const int Matcher::float_cmove_cost() {
- return (VM_Version::is_T4() || VM_Version::is_sparc64()) ? ConditionalMoveLimit : 0;
+ return VM_Version::has_fast_cmove() ? 0 : ConditionalMoveLimit;
}
// Does the CPU require late expand (see block.cpp for description of late expand)?
@@ -3194,7 +3197,7 @@
// Pointer Immediate: 64-bit
operand immP_set() %{
- predicate(!VM_Version::is_niagara_plus());
+ predicate(!VM_Version::has_fast_ld());
match(ConP);
op_cost(5);
@@ -3206,7 +3209,7 @@
// Pointer Immediate: 64-bit
// From Niagara2 processors on a load should be better than materializing.
operand immP_load() %{
- predicate(VM_Version::is_niagara_plus() && (n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set(n->get_ptr()) > 3)));
+ predicate(VM_Version::has_fast_ld() && (n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set(n->get_ptr()) > 3)));
match(ConP);
op_cost(5);
@@ -3217,7 +3220,7 @@
// Pointer Immediate: 64-bit
operand immP_no_oop_cheap() %{
- predicate(VM_Version::is_niagara_plus() && !n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set(n->get_ptr()) <= 3));
+ predicate(VM_Version::has_fast_ld() && !n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set(n->get_ptr()) <= 3));
match(ConP);
op_cost(5);
@@ -3341,7 +3344,7 @@
// Long Immediate: cheap (materialize in <= 3 instructions)
operand immL_cheap() %{
- predicate(!VM_Version::is_niagara_plus() || MacroAssembler::insts_for_set64(n->get_long()) <= 3);
+ predicate(!VM_Version::has_fast_ld() || MacroAssembler::insts_for_set64(n->get_long()) <= 3);
match(ConL);
op_cost(0);
@@ -3351,7 +3354,7 @@
// Long Immediate: expensive (materialize in > 3 instructions)
operand immL_expensive() %{
- predicate(VM_Version::is_niagara_plus() && MacroAssembler::insts_for_set64(n->get_long()) > 3);
+ predicate(VM_Version::has_fast_ld() && MacroAssembler::insts_for_set64(n->get_long()) > 3);
match(ConL);
op_cost(0);
--- a/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp Tue Jun 27 15:27:54 2017 +0200
@@ -71,28 +71,43 @@
declare_c2_constant(R_G5_num) \
declare_c2_constant(R_G6_num) \
declare_c2_constant(R_G7_num) \
- declare_constant(VM_Version::vis1_instructions_m) \
- declare_constant(VM_Version::vis2_instructions_m) \
- declare_constant(VM_Version::vis3_instructions_m) \
- declare_constant(VM_Version::cbcond_instructions_m) \
- declare_constant(VM_Version::v8_instructions_m) \
- declare_constant(VM_Version::hardware_mul32_m) \
- declare_constant(VM_Version::hardware_div32_m) \
- declare_constant(VM_Version::hardware_fsmuld_m) \
- declare_constant(VM_Version::hardware_popc_m) \
- declare_constant(VM_Version::v9_instructions_m) \
- declare_constant(VM_Version::sun4v_m) \
- declare_constant(VM_Version::blk_init_instructions_m) \
- declare_constant(VM_Version::fmaf_instructions_m) \
- declare_constant(VM_Version::sparc64_family_m) \
- declare_constant(VM_Version::M_family_m) \
- declare_constant(VM_Version::T_family_m) \
- declare_constant(VM_Version::T1_model_m) \
- declare_constant(VM_Version::sparc5_instructions_m) \
- declare_constant(VM_Version::aes_instructions_m) \
- declare_constant(VM_Version::sha1_instruction_m) \
- declare_constant(VM_Version::sha256_instruction_m) \
- declare_constant(VM_Version::sha512_instruction_m)
+ declare_constant(VM_Version::ISA_V9) \
+ declare_constant(VM_Version::ISA_POPC) \
+ declare_constant(VM_Version::ISA_VIS1) \
+ declare_constant(VM_Version::ISA_VIS2) \
+ declare_constant(VM_Version::ISA_BLK_INIT) \
+ declare_constant(VM_Version::ISA_FMAF) \
+ declare_constant(VM_Version::ISA_VIS3) \
+ declare_constant(VM_Version::ISA_HPC) \
+ declare_constant(VM_Version::ISA_IMA) \
+ declare_constant(VM_Version::ISA_AES) \
+ declare_constant(VM_Version::ISA_DES) \
+ declare_constant(VM_Version::ISA_KASUMI) \
+ declare_constant(VM_Version::ISA_CAMELLIA) \
+ declare_constant(VM_Version::ISA_MD5) \
+ declare_constant(VM_Version::ISA_SHA1) \
+ declare_constant(VM_Version::ISA_SHA256) \
+ declare_constant(VM_Version::ISA_SHA512) \
+ declare_constant(VM_Version::ISA_MPMUL) \
+ declare_constant(VM_Version::ISA_MONT) \
+ declare_constant(VM_Version::ISA_PAUSE) \
+ declare_constant(VM_Version::ISA_CBCOND) \
+ declare_constant(VM_Version::ISA_CRC32C) \
+ declare_constant(VM_Version::ISA_VIS3B) \
+ declare_constant(VM_Version::ISA_ADI) \
+ declare_constant(VM_Version::ISA_SPARC5) \
+ declare_constant(VM_Version::ISA_MWAIT) \
+ declare_constant(VM_Version::ISA_XMPMUL) \
+ declare_constant(VM_Version::ISA_XMONT) \
+ declare_constant(VM_Version::ISA_PAUSE_NSEC) \
+ declare_constant(VM_Version::ISA_VAMASK) \
+ declare_constant(VM_Version::CPU_FAST_IDIV) \
+ declare_constant(VM_Version::CPU_FAST_RDPC) \
+ declare_constant(VM_Version::CPU_FAST_BIS) \
+ declare_constant(VM_Version::CPU_FAST_LD) \
+ declare_constant(VM_Version::CPU_FAST_CMOVE) \
+ declare_constant(VM_Version::CPU_FAST_IND_BR) \
+ declare_constant(VM_Version::CPU_BLK_ZEROING)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Tue Jun 27 15:27:54 2017 +0200
@@ -32,7 +32,9 @@
#include "runtime/stubCodeGenerator.hpp"
#include "vm_version_sparc.hpp"
-unsigned int VM_Version::_L2_data_cache_line_size = 0;
+#include <sys/mman.h>
+
+uint VM_Version::_L2_data_cache_line_size = 0;
void VM_Version::initialize() {
assert(_features != 0, "System pre-initialization is not complete.");
@@ -69,77 +71,84 @@
_supports_cx8 = true; // All SPARC V9 implementations.
_supports_atomic_getset4 = true; // Using the 'swap' instruction.
- if (is_niagara()) {
- // Indirect branch is the same cost as direct
- if (FLAG_IS_DEFAULT(UseInlineCaches)) {
- FLAG_SET_DEFAULT(UseInlineCaches, false);
- }
- // Align loops on a single instruction boundary.
- if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
- FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
- }
- // 32-bit oops don't make sense for the 64-bit VM on sparc
- // since the 32-bit VM has the same registers and smaller objects.
- Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
- Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);
+ if (has_fast_ind_br() && FLAG_IS_DEFAULT(UseInlineCaches)) {
+ // Indirect and direct branches are cost equivalent.
+ FLAG_SET_DEFAULT(UseInlineCaches, false);
+ }
+ // Align loops on the proper instruction boundary to fill the instruction
+ // fetch buffer.
+ if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
+ FLAG_SET_DEFAULT(OptoLoopAlignment, VM_Version::insn_fetch_alignment);
+ }
+
+ // 32-bit oops don't make sense for the 64-bit VM on SPARC since the 32-bit
+ // VM has the same registers and smaller objects.
+ Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
+ Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);
+
#ifdef COMPILER2
- // Indirect branch is the same cost as direct
- if (FLAG_IS_DEFAULT(UseJumpTables)) {
- FLAG_SET_DEFAULT(UseJumpTables, true);
- }
- // Single-issue, so entry and loop tops are
- // aligned on a single instruction boundary
- if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
- FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
+ if (has_fast_ind_br() && FLAG_IS_DEFAULT(UseJumpTables)) {
+ // Indirect and direct branches are cost equivalent.
+ FLAG_SET_DEFAULT(UseJumpTables, true);
+ }
+ // Entry and loop tops are aligned to fill the instruction fetch buffer.
+ if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
+ FLAG_SET_DEFAULT(InteriorEntryAlignment, VM_Version::insn_fetch_alignment);
+ }
+ if (UseTLAB && cache_line_size > 0 &&
+ FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
+ if (has_fast_bis()) {
+ // Use BIS instruction for TLAB allocation prefetch.
+ FLAG_SET_DEFAULT(AllocatePrefetchInstr, 1);
}
- if (is_niagara_plus()) {
- if (has_blk_init() && (cache_line_size > 0) && UseTLAB &&
- FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
- if (!has_sparc5_instr()) {
- // Use BIS instruction for TLAB allocation prefetch
- // on Niagara plus processors other than those based on CoreS4
- FLAG_SET_DEFAULT(AllocatePrefetchInstr, 1);
- } else {
- // On CoreS4 processors use prefetch instruction
- // to avoid partial RAW issue, also use prefetch style 3
- FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
- if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
- FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
- }
- }
- }
- if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
- if (AllocatePrefetchInstr == 0) {
- // Use different prefetch distance without BIS
- FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
- } else {
- // Use smaller prefetch distance with BIS
- FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
- }
- }
- if (is_T4()) {
- // Double number of prefetched cache lines on T4
- // since L2 cache line size is smaller (32 bytes).
- if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
- FLAG_SET_ERGO(intx, AllocatePrefetchLines, AllocatePrefetchLines*2);
- }
- if (FLAG_IS_DEFAULT(AllocateInstancePrefetchLines)) {
- FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, AllocateInstancePrefetchLines*2);
- }
+ else if (has_sparc5()) {
+ // Use prefetch instruction to avoid partial RAW issue on Core S4 processors,
+ // also use prefetch style 3.
+ FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
+ if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
+ FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
}
}
-
- if ((AllocatePrefetchInstr == 1) && (AllocatePrefetchStyle != 3)) {
- if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
- warning("AllocatePrefetchStyle set to 3 because BIS instructions require aligned memory addresses");
- }
- FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
+ }
+ if (AllocatePrefetchInstr == 1) {
+ // Use allocation prefetch style 3 because BIS instructions require
+ // aligned memory addresses.
+ FLAG_SET_DEFAULT(AllocatePrefetchStyle, 3);
+ }
+ if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
+ if (AllocatePrefetchInstr == 0) {
+ // Use different prefetch distance without BIS
+ FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
+ } else {
+ // Use smaller prefetch distance with BIS
+ FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
}
-#endif /* COMPILER2 */
}
+ // We increase the number of prefetched cache lines, to use just a bit more
+ // aggressive approach, when the L2-cache line size is small (32 bytes), or
+ // when running on newer processor implementations, such as the Core S4.
+ bool inc_prefetch = cache_line_size > 0 && (cache_line_size < 64 || has_sparc5());
+
+ if (inc_prefetch) {
+ // We use a factor two for small cache line sizes (as before) but a slightly
+ // more conservative increase when running on more recent hardware that will
+ // benefit from just a bit more aggressive prefetching.
+ if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
+ const int ap_lns = AllocatePrefetchLines;
+ const int ap_inc = cache_line_size < 64 ? ap_lns : (ap_lns + 1) / 2;
+ FLAG_SET_ERGO(intx, AllocatePrefetchLines, ap_lns + ap_inc);
+ }
+ if (FLAG_IS_DEFAULT(AllocateInstancePrefetchLines)) {
+ const int ip_lns = AllocateInstancePrefetchLines;
+ const int ip_inc = cache_line_size < 64 ? ip_lns : (ip_lns + 1) / 2;
+ FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, ip_lns + ip_inc);
+ }
+ }
+#endif /* COMPILER2 */
+
// Use hardware population count instruction if available.
- if (has_hardware_popc()) {
+ if (has_popc()) {
if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
FLAG_SET_DEFAULT(UsePopCountInstruction, true);
}
@@ -148,7 +157,7 @@
FLAG_SET_DEFAULT(UsePopCountInstruction, false);
}
- // T4 and newer Sparc cpus have new compare and branch instruction.
+ // Use compare and branch instructions if available.
if (has_cbcond()) {
if (FLAG_IS_DEFAULT(UseCBCond)) {
FLAG_SET_DEFAULT(UseCBCond, true);
@@ -159,7 +168,8 @@
}
assert(BlockZeroingLowLimit > 0, "invalid value");
- if (has_block_zeroing() && cache_line_size > 0) {
+
+ if (has_blk_zeroing() && cache_line_size > 0) {
if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
FLAG_SET_DEFAULT(UseBlockZeroing, true);
}
@@ -169,7 +179,8 @@
}
assert(BlockCopyLowLimit > 0, "invalid value");
- if (has_block_zeroing() && cache_line_size > 0) { // has_blk_init() && is_T4(): core's local L2 cache
+
+ if (has_blk_zeroing() && cache_line_size > 0) {
if (FLAG_IS_DEFAULT(UseBlockCopy)) {
FLAG_SET_DEFAULT(UseBlockCopy, true);
}
@@ -179,7 +190,6 @@
}
#ifdef COMPILER2
- // T4 and newer Sparc cpus have fast RDPC.
if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
FLAG_SET_DEFAULT(UseRDPCForConstantTableBase, true);
}
@@ -196,44 +206,68 @@
assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
char buf[512];
- jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
- (has_hardware_popc() ? ", popc" : ""),
- (has_vis1() ? ", vis1" : ""),
- (has_vis2() ? ", vis2" : ""),
- (has_vis3() ? ", vis3" : ""),
- (has_blk_init() ? ", blk_init" : ""),
- (has_cbcond() ? ", cbcond" : ""),
- (has_aes() ? ", aes" : ""),
- (has_sha1() ? ", sha1" : ""),
- (has_sha256() ? ", sha256" : ""),
- (has_sha512() ? ", sha512" : ""),
- (has_crc32c() ? ", crc32c" : ""),
- (is_ultra3() ? ", ultra3" : ""),
- (has_sparc5_instr() ? ", sparc5" : ""),
- (is_sun4v() ? ", sun4v" : ""),
- (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
- (is_sparc64() ? ", sparc64" : ""),
- (!has_hardware_mul32() ? ", no-mul32" : ""),
- (!has_hardware_div32() ? ", no-div32" : ""),
- (!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
+ jio_snprintf(buf, sizeof(buf),
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ (has_v9() ? "v9" : ""),
+ (has_popc() ? ", popc" : ""),
+ (has_vis1() ? ", vis1" : ""),
+ (has_vis2() ? ", vis2" : ""),
+ (has_blk_init() ? ", blk_init" : ""),
+ (has_fmaf() ? ", fmaf" : ""),
+ (has_hpc() ? ", hpc" : ""),
+ (has_ima() ? ", ima" : ""),
+ (has_aes() ? ", aes" : ""),
+ (has_des() ? ", des" : ""),
+ (has_kasumi() ? ", kas" : ""),
+ (has_camellia() ? ", cam" : ""),
+ (has_md5() ? ", md5" : ""),
+ (has_sha1() ? ", sha1" : ""),
+ (has_sha256() ? ", sha256" : ""),
+ (has_sha512() ? ", sha512" : ""),
+ (has_mpmul() ? ", mpmul" : ""),
+ (has_mont() ? ", mont" : ""),
+ (has_pause() ? ", pause" : ""),
+ (has_cbcond() ? ", cbcond" : ""),
+ (has_crc32c() ? ", crc32c" : ""),
- // buf is started with ", " or is empty
- _features_string = os::strdup(strlen(buf) > 2 ? buf + 2 : buf);
+ (has_athena_plus() ? ", athena_plus" : ""),
+ (has_vis3b() ? ", vis3b" : ""),
+ (has_adi() ? ", adi" : ""),
+ (has_sparc5() ? ", sparc5" : ""),
+ (has_mwait() ? ", mwait" : ""),
+ (has_xmpmul() ? ", xmpmul" : ""),
+ (has_xmont() ? ", xmont" : ""),
+ (has_pause_nsec() ? ", pause_nsec" : ""),
+ (has_vamask() ? ", vamask" : ""),
- // UseVIS is set to the smallest of what hardware supports and what
- // the command line requires. I.e., you cannot set UseVIS to 3 on
- // older UltraSparc which do not support it.
- if (UseVIS > 3) UseVIS=3;
- if (UseVIS < 0) UseVIS=0;
+ (has_fast_idiv() ? ", *idiv" : ""),
+ (has_fast_rdpc() ? ", *rdpc" : ""),
+ (has_fast_bis() ? ", *bis" : ""),
+ (has_fast_ld() ? ", *ld" : ""),
+ (has_fast_cmove() ? ", *cmove" : ""),
+ (has_fast_fxtof() ? ", *fxtof" : ""),
+ (has_fast_ind_br() ? ", *ind_br" : ""),
+ (has_blk_zeroing() ? ", *blk_zeroing" : ""));
+
+ assert(strlen(buf) >= 2, "must be");
+
+ _features_string = os::strdup(buf);
+
+ log_info(os, cpu)("SPARC features detected: %s", _features_string);
+
+ // UseVIS is set to the smallest of what hardware supports and what the command
+ // line requires, i.e. you cannot set UseVIS to 3 on older UltraSparc which do
+ // not support it.
+
+ if (UseVIS > 3) UseVIS = 3;
+ if (UseVIS < 0) UseVIS = 0;
if (!has_vis3()) // Drop to 2 if no VIS3 support
- UseVIS = MIN2((intx)2,UseVIS);
+ UseVIS = MIN2((intx)2, UseVIS);
if (!has_vis2()) // Drop to 1 if no VIS2 support
- UseVIS = MIN2((intx)1,UseVIS);
+ UseVIS = MIN2((intx)1, UseVIS);
if (!has_vis1()) // Drop to 0 if no VIS1 support
UseVIS = 0;
- // SPARC T4 and above should have support for AES instructions
if (has_aes()) {
if (FLAG_IS_DEFAULT(UseAES)) {
FLAG_SET_DEFAULT(UseAES, true);
@@ -289,7 +323,7 @@
FLAG_SET_DEFAULT(UseFMA, false);
}
- // SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times
+ // SHA1, SHA256, and SHA512 instructions were added to SPARC at different times
if (has_sha1() || has_sha256() || has_sha512()) {
if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions
if (FLAG_IS_DEFAULT(UseSHA)) {
@@ -337,7 +371,6 @@
FLAG_SET_DEFAULT(UseSHA, false);
}
- // SPARC T4 and above should have support for CRC32C instruction
if (has_crc32c()) {
if (UseVIS > 2) { // CRC32C intrinsics use VIS3 instructions
if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
@@ -425,96 +458,46 @@
}
void VM_Version::print_features() {
- tty->print_cr("Version:%s", _features);
+ tty->print("ISA features [0x%0" PRIx64 "]:", _features);
+ if (_features_string != NULL) {
+ tty->print(" %s", _features_string);
+ }
+ tty->cr();
}
-int VM_Version::determine_features() {
+void VM_Version::determine_features() {
if (UseV8InstrsOnly) {
- log_info(os, cpu)("Version is Forced-V8");
- return generic_v8_m;
- }
-
- int features = platform_features(unknown_m); // platform_features() is os_arch specific
-
- if (features == unknown_m) {
- features = generic_v9_m;
- log_info(os)("Cannot recognize SPARC version. Default to V9");
+ log_info(os, cpu)("SPARC V8 not supported");
}
- assert(is_T_family(features) == is_niagara(features), "Niagara should be T series");
- if (UseNiagaraInstrs) { // Force code generation for Niagara
- if (is_T_family(features)) {
- // Happy to accomodate...
- } else {
- log_info(os, cpu)("Version is Forced-Niagara");
- features |= T_family_m;
- }
- } else {
- if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
- log_info(os, cpu)("Version is Forced-Not-Niagara");
- features &= ~(T_family_m | T1_model_m);
- } else {
- // Happy to accomodate...
- }
+ platform_features(); // platform_features() is os_arch specific
+
+ assert(has_v9(), "must be");
+
+ if (UseNiagaraInstrs) { // Limit code generation to Niagara.
+ _features &= niagara1_msk;
}
-
- return features;
}
static uint64_t saved_features = 0;
void VM_Version::allow_all() {
saved_features = _features;
- _features = all_features_m;
+ _features = full_feature_msk;
}
void VM_Version::revert() {
_features = saved_features;
}
+/* Determine a suitable number of threads on this particular machine.
+ *
+ * FIXME: Simply checking the processor family is insufficient.
+ */
unsigned int VM_Version::calc_parallel_worker_threads() {
- unsigned int result;
- if (is_M_series() || is_S_series()) {
- // for now, use same gc thread calculation for M-series and S-series as for
- // niagara-plus. In future, we may want to tweak parameters for
- // nof_parallel_worker_thread
- result = nof_parallel_worker_threads(5, 16, 8);
- } else if (is_niagara_plus()) {
- result = nof_parallel_worker_threads(5, 16, 8);
- } else {
- result = nof_parallel_worker_threads(5, 8, 8);
- }
- return result;
-}
-
-
-int VM_Version::parse_features(const char* implementation) {
- int features = unknown_m;
- // Convert to UPPER case before compare.
- char* impl = os::strdup_check_oom(implementation);
+ const int num = 5;
+ const int den = is_post_niagara() ? 16 : 8;
+ const int threshold = 8;
- for (int i = 0; impl[i] != 0; i++)
- impl[i] = (char)toupper((uint)impl[i]);
-
- if (strstr(impl, "SPARC64") != NULL) {
- features |= sparc64_family_m;
- } else if (strstr(impl, "SPARC-M") != NULL) {
- // M-series SPARC is based on T-series.
- features |= (M_family_m | T_family_m);
- } else if (strstr(impl, "SPARC-S") != NULL) {
- // S-series SPARC is based on T-series.
- features |= (S_family_m | T_family_m);
- } else if (strstr(impl, "SPARC-T") != NULL) {
- features |= T_family_m;
- if (strstr(impl, "SPARC-T1") != NULL) {
- features |= T1_model_m;
- }
- } else if (strstr(impl, "SUN4V-CPU") != NULL) {
- // Generic or migration class LDOM
- features |= T_family_m;
- } else {
- log_info(os, cpu)("Failed to parse CPU implementation = '%s'", impl);
- }
- os::free((void*)impl);
- return features;
+ return nof_parallel_worker_threads(num, den, threshold);
}
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Tue Jun 27 15:27:54 2017 +0200
@@ -33,150 +33,241 @@
friend class JVMCIVMStructs;
protected:
- enum Feature_Flag {
- v8_instructions = 0,
- hardware_mul32 = 1,
- hardware_div32 = 2,
- hardware_fsmuld = 3,
- hardware_popc = 4,
- v9_instructions = 5,
- vis1_instructions = 6,
- vis2_instructions = 7,
- sun4v_instructions = 8,
- blk_init_instructions = 9,
- fmaf_instructions = 10,
- vis3_instructions = 11,
- cbcond_instructions = 12,
- sparc64_family = 13,
- M_family = 14,
- S_family = 15,
- T_family = 16,
- T1_model = 17,
- sparc5_instructions = 18,
- aes_instructions = 19,
- sha1_instruction = 20,
- sha256_instruction = 21,
- sha512_instruction = 22,
- crc32c_instruction = 23
+ enum {
+ ISA_V9,
+ ISA_POPC,
+ ISA_VIS1,
+ ISA_VIS2,
+ ISA_BLK_INIT,
+ ISA_FMAF,
+ ISA_VIS3,
+ ISA_HPC,
+ ISA_IMA,
+ ISA_AES,
+ ISA_DES,
+ ISA_KASUMI,
+ ISA_CAMELLIA,
+ ISA_MD5,
+ ISA_SHA1,
+ ISA_SHA256,
+ ISA_SHA512,
+ ISA_MPMUL,
+ ISA_MONT,
+ ISA_PAUSE,
+ ISA_CBCOND,
+ ISA_CRC32C,
+
+ ISA_FJATHPLUS,
+ ISA_VIS3B,
+ ISA_ADI,
+ ISA_SPARC5,
+ ISA_MWAIT,
+ ISA_XMPMUL,
+ ISA_XMONT,
+ ISA_PAUSE_NSEC,
+ ISA_VAMASK,
+
+ // Synthesised properties:
+
+ CPU_FAST_IDIV,
+ CPU_FAST_RDPC,
+ CPU_FAST_BIS,
+ CPU_FAST_LD,
+ CPU_FAST_CMOVE,
+ CPU_FAST_IND_BR,
+ CPU_BLK_ZEROING
};
- enum Feature_Flag_Set {
- unknown_m = 0,
- all_features_m = -1,
+private:
+ enum { ISA_last_feature = ISA_VAMASK,
+ CPU_last_feature = CPU_BLK_ZEROING };
+
+ enum {
+ ISA_unknown_msk = 0,
+
+ ISA_v9_msk = UINT64_C(1) << ISA_V9,
- v8_instructions_m = 1 << v8_instructions,
- hardware_mul32_m = 1 << hardware_mul32,
- hardware_div32_m = 1 << hardware_div32,
- hardware_fsmuld_m = 1 << hardware_fsmuld,
- hardware_popc_m = 1 << hardware_popc,
- v9_instructions_m = 1 << v9_instructions,
- vis1_instructions_m = 1 << vis1_instructions,
- vis2_instructions_m = 1 << vis2_instructions,
- sun4v_m = 1 << sun4v_instructions,
- blk_init_instructions_m = 1 << blk_init_instructions,
- fmaf_instructions_m = 1 << fmaf_instructions,
- vis3_instructions_m = 1 << vis3_instructions,
- cbcond_instructions_m = 1 << cbcond_instructions,
- sparc64_family_m = 1 << sparc64_family,
- M_family_m = 1 << M_family,
- S_family_m = 1 << S_family,
- T_family_m = 1 << T_family,
- T1_model_m = 1 << T1_model,
- sparc5_instructions_m = 1 << sparc5_instructions,
- aes_instructions_m = 1 << aes_instructions,
- sha1_instruction_m = 1 << sha1_instruction,
- sha256_instruction_m = 1 << sha256_instruction,
- sha512_instruction_m = 1 << sha512_instruction,
- crc32c_instruction_m = 1 << crc32c_instruction,
+ ISA_popc_msk = UINT64_C(1) << ISA_POPC,
+ ISA_vis1_msk = UINT64_C(1) << ISA_VIS1,
+ ISA_vis2_msk = UINT64_C(1) << ISA_VIS2,
+ ISA_blk_init_msk = UINT64_C(1) << ISA_BLK_INIT,
+ ISA_fmaf_msk = UINT64_C(1) << ISA_FMAF,
+ ISA_vis3_msk = UINT64_C(1) << ISA_VIS3,
+ ISA_hpc_msk = UINT64_C(1) << ISA_HPC,
+ ISA_ima_msk = UINT64_C(1) << ISA_IMA,
+ ISA_aes_msk = UINT64_C(1) << ISA_AES,
+ ISA_des_msk = UINT64_C(1) << ISA_DES,
+ ISA_kasumi_msk = UINT64_C(1) << ISA_KASUMI,
+ ISA_camellia_msk = UINT64_C(1) << ISA_CAMELLIA,
+ ISA_md5_msk = UINT64_C(1) << ISA_MD5,
+ ISA_sha1_msk = UINT64_C(1) << ISA_SHA1,
+ ISA_sha256_msk = UINT64_C(1) << ISA_SHA256,
+ ISA_sha512_msk = UINT64_C(1) << ISA_SHA512,
+ ISA_mpmul_msk = UINT64_C(1) << ISA_MPMUL,
+ ISA_mont_msk = UINT64_C(1) << ISA_MONT,
+ ISA_pause_msk = UINT64_C(1) << ISA_PAUSE,
+ ISA_cbcond_msk = UINT64_C(1) << ISA_CBCOND,
+ ISA_crc32c_msk = UINT64_C(1) << ISA_CRC32C,
- generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
- generic_v9_m = generic_v8_m | v9_instructions_m,
- ultra3_m = generic_v9_m | vis1_instructions_m | vis2_instructions_m,
+ ISA_fjathplus_msk = UINT64_C(1) << ISA_FJATHPLUS,
+ ISA_vis3b_msk = UINT64_C(1) << ISA_VIS3B,
+ ISA_adi_msk = UINT64_C(1) << ISA_ADI,
+ ISA_sparc5_msk = UINT64_C(1) << ISA_SPARC5,
+ ISA_mwait_msk = UINT64_C(1) << ISA_MWAIT,
+ ISA_xmpmul_msk = UINT64_C(1) << ISA_XMPMUL,
+ ISA_xmont_msk = UINT64_C(1) << ISA_XMONT,
+ ISA_pause_nsec_msk = UINT64_C(1) << ISA_PAUSE_NSEC,
+ ISA_vamask_msk = UINT64_C(1) << ISA_VAMASK,
- // Temporary until we have something more accurate
- niagara1_unique_m = sun4v_m,
- niagara1_m = generic_v9_m | niagara1_unique_m
+ CPU_fast_idiv_msk = UINT64_C(1) << CPU_FAST_IDIV,
+ CPU_fast_rdpc_msk = UINT64_C(1) << CPU_FAST_RDPC,
+ CPU_fast_bis_msk = UINT64_C(1) << CPU_FAST_BIS,
+ CPU_fast_ld_msk = UINT64_C(1) << CPU_FAST_LD,
+ CPU_fast_cmove_msk = UINT64_C(1) << CPU_FAST_CMOVE,
+ CPU_fast_ind_br_msk = UINT64_C(1) << CPU_FAST_IND_BR,
+ CPU_blk_zeroing_msk = UINT64_C(1) << CPU_BLK_ZEROING,
+
+ last_feature_msk = CPU_blk_zeroing_msk,
+ full_feature_msk = (last_feature_msk << 1) - 1
};
- static unsigned int _L2_data_cache_line_size;
- static unsigned int L2_data_cache_line_size() { return _L2_data_cache_line_size; }
-
- static void print_features();
- static int determine_features();
- static int platform_features(int features);
+/* The following, previously supported, SPARC implementations are no longer
+ * supported.
+ *
+ * UltraSPARC I/II:
+ * SPARC-V9, VIS
+ * UltraSPARC III/+: (Cheetah/+)
+ * SPARC-V9, VIS
+ * UltraSPARC IV: (Jaguar)
+ * SPARC-V9, VIS
+ * UltraSPARC IV+: (Panther)
+ * SPARC-V9, VIS, POPC
+ *
+ * The currently supported SPARC implementations are listed below (including
+ * generic V9 support).
+ *
+ * UltraSPARC T1: (Niagara)
+ * SPARC-V9, VIS, ASI_BIS (Crypto/hash in SPU)
+ * UltraSPARC T2: (Niagara-2)
+ * SPARC-V9, VIS, ASI_BIS, POPC (Crypto/hash in SPU)
+ * UltraSPARC T2+: (Victoria Falls, etc.)
+ * SPARC-V9, VIS, VIS2, ASI_BIS, POPC (Crypto/hash in SPU)
+ *
+ * UltraSPARC T3: (Rainbow Falls/S2)
+ * SPARC-V9, VIS, VIS2, ASI_BIS, POPC (Crypto/hash in SPU)
+ *
+ * Oracle SPARC T4/T5/M5: (Core S3)
+ * SPARC-V9, VIS, VIS2, VIS3, ASI_BIS, HPC, POPC, FMAF, IMA, PAUSE, CBCOND,
+ * AES, DES, Kasumi, Camellia, MD5, SHA1, SHA256, SHA512, CRC32C, MONT, MPMUL
+ *
+ * Oracle SPARC M7: (Core S4)
+ * SPARC-V9, VIS, VIS2, VIS3, ASI_BIS, HPC, POPC, FMAF, IMA, PAUSE, CBCOND,
+ * AES, DES, Camellia, MD5, SHA1, SHA256, SHA512, CRC32C, MONT, MPMUL, VIS3b,
+ * ADI, SPARC5, MWAIT, XMPMUL, XMONT, PAUSE_NSEC, VAMASK
+ *
+ */
+ enum {
+ niagara1_msk = ISA_v9_msk | ISA_vis1_msk | ISA_blk_init_msk,
+ niagara2_msk = niagara1_msk | ISA_popc_msk,
- // Returns true if the platform is in the niagara line (T series)
- static bool is_M_family(int features) { return (features & M_family_m) != 0; }
- static bool is_S_family(int features) { return (features & S_family_m) != 0; }
- static bool is_T_family(int features) { return (features & T_family_m) != 0; }
- static bool is_niagara() { return is_T_family(_features); }
-#ifdef ASSERT
- static bool is_niagara(int features) {
- // 'sun4v_m' may be defined on both Sun/Oracle Sparc CPUs as well as
- // on Fujitsu Sparc64 CPUs, but only Sun/Oracle Sparcs can be 'niagaras'.
- return (features & sun4v_m) != 0 && (features & sparc64_family_m) == 0;
- }
-#endif
+ core_S2_msk = niagara2_msk | ISA_vis2_msk,
+
+ core_S3_msk = core_S2_msk | ISA_fmaf_msk | ISA_vis3_msk | ISA_hpc_msk |
+ ISA_ima_msk | ISA_aes_msk | ISA_des_msk | ISA_kasumi_msk |
+ ISA_camellia_msk | ISA_md5_msk | ISA_sha1_msk | ISA_sha256_msk |
+ ISA_sha512_msk | ISA_mpmul_msk | ISA_mont_msk | ISA_pause_msk |
+ ISA_cbcond_msk | ISA_crc32c_msk,
+
+ core_S4_msk = core_S3_msk - ISA_kasumi_msk |
+ ISA_vis3b_msk | ISA_adi_msk | ISA_sparc5_msk | ISA_mwait_msk |
+ ISA_xmpmul_msk | ISA_xmont_msk | ISA_pause_nsec_msk | ISA_vamask_msk,
+
+ ultra_sparc_t1_msk = niagara1_msk,
+ ultra_sparc_t2_msk = niagara2_msk,
+ ultra_sparc_t3_msk = core_S2_msk,
+ ultra_sparc_m5_msk = core_S3_msk, // NOTE: First out-of-order pipeline.
+ ultra_sparc_m7_msk = core_S4_msk
+ };
- // Returns true if it is niagara1 (T1).
- static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
+ static uint _L2_data_cache_line_size;
+ static uint L2_data_cache_line_size() { return _L2_data_cache_line_size; }
+
+ static void determine_features();
+ static void platform_features();
+ static void print_features();
- static int maximum_niagara1_processor_count() { return 32; }
- static int parse_features(const char* implementation);
public:
- // Initialization
+ enum {
+ // Adopt a conservative behaviour (modelling single-insn-fetch-n-issue) for
+ // Niagara (and SPARC64). While there are at least two entries/slots in the
+ // instruction fetch buffer on any Niagara core (and as many as eight on a
+ // SPARC64), the performance improvement from keeping hot branch targets on
+ // optimally aligned addresses is such a small one (if any) that we choose
+ // not to use the extra code space required.
+
+ insn_fetch_alignment = 4 // Byte alignment in L1 insn. cache.
+ };
+
static void initialize();
- static void init_before_ergo() { _features = determine_features(); }
+ static void init_before_ergo() { determine_features(); }
+
+ // Instruction feature support:
- // Instruction support
- static bool has_v8() { return (_features & v8_instructions_m) != 0; }
- static bool has_v9() { return (_features & v9_instructions_m) != 0; }
- static bool has_hardware_mul32() { return (_features & hardware_mul32_m) != 0; }
- static bool has_hardware_div32() { return (_features & hardware_div32_m) != 0; }
- static bool has_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; }
- static bool has_hardware_popc() { return (_features & hardware_popc_m) != 0; }
- static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
- static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
- static bool has_vis3() { return (_features & vis3_instructions_m) != 0; }
- static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; }
- static bool has_cbcond() { return (_features & cbcond_instructions_m) != 0; }
- static bool has_sparc5_instr() { return (_features & sparc5_instructions_m) != 0; }
- static bool has_aes() { return (_features & aes_instructions_m) != 0; }
- static bool has_sha1() { return (_features & sha1_instruction_m) != 0; }
- static bool has_sha256() { return (_features & sha256_instruction_m) != 0; }
- static bool has_sha512() { return (_features & sha512_instruction_m) != 0; }
- static bool has_crc32c() { return (_features & crc32c_instruction_m) != 0; }
-
- static bool supports_compare_and_exchange()
- { return has_v9(); }
+ static bool has_v9() { return (_features & ISA_v9_msk) != 0; }
+ static bool has_popc() { return (_features & ISA_popc_msk) != 0; }
+ static bool has_vis1() { return (_features & ISA_vis1_msk) != 0; }
+ static bool has_vis2() { return (_features & ISA_vis2_msk) != 0; }
+ static bool has_blk_init() { return (_features & ISA_blk_init_msk) != 0; }
+ static bool has_fmaf() { return (_features & ISA_fmaf_msk) != 0; }
+ static bool has_vis3() { return (_features & ISA_vis3_msk) != 0; }
+ static bool has_hpc() { return (_features & ISA_hpc_msk) != 0; }
+ static bool has_ima() { return (_features & ISA_ima_msk) != 0; }
+ static bool has_aes() { return (_features & ISA_aes_msk) != 0; }
+ static bool has_des() { return (_features & ISA_des_msk) != 0; }
+ static bool has_kasumi() { return (_features & ISA_kasumi_msk) != 0; }
+ static bool has_camellia() { return (_features & ISA_camellia_msk) != 0; }
+ static bool has_md5() { return (_features & ISA_md5_msk) != 0; }
+ static bool has_sha1() { return (_features & ISA_sha1_msk) != 0; }
+ static bool has_sha256() { return (_features & ISA_sha256_msk) != 0; }
+ static bool has_sha512() { return (_features & ISA_sha512_msk) != 0; }
+ static bool has_mpmul() { return (_features & ISA_mpmul_msk) != 0; }
+ static bool has_mont() { return (_features & ISA_mont_msk) != 0; }
+ static bool has_pause() { return (_features & ISA_pause_msk) != 0; }
+ static bool has_cbcond() { return (_features & ISA_cbcond_msk) != 0; }
+ static bool has_crc32c() { return (_features & ISA_crc32c_msk) != 0; }
- // Returns true if the platform is in the niagara line (T series)
- // and newer than the niagara1.
- static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); }
-
- static bool is_M_series() { return is_M_family(_features); }
- static bool is_S_series() { return is_S_family(_features); }
- static bool is_T4() { return is_T_family(_features) && has_cbcond(); }
- static bool is_T7() { return is_T_family(_features) && has_sparc5_instr(); }
-
- // Fujitsu SPARC64
- static bool is_sparc64() { return (_features & sparc64_family_m) != 0; }
+ static bool has_athena_plus() { return (_features & ISA_fjathplus_msk) != 0; }
+ static bool has_vis3b() { return (_features & ISA_vis3b_msk) != 0; }
+ static bool has_adi() { return (_features & ISA_adi_msk) != 0; }
+ static bool has_sparc5() { return (_features & ISA_sparc5_msk) != 0; }
+ static bool has_mwait() { return (_features & ISA_mwait_msk) != 0; }
+ static bool has_xmpmul() { return (_features & ISA_xmpmul_msk) != 0; }
+ static bool has_xmont() { return (_features & ISA_xmont_msk) != 0; }
+ static bool has_pause_nsec() { return (_features & ISA_pause_nsec_msk) != 0; }
+ static bool has_vamask() { return (_features & ISA_vamask_msk) != 0; }
- static bool is_sun4v() { return (_features & sun4v_m) != 0; }
- static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m && !is_sun4v() && !is_sparc64(); }
-
- static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); }
- static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); }
+ static bool has_fast_idiv() { return (_features & CPU_fast_idiv_msk) != 0; }
+ static bool has_fast_rdpc() { return (_features & CPU_fast_rdpc_msk) != 0; }
+ static bool has_fast_bis() { return (_features & CPU_fast_bis_msk) != 0; }
+ static bool has_fast_ld() { return (_features & CPU_fast_ld_msk) != 0; }
+ static bool has_fast_cmove() { return (_features & CPU_fast_cmove_msk) != 0; }
+ static bool has_fast_fxtof() { return true; }
- // T4 and newer Sparc have fast RDPC instruction.
- static bool has_fast_rdpc() { return is_T4(); }
+ // If indirect and direct branching is equally fast.
+ static bool has_fast_ind_br() { return (_features & CPU_fast_ind_br_msk) != 0; }
+ // If SPARC BIS to the beginning of cache line always zeros it.
+ static bool has_blk_zeroing() { return (_features & CPU_blk_zeroing_msk) != 0; }
+
+ static bool supports_compare_and_exchange() { return true; }
- // On T4 and newer Sparc BIS to the beginning of cache line always zeros it.
- static bool has_block_zeroing() { return has_blk_init() && is_T4(); }
+ // FIXME: To be removed.
+ static bool is_post_niagara() {
+ return (_features & niagara2_msk) == niagara2_msk;
+ }
- // default prefetch block size on sparc
- static intx prefetch_data_size() { return L2_data_cache_line_size(); }
+ // Default prefetch block size on SPARC.
+ static uint prefetch_data_size() { return L2_data_cache_line_size(); }
private:
// Prefetch policy and characteristics:
@@ -228,7 +319,11 @@
static void revert();
// Override the Abstract_VM_Version implementation.
- static uint page_size_count() { return is_sun4v() ? 4 : 2; }
+ //
+ // FIXME: Removed broken test on sun4v (always false when invoked prior to the
+ // proper capability setup), thus always returning 2. Still need to fix
+ // this properly in order to enable complete page size support.
+ static uint page_size_count() { return 2; }
// Calculates the number of parallel threads
static unsigned int calc_parallel_worker_threads();
--- a/hotspot/src/cpu/sparc/vm/vmreg_sparc.hpp Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vmreg_sparc.hpp Tue Jun 27 15:27:54 2017 +0200
@@ -27,9 +27,8 @@
inline bool is_Register() { return value() >= 0 && value() < ConcreteRegisterImpl::max_gpr; }
inline bool is_FloatRegister() { return value() >= ConcreteRegisterImpl::max_gpr &&
- value() < ConcreteRegisterImpl::max_fpr; }
+ value() < ConcreteRegisterImpl::max_fpr; }
inline Register as_Register() {
-
assert( is_Register() && is_even(value()), "even-aligned GPR name" );
// Yuk
return ::as_Register(value()>>1);
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Tue Jun 27 15:27:54 2017 +0200
@@ -57,72 +57,120 @@
protected EnumSet<CPUFeature> computeFeatures(SPARCHotSpotVMConfig config) {
EnumSet<CPUFeature> features = EnumSet.noneOf(CPUFeature.class);
- if ((config.vmVersionFeatures & config.sparcVis1Instructions) != 0) {
- features.add(CPUFeature.VIS1);
+
+ if ((config.vmVersionFeatures & 1L << config.sparc_ADI) != 0) {
+ features.add(CPUFeature.ADI);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_AES) != 0) {
+ features.add(CPUFeature.AES);
}
- if ((config.vmVersionFeatures & config.sparcVis2Instructions) != 0) {
- features.add(CPUFeature.VIS2);
+ if ((config.vmVersionFeatures & 1L << config.sparc_BLK_INIT) != 0) {
+ features.add(CPUFeature.BLK_INIT);
}
- if ((config.vmVersionFeatures & config.sparcVis3Instructions) != 0) {
- features.add(CPUFeature.VIS3);
+ if ((config.vmVersionFeatures & 1L << config.sparc_CAMELLIA) != 0) {
+ features.add(CPUFeature.CAMELLIA);
}
- if ((config.vmVersionFeatures & config.sparcCbcondInstructions) != 0) {
+ if ((config.vmVersionFeatures & 1L << config.sparc_CBCOND) != 0) {
features.add(CPUFeature.CBCOND);
}
- if ((config.vmVersionFeatures & config.sparcV8Instructions) != 0) {
- features.add(CPUFeature.V8);
+ if ((config.vmVersionFeatures & 1L << config.sparc_CRC32C) != 0) {
+ features.add(CPUFeature.CRC32C);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_DES) != 0) {
+ features.add(CPUFeature.DES);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_FMAF) != 0) {
+ features.add(CPUFeature.FMAF);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_HPC) != 0) {
+ features.add(CPUFeature.HPC);
}
- if ((config.vmVersionFeatures & config.sparcHardwareMul32) != 0) {
- features.add(CPUFeature.HARDWARE_MUL32);
+ if ((config.vmVersionFeatures & 1L << config.sparc_IMA) != 0) {
+ features.add(CPUFeature.IMA);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_KASUMI) != 0) {
+ features.add(CPUFeature.KASUMI);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_MD5) != 0) {
+ features.add(CPUFeature.MD5);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_MONT) != 0) {
+ features.add(CPUFeature.MONT);
}
- if ((config.vmVersionFeatures & config.sparcHardwareDiv32) != 0) {
- features.add(CPUFeature.HARDWARE_DIV32);
+ if ((config.vmVersionFeatures & 1L << config.sparc_MPMUL) != 0) {
+ features.add(CPUFeature.MPMUL);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_MWAIT) != 0) {
+ features.add(CPUFeature.MWAIT);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_PAUSE) != 0) {
+ features.add(CPUFeature.PAUSE);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_PAUSE_NSEC) != 0) {
+ features.add(CPUFeature.PAUSE_NSEC);
}
- if ((config.vmVersionFeatures & config.sparcHardwareFsmuld) != 0) {
- features.add(CPUFeature.HARDWARE_FSMULD);
+ if ((config.vmVersionFeatures & 1L << config.sparc_POPC) != 0) {
+ features.add(CPUFeature.POPC);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_SHA1) != 0) {
+ features.add(CPUFeature.SHA1);
}
- if ((config.vmVersionFeatures & config.sparcHardwarePopc) != 0) {
- features.add(CPUFeature.HARDWARE_POPC);
+ if ((config.vmVersionFeatures & 1L << config.sparc_SHA256) != 0) {
+ features.add(CPUFeature.SHA256);
}
- if ((config.vmVersionFeatures & config.sparcV9Instructions) != 0) {
+ if ((config.vmVersionFeatures & 1L << config.sparc_SHA512) != 0) {
+ features.add(CPUFeature.SHA512);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_SPARC5) != 0) {
+ features.add(CPUFeature.SPARC5);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_V9) != 0) {
features.add(CPUFeature.V9);
}
- if ((config.vmVersionFeatures & config.sparcSun4v) != 0) {
- features.add(CPUFeature.SUN4V);
+ if ((config.vmVersionFeatures & 1L << config.sparc_VAMASK) != 0) {
+ features.add(CPUFeature.VAMASK);
}
- if ((config.vmVersionFeatures & config.sparcBlkInitInstructions) != 0) {
- features.add(CPUFeature.BLK_INIT_INSTRUCTIONS);
+ if ((config.vmVersionFeatures & 1L << config.sparc_VIS1) != 0) {
+ features.add(CPUFeature.VIS1);
}
- if ((config.vmVersionFeatures & config.sparcFmafInstructions) != 0) {
- features.add(CPUFeature.FMAF);
+ if ((config.vmVersionFeatures & 1L << config.sparc_VIS2) != 0) {
+ features.add(CPUFeature.VIS2);
}
- if ((config.vmVersionFeatures & config.sparcSparc64Family) != 0) {
- features.add(CPUFeature.SPARC64_FAMILY);
+ if ((config.vmVersionFeatures & 1L << config.sparc_VIS3) != 0) {
+ features.add(CPUFeature.VIS3);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_VIS3B) != 0) {
+ features.add(CPUFeature.VIS3B);
}
- if ((config.vmVersionFeatures & config.sparcMFamily) != 0) {
- features.add(CPUFeature.M_FAMILY);
+ if ((config.vmVersionFeatures & 1L << config.sparc_XMONT) != 0) {
+ features.add(CPUFeature.XMONT);
}
- if ((config.vmVersionFeatures & config.sparcTFamily) != 0) {
- features.add(CPUFeature.T_FAMILY);
+ if ((config.vmVersionFeatures & 1L << config.sparc_XMPMUL) != 0) {
+ features.add(CPUFeature.XMPMUL);
}
- if ((config.vmVersionFeatures & config.sparcT1Model) != 0) {
- features.add(CPUFeature.T1_MODEL);
+
+ if ((config.vmVersionFeatures & 1L << config.sparc_BLK_ZEROING) != 0) {
+ features.add(CPUFeature.BLK_ZEROING);
}
- if ((config.vmVersionFeatures & config.sparcSparc5Instructions) != 0) {
- features.add(CPUFeature.SPARC5);
+ if ((config.vmVersionFeatures & 1L << config.sparc_FAST_BIS) != 0) {
+ features.add(CPUFeature.FAST_BIS);
}
- if ((config.vmVersionFeatures & config.sparcAesInstructions) != 0) {
- features.add(CPUFeature.SPARC64_FAMILY);
+ if ((config.vmVersionFeatures & 1L << config.sparc_FAST_CMOVE) != 0) {
+ features.add(CPUFeature.FAST_CMOVE);
}
- if ((config.vmVersionFeatures & config.sparcSha1Instruction) != 0) {
- features.add(CPUFeature.SHA1);
+ if ((config.vmVersionFeatures & 1L << config.sparc_FAST_IDIV) != 0) {
+ features.add(CPUFeature.FAST_IDIV);
+ }
+ if ((config.vmVersionFeatures & 1L << config.sparc_FAST_IND_BR) != 0) {
+ features.add(CPUFeature.FAST_IND_BR);
}
- if ((config.vmVersionFeatures & config.sparcSha256Instruction) != 0) {
- features.add(CPUFeature.SHA256);
+ if ((config.vmVersionFeatures & 1L << config.sparc_FAST_LD) != 0) {
+ features.add(CPUFeature.FAST_LD);
}
- if ((config.vmVersionFeatures & config.sparcSha512Instruction) != 0) {
- features.add(CPUFeature.SHA512);
+ if ((config.vmVersionFeatures & 1L << config.sparc_FAST_RDPC) != 0) {
+ features.add(CPUFeature.FAST_RDPC);
}
+
return features;
}
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotVMConfig.java Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotVMConfig.java Tue Jun 27 15:27:54 2017 +0200
@@ -38,32 +38,54 @@
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
- // CPU capabilities
+ // CPU capabilities:
+ //
+ // FIXME: Using a 64-bit value is insufficient to support future capability
+ // sets (including co-processor capabilities such as DAX).
final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t");
- // SPARC specific values
- final int sparcVis3Instructions = getConstant("VM_Version::vis3_instructions_m", Integer.class);
- final int sparcVis2Instructions = getConstant("VM_Version::vis2_instructions_m", Integer.class);
- final int sparcVis1Instructions = getConstant("VM_Version::vis1_instructions_m", Integer.class);
- final int sparcCbcondInstructions = getConstant("VM_Version::cbcond_instructions_m", Integer.class);
- final int sparcV8Instructions = getConstant("VM_Version::v8_instructions_m", Integer.class);
- final int sparcHardwareMul32 = getConstant("VM_Version::hardware_mul32_m", Integer.class);
- final int sparcHardwareDiv32 = getConstant("VM_Version::hardware_div32_m", Integer.class);
- final int sparcHardwareFsmuld = getConstant("VM_Version::hardware_fsmuld_m", Integer.class);
- final int sparcHardwarePopc = getConstant("VM_Version::hardware_popc_m", Integer.class);
- final int sparcV9Instructions = getConstant("VM_Version::v9_instructions_m", Integer.class);
- final int sparcSun4v = getConstant("VM_Version::sun4v_m", Integer.class);
- final int sparcBlkInitInstructions = getConstant("VM_Version::blk_init_instructions_m", Integer.class);
- final int sparcFmafInstructions = getConstant("VM_Version::fmaf_instructions_m", Integer.class);
- final int sparcSparc64Family = getConstant("VM_Version::sparc64_family_m", Integer.class);
- final int sparcMFamily = getConstant("VM_Version::M_family_m", Integer.class);
- final int sparcTFamily = getConstant("VM_Version::T_family_m", Integer.class);
- final int sparcT1Model = getConstant("VM_Version::T1_model_m", Integer.class);
- final int sparcSparc5Instructions = getConstant("VM_Version::sparc5_instructions_m", Integer.class);
- final int sparcAesInstructions = getConstant("VM_Version::aes_instructions_m", Integer.class);
- final int sparcSha1Instruction = getConstant("VM_Version::sha1_instruction_m", Integer.class);
- final int sparcSha256Instruction = getConstant("VM_Version::sha256_instruction_m", Integer.class);
- final int sparcSha512Instruction = getConstant("VM_Version::sha512_instruction_m", Integer.class);
+ // SPARC specific values:
+ //
+ // NOTE: Values changed into an enumeration (that do indeed fit within a
+ // 32-bit integer) instead of the exported (64-bit wide) bit-masks.
+ final int sparc_ADI = getConstant("VM_Version::ISA_ADI", Integer.class);
+ final int sparc_AES = getConstant("VM_Version::ISA_AES", Integer.class);
+ final int sparc_BLK_INIT = getConstant("VM_Version::ISA_BLK_INIT", Integer.class);
+ final int sparc_CAMELLIA = getConstant("VM_Version::ISA_CAMELLIA", Integer.class);
+ final int sparc_CBCOND = getConstant("VM_Version::ISA_CBCOND", Integer.class);
+ final int sparc_CRC32C = getConstant("VM_Version::ISA_CRC32C", Integer.class);
+ final int sparc_DES = getConstant("VM_Version::ISA_DES", Integer.class);
+ final int sparc_FMAF = getConstant("VM_Version::ISA_FMAF", Integer.class);
+ final int sparc_HPC = getConstant("VM_Version::ISA_HPC", Integer.class);
+ final int sparc_IMA = getConstant("VM_Version::ISA_IMA", Integer.class);
+ final int sparc_KASUMI = getConstant("VM_Version::ISA_KASUMI", Integer.class);
+ final int sparc_MD5 = getConstant("VM_Version::ISA_MD5", Integer.class);
+ final int sparc_MONT = getConstant("VM_Version::ISA_MONT", Integer.class);
+ final int sparc_MPMUL = getConstant("VM_Version::ISA_MPMUL", Integer.class);
+ final int sparc_MWAIT = getConstant("VM_Version::ISA_MWAIT", Integer.class);
+ final int sparc_PAUSE = getConstant("VM_Version::ISA_PAUSE", Integer.class);
+ final int sparc_PAUSE_NSEC = getConstant("VM_Version::ISA_PAUSE_NSEC", Integer.class);
+ final int sparc_POPC = getConstant("VM_Version::ISA_POPC", Integer.class);
+ final int sparc_SHA1 = getConstant("VM_Version::ISA_SHA1", Integer.class);
+ final int sparc_SHA256 = getConstant("VM_Version::ISA_SHA256", Integer.class);
+ final int sparc_SHA512 = getConstant("VM_Version::ISA_SHA512", Integer.class);
+ final int sparc_SPARC5 = getConstant("VM_Version::ISA_SPARC5", Integer.class);
+ final int sparc_V9 = getConstant("VM_Version::ISA_V9", Integer.class);
+ final int sparc_VAMASK = getConstant("VM_Version::ISA_VAMASK", Integer.class);
+ final int sparc_VIS1 = getConstant("VM_Version::ISA_VIS1", Integer.class);
+ final int sparc_VIS2 = getConstant("VM_Version::ISA_VIS2", Integer.class);
+ final int sparc_VIS3 = getConstant("VM_Version::ISA_VIS3", Integer.class);
+ final int sparc_VIS3B = getConstant("VM_Version::ISA_VIS3B", Integer.class);
+ final int sparc_XMONT = getConstant("VM_Version::ISA_XMONT", Integer.class);
+ final int sparc_XMPMUL = getConstant("VM_Version::ISA_XMPMUL", Integer.class);
+
+ final int sparc_BLK_ZEROING = getConstant("VM_Version::CPU_BLK_ZEROING", Integer.class);
+ final int sparc_FAST_BIS = getConstant("VM_Version::CPU_FAST_BIS", Integer.class);
+ final int sparc_FAST_CMOVE = getConstant("VM_Version::CPU_FAST_CMOVE", Integer.class);
+ final int sparc_FAST_IDIV = getConstant("VM_Version::CPU_FAST_IDIV", Integer.class);
+ final int sparc_FAST_IND_BR = getConstant("VM_Version::CPU_FAST_IND_BR", Integer.class);
+ final int sparc_FAST_LD = getConstant("VM_Version::CPU_FAST_LD", Integer.class);
+ final int sparc_FAST_RDPC = getConstant("VM_Version::CPU_FAST_RDPC", Integer.class);
final boolean useBlockZeroing = getFlag("UseBlockZeroing", Boolean.class);
final int blockZeroingLowLimit = getFlag("BlockZeroingLowLimit", Integer.class);
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java Tue Jun 27 15:27:54 2017 +0200
@@ -336,27 +336,44 @@
}
public enum CPUFeature {
+ // ISA determined properties:
+ ADI,
+ AES,
+ BLK_INIT,
+ CAMELLIA,
+ CBCOND,
+ CRC32C,
+ DES,
+ FMAF,
+ HPC,
+ IMA,
+ KASUMI,
+ MD5,
+ MONT,
+ MPMUL,
+ MWAIT,
+ PAUSE,
+ PAUSE_NSEC,
+ POPC,
+ SHA1,
+ SHA256,
+ SHA512,
+ SPARC5,
+ V9,
+ VAMASK,
VIS1,
VIS2,
VIS3,
- CBCOND,
- V8,
- HARDWARE_MUL32,
- HARDWARE_DIV32,
- HARDWARE_FSMULD,
- HARDWARE_POPC,
- V9,
- SUN4V,
- BLK_INIT_INSTRUCTIONS,
- FMAF,
- SPARC64_FAMILY,
- M_FAMILY,
- T_FAMILY,
- T1_MODEL,
- SPARC5,
- AES,
- SHA1,
- SHA256,
- SHA512
+ VIS3B,
+ XMONT,
+ XMPMUL,
+ // Synthesised CPU properties:
+ BLK_ZEROING,
+ FAST_BIS,
+ FAST_CMOVE,
+ FAST_IDIV,
+ FAST_IND_BR,
+ FAST_LD,
+ FAST_RDPC
}
}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Tue Jun 27 15:27:54 2017 +0200
@@ -30,9 +30,7 @@
#include "vm_version_sparc.hpp"
#include <sys/auxv.h>
-#include <sys/auxv_SPARC.h>
#include <sys/systeminfo.h>
-#include <kstat.h>
#include <picl.h>
#include <dlfcn.h>
#include <link.h>
@@ -263,21 +261,6 @@
_dl_handle = NULL;
}
-// We need to keep these here as long as we have to build on Solaris
-// versions before 10.
-
-#ifndef SI_ARCHITECTURE_32
-#define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */
-#endif
-
-#ifndef SI_ARCHITECTURE_64
-#define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */
-#endif
-
-#ifndef SI_CPUBRAND
-#define SI_CPUBRAND 523 /* return cpu brand string */
-#endif
-
class Sysinfo {
char* _string;
public:
@@ -343,115 +326,156 @@
#define _SC_L2CACHE_LINESZ 527 /* Size of L2 cache line */
#endif
-// Hardware capability bits that appeared after Solaris 11.1
-#ifndef AV_SPARC_FMAF
-#define AV_SPARC_FMAF 0x00000100 /* Fused Multiply-Add */
-#endif
-#ifndef AV2_SPARC_SPARC5
-#define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */
-#endif
-
-int VM_Version::platform_features(int features) {
+void VM_Version::platform_features() {
+ uint64_t features = ISA_v9_msk; // Basic SPARC-V9 required (V8 not supported).
- // Check 32-bit architecture.
- if (Sysinfo(SI_ARCHITECTURE_32).match("sparc")) {
- features |= v8_instructions_m;
- }
-
- // Check 64-bit architecture.
- if (Sysinfo(SI_ARCHITECTURE_64).match("sparcv9")) {
- features |= generic_v9_m;
- }
+ assert(Sysinfo(SI_ARCHITECTURE_64).match("sparcv9"), "must be");
// Extract valid instruction set extensions.
- uint_t avs[AV_HW2_IDX + 1];
- uint_t avn = getisax(avs, ARRAY_SIZE(avs));
+ uint32_t avs[AV_HW2_IDX + 1];
+ uint_t avn = getisax(avs, AV_HW2_IDX + 1);
+ assert(avn <= 2, "should return two or less av's");
log_info(os, cpu)("getisax(2) returned %d words:", avn);
for (int i = 0; i < avn; i++) {
log_info(os, cpu)(" word %d: " PTR32_FORMAT, i, avs[i]);
}
- uint_t av1 = avs[AV_HW1_IDX];
- if (av1 & AV_SPARC_MUL32) features |= hardware_mul32_m;
- if (av1 & AV_SPARC_DIV32) features |= hardware_div32_m;
- if (av1 & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
- if (av1 & AV_SPARC_V8PLUS) features |= v9_instructions_m;
- if (av1 & AV_SPARC_POPC) features |= hardware_popc_m;
- if (av1 & AV_SPARC_VIS) features |= vis1_instructions_m;
- if (av1 & AV_SPARC_VIS2) features |= vis2_instructions_m;
- if (av1 & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
- if (av1 & AV_SPARC_FMAF) features |= fmaf_instructions_m;
- if (av1 & AV_SPARC_VIS3) features |= vis3_instructions_m;
- if (av1 & AV_SPARC_CBCOND) features |= cbcond_instructions_m;
- if (av1 & AV_SPARC_CRC32C) features |= crc32c_instruction_m;
- if (av1 & AV_SPARC_AES) features |= aes_instructions_m;
- if (av1 & AV_SPARC_SHA1) features |= sha1_instruction_m;
- if (av1 & AV_SPARC_SHA256) features |= sha256_instruction_m;
- if (av1 & AV_SPARC_SHA512) features |= sha512_instruction_m;
+ uint32_t av = avs[AV_HW1_IDX];
+
+ // These are SPARC V8 legacy features.
+
+ assert((av & AV_SPARC_MUL32) == 0, "unsupported V8");
+ assert((av & AV_SPARC_DIV32) == 0, "unsupported V8");
+ assert((av & AV_SPARC_FSMULD) == 0, "unsupported V8");
+ assert((av & AV_SPARC_V8PLUS) == 0, "unsupported V8");
+
+ if (av & AV_SPARC_POPC) features |= ISA_popc_msk;
+ if (av & AV_SPARC_VIS) features |= ISA_vis1_msk;
+ if (av & AV_SPARC_VIS2) features |= ISA_vis2_msk;
+
+ // Hardware capability defines introduced after Solaris 11.1:
+
+#ifndef AV_SPARC_FMAF
+#define AV_SPARC_FMAF 0x00000100 // Fused Multiply-Add
+#endif
+
+ if (av & AV_SPARC_ASI_BLK_INIT) features |= ISA_blk_init_msk;
+ if (av & AV_SPARC_FMAF) features |= ISA_fmaf_msk;
+ if (av & AV_SPARC_VIS3) features |= ISA_vis3_msk;
+ if (av & AV_SPARC_HPC) features |= ISA_hpc_msk;
+ if (av & AV_SPARC_IMA) features |= ISA_ima_msk;
+ if (av & AV_SPARC_AES) features |= ISA_aes_msk;
+ if (av & AV_SPARC_DES) features |= ISA_des_msk;
+ if (av & AV_SPARC_KASUMI) features |= ISA_kasumi_msk;
+ if (av & AV_SPARC_CAMELLIA) features |= ISA_camellia_msk;
+ if (av & AV_SPARC_MD5) features |= ISA_md5_msk;
+ if (av & AV_SPARC_SHA1) features |= ISA_sha1_msk;
+ if (av & AV_SPARC_SHA256) features |= ISA_sha256_msk;
+ if (av & AV_SPARC_SHA512) features |= ISA_sha512_msk;
+ if (av & AV_SPARC_MPMUL) features |= ISA_mpmul_msk;
+ if (av & AV_SPARC_MONT) features |= ISA_mont_msk;
+ if (av & AV_SPARC_PAUSE) features |= ISA_pause_msk;
+ if (av & AV_SPARC_CBCOND) features |= ISA_cbcond_msk;
+ if (av & AV_SPARC_CRC32C) features |= ISA_crc32c_msk;
- if (avn > AV_HW2_IDX) {
- uint_t av2 = avs[AV_HW2_IDX];
- if (av2 & AV2_SPARC_SPARC5) features |= sparc5_instructions_m;
- }
+#ifndef AV2_SPARC_FJATHPLUS
+#define AV2_SPARC_FJATHPLUS 0x00000001 // Fujitsu Athena+
+#endif
+#ifndef AV2_SPARC_VIS3B
+#define AV2_SPARC_VIS3B 0x00000002 // VIS3 present on multiple chips
+#endif
+#ifndef AV2_SPARC_ADI
+#define AV2_SPARC_ADI 0x00000004 // Application Data Integrity
+#endif
+#ifndef AV2_SPARC_SPARC5
+#define AV2_SPARC_SPARC5 0x00000008 // The 29 new fp and sub instructions
+#endif
+#ifndef AV2_SPARC_MWAIT
+#define AV2_SPARC_MWAIT 0x00000010 // mwait instruction and load/monitor ASIs
+#endif
+#ifndef AV2_SPARC_XMPMUL
+#define AV2_SPARC_XMPMUL 0x00000020 // XOR multiple precision multiply
+#endif
+#ifndef AV2_SPARC_XMONT
+#define AV2_SPARC_XMONT 0x00000040 // XOR Montgomery mult/sqr instructions
+#endif
+#ifndef AV2_SPARC_PAUSE_NSEC
+#define AV2_SPARC_PAUSE_NSEC 0x00000080 // pause instruction with support for nsec timings
+#endif
+#ifndef AV2_SPARC_VAMASK
+#define AV2_SPARC_VAMASK 0x00000100 // Virtual Address masking
+#endif
- // Determine the machine type.
- if (Sysinfo(SI_MACHINE).match("sun4v")) {
- features |= sun4v_m;
+ if (avn > 1) {
+ uint32_t av2 = avs[AV_HW2_IDX];
+
+ if (av2 & AV2_SPARC_FJATHPLUS) features |= ISA_fjathplus_msk;
+ if (av2 & AV2_SPARC_VIS3B) features |= ISA_vis3b_msk;
+ if (av2 & AV2_SPARC_ADI) features |= ISA_adi_msk;
+ if (av2 & AV2_SPARC_SPARC5) features |= ISA_sparc5_msk;
+ if (av2 & AV2_SPARC_MWAIT) features |= ISA_mwait_msk;
+ if (av2 & AV2_SPARC_XMPMUL) features |= ISA_xmpmul_msk;
+ if (av2 & AV2_SPARC_XMONT) features |= ISA_xmont_msk;
+ if (av2 & AV2_SPARC_PAUSE_NSEC) features |= ISA_pause_nsec_msk;
+ if (av2 & AV2_SPARC_VAMASK) features |= ISA_vamask_msk;
}
- // If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
- // is available to us as well
- Sysinfo cpu_info(SI_CPUBRAND);
- bool use_solaris_12_api = cpu_info.valid();
- const char* impl = "unknown";
- int impl_m = 0;
- if (use_solaris_12_api) {
- impl = cpu_info.value();
- log_info(os, cpu)("Parsing CPU implementation from %s", impl);
- impl_m = parse_features(impl);
+ _features = features; // ISA feature set completed, update state.
+
+ Sysinfo machine(SI_MACHINE);
+
+ bool is_sun4v = machine.match("sun4v"); // All Oracle SPARC + Fujitsu Athena+
+ bool is_sun4u = machine.match("sun4u"); // All other Fujitsu
+
+ // Handle Athena+ conservatively (simply because we are lacking info.).
+
+ bool do_sun4v = is_sun4v && !has_athena_plus();
+ bool do_sun4u = is_sun4u || has_athena_plus();
+
+ uint64_t synthetic = 0;
+
+ if (do_sun4v) {
+ // Indirect and direct branches are equally fast.
+ synthetic = CPU_fast_ind_br_msk;
+ // Fast IDIV, BIS and LD available on Niagara Plus.
+ if (has_vis2()) {
+ synthetic |= (CPU_fast_idiv_msk | CPU_fast_ld_msk);
+ // ...on Core S4 however, we prefer not to use BIS.
+ if (!has_sparc5()) {
+ synthetic |= CPU_fast_bis_msk;
+ }
+ }
+ // Niagara Core S3 supports fast RDPC and block zeroing.
+ if (has_ima()) {
+ synthetic |= (CPU_fast_rdpc_msk | CPU_blk_zeroing_msk);
+ }
+ // Niagara Core S3 and S4 have slow CMOVE.
+ if (!has_ima()) {
+ synthetic |= CPU_fast_cmove_msk;
+ }
+ } else if (do_sun4u) {
+ // SPARC64 only have fast IDIV and RDPC.
+ synthetic |= (CPU_fast_idiv_msk | CPU_fast_rdpc_msk);
} else {
- // Otherwise use kstat to determine the machine type.
- kstat_ctl_t* kc = kstat_open();
- if (kc != NULL) {
- kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
- if (ksp != NULL) {
- if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
- kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
- for (int i = 0; i < ksp->ks_ndata; i++) {
- if (strcmp((const char*)&(knm[i].name), "implementation") == 0) {
- impl = KSTAT_NAMED_STR_PTR(&knm[i]);
- log_info(os, cpu)("Parsing CPU implementation from %s", impl);
- impl_m = parse_features(impl);
- break;
- }
- }
- }
- }
- kstat_close(kc);
- }
+ log_info(os, cpu)("Unable to derive CPU features: %s", machine.value());
}
- assert(impl_m != 0, "Unrecognized CPU implementation: %s", impl);
- features |= impl_m;
+
+ _features += synthetic; // Including CPU derived/synthetic features.
+
+ Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ);
+ Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ);
+
+ // Require both Sysconf requests to be valid or use fall-back.
- bool is_sun4v = (features & sun4v_m) != 0;
- if (use_solaris_12_api && is_sun4v) {
- // If Solaris 12 API is supported and it's sun4v use sysconf() to get the cache line sizes
- Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ);
- if (l1_dcache_line_size.valid()) {
- _L1_data_cache_line_size = l1_dcache_line_size.value();
- }
-
- Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ);
- if (l2_dcache_line_size.valid()) {
- _L2_data_cache_line_size = l2_dcache_line_size.value();
- }
+ if (l1_dcache_line_size.valid() &&
+ l2_dcache_line_size.valid()) {
+ _L1_data_cache_line_size = l1_dcache_line_size.value();
+ _L2_data_cache_line_size = l2_dcache_line_size.value();
} else {
- // Otherwise figure out the cache line sizes using PICL
- bool is_fujitsu = (features & sparc64_family_m) != 0;
- PICL picl(is_fujitsu, is_sun4v);
+ // Otherwise figure out the cache line sizes using PICL.
+ PICL picl(is_sun4u, is_sun4v);
_L1_data_cache_line_size = picl.L1_data_cache_line_size();
_L2_data_cache_line_size = picl.L2_data_cache_line_size();
}
- return features;
}
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Tue Jun 27 15:22:23 2017 +0200
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Tue Jun 27 15:27:54 2017 +0200
@@ -731,29 +731,43 @@
volatile_nonstatic_field(JavaFrameAnchor, _flags, int)
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
- declare_constant(VM_Version::vis1_instructions_m) \
- declare_constant(VM_Version::vis2_instructions_m) \
- declare_constant(VM_Version::vis3_instructions_m) \
- declare_constant(VM_Version::cbcond_instructions_m) \
- declare_constant(VM_Version::v8_instructions_m) \
- declare_constant(VM_Version::hardware_mul32_m) \
- declare_constant(VM_Version::hardware_div32_m) \
- declare_constant(VM_Version::hardware_fsmuld_m) \
- declare_constant(VM_Version::hardware_popc_m) \
- declare_constant(VM_Version::v9_instructions_m) \
- declare_constant(VM_Version::sun4v_m) \
- declare_constant(VM_Version::blk_init_instructions_m) \
- declare_constant(VM_Version::fmaf_instructions_m) \
- declare_constant(VM_Version::sparc64_family_m) \
- declare_constant(VM_Version::M_family_m) \
- declare_constant(VM_Version::T_family_m) \
- declare_constant(VM_Version::T1_model_m) \
- declare_constant(VM_Version::sparc5_instructions_m) \
- declare_constant(VM_Version::aes_instructions_m) \
- declare_constant(VM_Version::sha1_instruction_m) \
- declare_constant(VM_Version::sha256_instruction_m) \
- declare_constant(VM_Version::sha512_instruction_m)
-
+ declare_constant(VM_Version::ISA_V9) \
+ declare_constant(VM_Version::ISA_POPC) \
+ declare_constant(VM_Version::ISA_VIS1) \
+ declare_constant(VM_Version::ISA_VIS2) \
+ declare_constant(VM_Version::ISA_BLK_INIT) \
+ declare_constant(VM_Version::ISA_FMAF) \
+ declare_constant(VM_Version::ISA_VIS3) \
+ declare_constant(VM_Version::ISA_HPC) \
+ declare_constant(VM_Version::ISA_IMA) \
+ declare_constant(VM_Version::ISA_AES) \
+ declare_constant(VM_Version::ISA_DES) \
+ declare_constant(VM_Version::ISA_KASUMI) \
+ declare_constant(VM_Version::ISA_CAMELLIA) \
+ declare_constant(VM_Version::ISA_MD5) \
+ declare_constant(VM_Version::ISA_SHA1) \
+ declare_constant(VM_Version::ISA_SHA256) \
+ declare_constant(VM_Version::ISA_SHA512) \
+ declare_constant(VM_Version::ISA_MPMUL) \
+ declare_constant(VM_Version::ISA_MONT) \
+ declare_constant(VM_Version::ISA_PAUSE) \
+ declare_constant(VM_Version::ISA_CBCOND) \
+ declare_constant(VM_Version::ISA_CRC32C) \
+ declare_constant(VM_Version::ISA_VIS3B) \
+ declare_constant(VM_Version::ISA_ADI) \
+ declare_constant(VM_Version::ISA_SPARC5) \
+ declare_constant(VM_Version::ISA_MWAIT) \
+ declare_constant(VM_Version::ISA_XMPMUL) \
+ declare_constant(VM_Version::ISA_XMONT) \
+ declare_constant(VM_Version::ISA_PAUSE_NSEC) \
+ declare_constant(VM_Version::ISA_VAMASK) \
+ declare_constant(VM_Version::CPU_FAST_IDIV) \
+ declare_constant(VM_Version::CPU_FAST_RDPC) \
+ declare_constant(VM_Version::CPU_FAST_BIS) \
+ declare_constant(VM_Version::CPU_FAST_LD) \
+ declare_constant(VM_Version::CPU_FAST_CMOVE) \
+ declare_constant(VM_Version::CPU_FAST_IND_BR) \
+ declare_constant(VM_Version::CPU_BLK_ZEROING)
#endif