8079203: AARCH64: Need to cater for different partner implementations
authorenevill
Tue, 12 May 2015 13:58:42 +0000
changeset 30429 c980154ed1a3
parent 30412 8ffdeabc7c2b
child 30430 01b7cab6b7b1
child 30635 8884c2399789
8079203: AARCH64: Need to cater for different partner implementations Summary: Parse /proc/cpuinfo to derive implementation specific info Reviewed-by: kvn
hotspot/src/cpu/aarch64/vm/aarch64.ad
hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp
hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Wed Jul 05 20:32:48 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Tue May 12 13:58:42 2015 +0000
@@ -810,9 +810,6 @@
   bool unnecessary_volatile(const Node *barrier);
   bool needs_releasing_store(const Node *store);
 
-  // Use barrier instructions rather than load acquire / store
-  // release.
-  const bool UseBarriersForVolatile = false;
   // Use barrier instructions for unsafe volatile gets rather than
   // trying to identify an exact signature for them
   const bool UseBarriersForUnsafeVolatileGet = false;
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Wed Jul 05 20:32:48 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Tue May 12 13:58:42 2015 +0000
@@ -98,8 +98,8 @@
   product(bool, NearCpool, true,                                        \
          "constant pool is close to instructions")                      \
                                                                         \
-  notproduct(bool, UseAcqRelForVolatileFields, false,                   \
-             "Use acquire and release insns for volatile fields")       \
+  product(bool, UseBarriersForVolatile, false,                          \
+          "Use memory barriers to implement volatile accesses")         \
                                                                         \
   product(bool, UseCRC32, false,                                        \
           "Use CRC32 instructions for CRC32 computation")               \
@@ -117,8 +117,8 @@
   product(bool, NearCpool, true,                                        \
          "constant pool is close to instructions")                      \
                                                                         \
-  notproduct(bool, UseAcqRelForVolatileFields, false,                   \
-             "Use acquire and release insns for volatile fields")       \
+  product(bool, UseBarriersForVolatile, false,                          \
+          "Use memory barriers to implement volatile accesses")         \
   product(bool, UseNeon, false,                                         \
           "Use Neon for CRC32 computation")                             \
   product(bool, UseCRC32, false,                                        \
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Wed Jul 05 20:32:48 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Tue May 12 13:58:42 2015 +0000
@@ -1314,7 +1314,7 @@
     // case_array_offset_in_bytes()
     movw(reg2, in_bytes(MultiBranchData::per_case_size()));
     movw(rscratch1, in_bytes(MultiBranchData::case_array_offset()));
-    maddw(index, index, reg2, rscratch1);
+    Assembler::maddw(index, index, reg2, rscratch1);
 
     // Update the case count
     increment_mdp_data_at(mdp,
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Jul 05 20:32:48 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Tue May 12 13:58:42 2015 +0000
@@ -1625,7 +1625,7 @@
     sdivw(result, ra, rb);
   } else {
     sdivw(scratch, ra, rb);
-    msubw(result, scratch, rb, ra);
+    Assembler::msubw(result, scratch, rb, ra);
   }
 
   return idivl_offset;
@@ -1655,7 +1655,7 @@
     sdiv(result, ra, rb);
   } else {
     sdiv(scratch, ra, rb);
-    msub(result, scratch, rb, ra);
+    Assembler::msub(result, scratch, rb, ra);
   }
 
   return idivq_offset;
@@ -3787,14 +3787,6 @@
   }
 }
 
-  bool MacroAssembler::use_acq_rel_for_volatile_fields() {
-#ifdef PRODUCT
-    return false;
-#else
-    return UseAcqRelForVolatileFields;
-#endif
-  }
-
 void MacroAssembler::build_frame(int framesize) {
   if (framesize == 0) {
     // Is this even possible?
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Jul 05 20:32:48 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Tue May 12 13:58:42 2015 +0000
@@ -405,6 +405,18 @@
     umaddl(Rd, Rn, Rm, zr);
   }
 
+#define WRAP(INSN)                                                            \
+  void INSN(Register Rd, Register Rn, Register Rm, Register Ra) {             \
+    if ((VM_Version::cpu_cpuFeatures() & VM_Version::CPU_A53MAC) && Ra != zr) \
+      nop();                                                                  \
+    Assembler::INSN(Rd, Rn, Rm, Ra);                                          \
+  }
+
+  WRAP(madd) WRAP(msub) WRAP(maddw) WRAP(msubw)
+  WRAP(smaddl) WRAP(smsubl) WRAP(umaddl) WRAP(umsubl)
+#undef WRAP
+
+
   // macro assembly operations needed for aarch64
 
   // first two private routines for loading 32 bit or 64 bit constants
@@ -1094,9 +1106,6 @@
   address read_polling_page(Register r, address page, relocInfo::relocType rtype);
   address read_polling_page(Register r, relocInfo::relocType rtype);
 
-  // Used by aarch64.ad to control code generation
-  static bool use_acq_rel_for_volatile_fields();
-
   // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
   void update_byte_crc32(Register crc, Register val, Register table);
   void update_word_crc32(Register crc, Register v, Register tmp,
@@ -1150,10 +1159,6 @@
                             int offset, int size);
 };
 
