# HG changeset patch # User enevill # Date 1431439122 0 # Node ID c980154ed1a3ab925629cc0969bf55442a2f23a0 # Parent 8ffdeabc7c2b9a8280bf46cae026ac46b4d31c26 8079203: AARCH64: Need to cater for different partner implementations Summary: Parse /proc/cpuinfo to derive implementation specific info Reviewed-by: kvn diff -r 8ffdeabc7c2b -r c980154ed1a3 hotspot/src/cpu/aarch64/vm/aarch64.ad --- 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; diff -r 8ffdeabc7c2b -r c980154ed1a3 hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp --- 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, \ diff -r 8ffdeabc7c2b -r c980154ed1a3 hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp --- 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, diff -r 8ffdeabc7c2b -r c980154ed1a3 hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp --- 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? diff -r 8ffdeabc7c2b -r c980154ed1a3 hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp --- 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 diff -r 8ffdeabc7c2b -r c980154ed1a3 hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp --- 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; diff -r 8ffdeabc7c2b -r c980154ed1a3 hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp --- 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; } };