< prev index next >
src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
Print this page
rev 60615 : 8231441: Initial SVE backend support
Reviewed-by: adinn, pli
Contributed-by: joshua.zhu@arm.com, yang.zhang@arm.com, ningsheng.jian@arm.com
*** 29,44 ****
#include "memory/resourceArea.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/macros.hpp"
#include OS_HEADER_INLINE(os)
- #include <sys/auxv.h>
#include <asm/hwcap.h>
#ifndef HWCAP_AES
#define HWCAP_AES (1<<3)
#endif
--- 29,46 ----
#include "memory/resourceArea.hpp"
#include "runtime/java.hpp"
#include "runtime/os.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/vm_version.hpp"
+ #include "utilities/formatBuffer.hpp"
#include "utilities/macros.hpp"
#include OS_HEADER_INLINE(os)
#include <asm/hwcap.h>
+ #include <sys/auxv.h>
+ #include <sys/prctl.h>
#ifndef HWCAP_AES
#define HWCAP_AES (1<<3)
#endif
*** 64,80 ****
--- 66,97 ----
#ifndef HWCAP_SHA512
#define HWCAP_SHA512 (1 << 21)
#endif
+ #ifndef HWCAP_SVE
+ #define HWCAP_SVE (1 << 22)
+ #endif
+
+ #ifndef HWCAP2_SVE2
+ #define HWCAP2_SVE2 (1 << 1)
+ #endif
+
+ #ifndef PR_SVE_GET_VL
+ // For old toolchains which do not have SVE related macros defined.
+ #define PR_SVE_SET_VL 50
+ #define PR_SVE_GET_VL 51
+ #endif
+
int VM_Version::_cpu;
int VM_Version::_model;
int VM_Version::_model2;
int VM_Version::_variant;
int VM_Version::_revision;
int VM_Version::_stepping;
bool VM_Version::_dcpop;
+ int VM_Version::_initial_sve_vector_length;
VM_Version::PsrInfo VM_Version::_psr_info = { 0, };
static BufferBlob* stub_blob;
static const int stub_size = 550;
*** 113,123 ****
return start;
}
};
-
void VM_Version::get_processor_features() {
_supports_cx8 = true;
_supports_atomic_getset4 = true;
_supports_atomic_getadd4 = true;
_supports_atomic_getset8 = true;
--- 130,139 ----
*** 164,173 ****
--- 180,190 ----
warning("SoftwarePrefetchHintDistance must be -1, or a multiple of 8");
SoftwarePrefetchHintDistance &= ~7;
}
uint64_t auxv = getauxval(AT_HWCAP);
+ uint64_t auxv2 = getauxval(AT_HWCAP2);
char buf[512];
_features = auxv;
*** 289,298 ****
--- 306,317 ----
if (auxv & HWCAP_AES) strcat(buf, ", aes");
if (auxv & HWCAP_SHA1) strcat(buf, ", sha1");
if (auxv & HWCAP_SHA2) strcat(buf, ", sha256");
if (auxv & HWCAP_SHA512) strcat(buf, ", sha512");
if (auxv & HWCAP_ATOMICS) strcat(buf, ", lse");
+ if (auxv & HWCAP_SVE) strcat(buf, ", sve");
+ if (auxv2 & HWCAP2_SVE2) strcat(buf, ", sve2");
_features_string = os::strdup(buf);
if (FLAG_IS_DEFAULT(UseCRC32)) {
UseCRC32 = (auxv & HWCAP_CRC32) != 0;
*** 428,437 ****
--- 447,468 ----
} else if (UseBlockZeroing) {
warning("DC ZVA is not available on this CPU");
FLAG_SET_DEFAULT(UseBlockZeroing, false);
}
+ if (auxv & HWCAP_SVE) {
+ if (FLAG_IS_DEFAULT(UseSVE)) {
+ FLAG_SET_DEFAULT(UseSVE, (auxv2 & HWCAP2_SVE2) ? 2 : 1);
+ }
+ if (UseSVE > 0) {
+ _initial_sve_vector_length = prctl(PR_SVE_GET_VL);
+ }
+ } else if (UseSVE > 0) {
+ warning("UseSVE specified, but not supported on current CPU. Disabling SVE.");
+ FLAG_SET_DEFAULT(UseSVE, 0);
+ }
+
// This machine allows unaligned memory accesses
if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
}
*** 462,471 ****
--- 493,546 ----
}
if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
UseMontgomerySquareIntrinsic = true;
}
+ if (UseSVE > 0) {
+ if (FLAG_IS_DEFAULT(MaxVectorSize)) {
+ MaxVectorSize = _initial_sve_vector_length;
+ } else if (MaxVectorSize < 16) {
+ warning("SVE does not support vector length less than 16 bytes. Disabling SVE.");
+ UseSVE = 0;
+ } else if ((MaxVectorSize % 16) == 0 && is_power_of_2(MaxVectorSize)) {
+ int new_vl = prctl(PR_SVE_SET_VL, MaxVectorSize);
+ _initial_sve_vector_length = new_vl;
+ // If MaxVectorSize is larger than system largest supported SVE vector length, above prctl()
+ // call will set task vector length to the system largest supported value. So, we also update
+ // MaxVectorSize to that largest supported value.
+ if (new_vl < 0) {
+ vm_exit_during_initialization(
+ err_msg("Current system does not support SVE vector length for MaxVectorSize: %d",
+ (int)MaxVectorSize));
+ } else if (new_vl != MaxVectorSize) {
+ warning("Current system only supports max SVE vector length %d. Set MaxVectorSize to %d",
+ new_vl, new_vl);
+ }
+ MaxVectorSize = new_vl;
+ } else {
+ vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize));
+ }
+ }
+
+ if (UseSVE == 0) { // NEON
+ int min_vector_size = 8;
+ int max_vector_size = 16;
+ if (!FLAG_IS_DEFAULT(MaxVectorSize)) {
+ if (!is_power_of_2(MaxVectorSize)) {
+ vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize));
+ } else if (MaxVectorSize < min_vector_size) {
+ warning("MaxVectorSize must be at least %i on this platform", min_vector_size);
+ FLAG_SET_DEFAULT(MaxVectorSize, min_vector_size);
+ } else if (MaxVectorSize > max_vector_size) {
+ warning("MaxVectorSize must be at most %i on this platform", max_vector_size);
+ FLAG_SET_DEFAULT(MaxVectorSize, max_vector_size);
+ }
+ } else {
+ FLAG_SET_DEFAULT(MaxVectorSize, 16);
+ }
+ }
+
if (FLAG_IS_DEFAULT(OptoScheduling)) {
OptoScheduling = true;
}
if (FLAG_IS_DEFAULT(AlignVector)) {
< prev index next >