-// Used by aarch64.ad to control code generation
-#define treat_as_volatile(MEM_NODE)                                     \
-  (MacroAssembler::use_acq_rel_for_volatile_fields() ? (MEM_NODE)->is_volatile() : false)
-
 #ifdef ASSERT
 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
 #endif
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Wed Jul 05 20:32:48 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Tue May 12 13:58:42 2015 +0000
@@ -59,6 +59,9 @@
 
 int VM_Version::_cpu;
 int VM_Version::_model;
+int VM_Version::_model2;
+int VM_Version::_variant;
+int VM_Version::_revision;
 int VM_Version::_stepping;
 int VM_Version::_cpuFeatures;
 const char*           VM_Version::_features_str = "";
@@ -122,13 +125,47 @@
 
   char buf[512];
 
-  strcpy(buf, "simd");
+  _cpuFeatures = auxv;
+
+  int cpu_lines = 0;
+  if (FILE *f = fopen("/proc/cpuinfo", "r")) {
+    char buf[128], *p;
+    while (fgets(buf, sizeof (buf), f) != NULL) {
+      if (p = strchr(buf, ':')) {
+        long v = strtol(p+1, NULL, 0);
+        if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) {
+          _cpu = v;
+          cpu_lines++;
+        } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) {
+          _variant = v;
+        } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) {
+          if (_model != v)  _model2 = _model;
+          _model = v;
+        } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
+          _revision = v;
+        }
+      }
+    }
+    fclose(f);
+  }
+
+  // Enable vendor specific features
+  if (_cpu == CPU_CAVIUM && _variant == 0) _cpuFeatures |= CPU_DMB_ATOMICS;
+  if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) _cpuFeatures |= CPU_A53MAC;
+  // If an olde style /proc/cpuinfo (cpu_lines == 1) then if _model is an A57 (0xd07)
+  // we assume the worst and assume we could be on a big little system and have
+  // undisclosed A53 cores which we could be swapped to at any stage
+  if (_cpu == CPU_ARM && cpu_lines == 1 && _model == 0xd07) _cpuFeatures |= CPU_A53MAC;
+
+  sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
+  if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2);
+  if (auxv & HWCAP_ASIMD) strcat(buf, ", simd");
   if (auxv & HWCAP_CRC32) strcat(buf, ", crc");
   if (auxv & HWCAP_AES)   strcat(buf, ", aes");
   if (auxv & HWCAP_SHA1)  strcat(buf, ", sha1");
   if (auxv & HWCAP_SHA2)  strcat(buf, ", sha256");
 
-  _features_str = strdup(buf);
+  _features_str = os::strdup(buf);
 
   if (FLAG_IS_DEFAULT(UseCRC32)) {
     UseCRC32 = (auxv & HWCAP_CRC32) != 0;
@@ -202,6 +239,10 @@
     UseMultiplyToLenIntrinsic = true;
   }
 
+  if (FLAG_IS_DEFAULT(UseBarriersForVolatile)) {
+    UseBarriersForVolatile = (_cpuFeatures & CPU_DMB_ATOMICS) != 0;
+  }
+
 #ifdef COMPILER2
   if (FLAG_IS_DEFAULT(OptoScheduling)) {
     OptoScheduling = true;
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp	Wed Jul 05 20:32:48 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp	Tue May 12 13:58:42 2015 +0000
@@ -34,6 +34,9 @@
 protected:
   static int _cpu;
   static int _model;
+  static int _model2;
+  static int _variant;
+  static int _revision;
   static int _stepping;
   static int _cpuFeatures;     // features returned by the "cpuid" instruction
                                // 0 if this instruction is not available
@@ -49,7 +52,40 @@
   static void assert_is_initialized() {
   }
 
+  enum {
+    CPU_ARM       = 'A',
+    CPU_BROADCOM  = 'B',
+    CPU_CAVIUM    = 'C',
+    CPU_DEC       = 'D',
+    CPU_INFINEON  = 'I',
+    CPU_MOTOROLA  = 'M',
+    CPU_NVIDIA    = 'N',
+    CPU_AMCC      = 'P',
+    CPU_QUALCOM   = 'Q',
+    CPU_MARVELL   = 'V',
+    CPU_INTEL     = 'i',
+  } cpuFamily;
+
+  enum {
+    CPU_FP           = (1<<0),
+    CPU_ASIMD        = (1<<1),
+    CPU_EVTSTRM      = (1<<2),
+    CPU_AES          = (1<<3),
+    CPU_PMULL        = (1<<4),
+    CPU_SHA1         = (1<<5),
+    CPU_SHA2         = (1<<6),
+    CPU_CRC32        = (1<<7),
+    CPU_A53MAC       = (1 << 30),
+    CPU_DMB_ATOMICS  = (1 << 31),
+  } cpuFeatureFlags;
+
   static const char* cpu_features()           { return _features_str; }
+  static int cpu_family()                     { return _cpu; }
+  static int cpu_model()                      { return _model; }
+  static int cpu_model2()                     { return _model2; }
+  static int cpu_variant()                    { return _variant; }
+  static int cpu_revision()                   { return _revision; }
+  static int cpu_cpuFeatures()                { return _cpuFeatures; }
 
 };