1 /* 2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 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 #include "precompiled.hpp" 26 #include "asm/macroAssembler.inline.hpp" 27 #include "memory/resourceArea.hpp" 28 #include "runtime/java.hpp" 29 #include "runtime/os.inline.hpp" 30 #include "runtime/stubCodeGenerator.hpp" 31 #include "vm_version_arm.hpp" 32 #include <sys/auxv.h> 33 #include <asm/hwcap.h> 34 35 #ifndef HWCAP_AES 36 #define HWCAP_AES 1 << 3 37 #endif 38 39 bool VM_Version::_is_initialized = false; 40 bool VM_Version::_has_simd = false; 41 42 extern "C" { 43 typedef bool (*check_simd_t)(); 44 } 45 46 47 #ifdef COMPILER2 48 49 #define __ _masm-> 50 51 class VM_Version_StubGenerator: public StubCodeGenerator { 52 public: 53 54 VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} 55 56 address generate_check_simd() { 57 StubCodeMark mark(this, "VM_Version", "check_simd"); 58 address start = __ pc(); 59 60 __ vcnt(Stemp, Stemp); 61 __ mov(R0, 1); 62 __ ret(LR); 63 64 return start; 65 }; 66 }; 67 68 #undef __ 69 70 #endif 71 72 73 74 extern "C" address check_simd_fault_instr; 75 76 77 void VM_Version::initialize() { 78 ResourceMark rm; 79 80 // Making this stub must be FIRST use of assembler 81 const int stub_size = 128; 82 BufferBlob* stub_blob = BufferBlob::create("get_cpu_info", stub_size); 83 if (stub_blob == NULL) { 84 vm_exit_during_initialization("Unable to allocate get_cpu_info stub"); 85 } 86 87 if (UseFMA) { 88 warning("FMA instructions are not available on this CPU"); 89 FLAG_SET_DEFAULT(UseFMA, false); 90 } 91 92 if (UseSHA) { 93 warning("SHA instructions are not available on this CPU"); 94 FLAG_SET_DEFAULT(UseSHA, false); 95 } 96 97 if (UseSHA1Intrinsics) { 98 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU."); 99 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); 100 } 101 102 if (UseSHA256Intrinsics) { 103 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU."); 104 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); 105 } 106 107 if (UseSHA512Intrinsics) { 108 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU."); 109 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); 110 } 111 112 if (UseCRC32Intrinsics) { 113 if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics)) 114 warning("CRC32 intrinsics are not available on this CPU"); 115 FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); 116 } 117 118 if (UseCRC32CIntrinsics) { 119 if (!FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) 120 warning("CRC32C intrinsics are not available on this CPU"); 121 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); 122 } 123 124 if (UseAdler32Intrinsics) { 125 warning("Adler32 intrinsics are not available on this CPU"); 126 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false); 127 } 128 129 if (UseVectorizedMismatchIntrinsic) { 130 warning("vectorizedMismatch intrinsic is not available on this CPU."); 131 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); 132 } 133 134 CodeBuffer c(stub_blob); 135 136 #ifdef COMPILER2 137 VM_Version_StubGenerator g(&c); 138 139 address check_simd_pc = g.generate_check_simd(); 140 if (check_simd_pc != NULL) { 141 check_simd_t check_simd = CAST_TO_FN_PTR(check_simd_t, check_simd_pc); 142 check_simd_fault_instr = (address)check_simd; 143 _has_simd = check_simd(); 144 } else { 145 assert(! _has_simd, "default _has_simd value must be 'false'"); 146 } 147 #endif 148 149 unsigned long auxv = getauxval(AT_HWCAP); 150 151 char buf[512]; 152 jio_snprintf(buf, sizeof(buf), "AArch64%s", 153 ((auxv & HWCAP_AES) ? ", aes" : "")); 154 155 _features_string = os::strdup(buf); 156 157 #ifdef COMPILER2 158 if (auxv & HWCAP_AES) { 159 if (FLAG_IS_DEFAULT(UseAES)) { 160 FLAG_SET_DEFAULT(UseAES, true); 161 } 162 if (!UseAES) { 163 if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { 164 warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); 165 } 166 FLAG_SET_DEFAULT(UseAESIntrinsics, false); 167 } else { 168 if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { 169 FLAG_SET_DEFAULT(UseAESIntrinsics, true); 170 } 171 } 172 } else 173 #endif 174 if (UseAES || UseAESIntrinsics) { 175 if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { 176 warning("AES instructions are not available on this CPU"); 177 FLAG_SET_DEFAULT(UseAES, false); 178 } 179 if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { 180 warning("AES intrinsics are not available on this CPU"); 181 FLAG_SET_DEFAULT(UseAESIntrinsics, false); 182 } 183 } 184 185 if (UseAESCTRIntrinsics) { 186 warning("AES/CTR intrinsics are not available on this CPU"); 187 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); 188 } 189 190 _supports_cx8 = true; 191 _supports_atomic_getset4 = true; 192 _supports_atomic_getadd4 = true; 193 _supports_atomic_getset8 = true; 194 _supports_atomic_getadd8 = true; 195 196 // TODO-AARCH64 revise C2 flags 197 198 if (has_simd()) { 199 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) { 200 FLAG_SET_DEFAULT(UsePopCountInstruction, true); 201 } 202 } 203 204 AllocatePrefetchDistance = 128; 205 206 #ifdef COMPILER2 207 FLAG_SET_DEFAULT(UseFPUForSpilling, true); 208 209 if (FLAG_IS_DEFAULT(MaxVectorSize)) { 210 // FLAG_SET_DEFAULT(MaxVectorSize, has_simd() ? 16 : 8); 211 // SIMD/NEON can use 16, but default is 8 because currently 212 // larger than 8 will disable instruction scheduling 213 FLAG_SET_DEFAULT(MaxVectorSize, 8); 214 } 215 216 if (MaxVectorSize > 16) { 217 FLAG_SET_DEFAULT(MaxVectorSize, 8); 218 } 219 #endif 220 221 if (FLAG_IS_DEFAULT(Tier4CompileThreshold)) { 222 Tier4CompileThreshold = 10000; 223 } 224 if (FLAG_IS_DEFAULT(Tier3InvocationThreshold)) { 225 Tier3InvocationThreshold = 1000; 226 } 227 if (FLAG_IS_DEFAULT(Tier3CompileThreshold)) { 228 Tier3CompileThreshold = 5000; 229 } 230 if (FLAG_IS_DEFAULT(Tier3MinInvocationThreshold)) { 231 Tier3MinInvocationThreshold = 500; 232 } 233 234 FLAG_SET_DEFAULT(TypeProfileLevel, 0); // unsupported 235 236 // This machine does not allow unaligned memory accesses 237 if (UseUnalignedAccesses) { 238 if (!FLAG_IS_DEFAULT(UseUnalignedAccesses)) 239 warning("Unaligned memory access is not available on this CPU"); 240 FLAG_SET_DEFAULT(UseUnalignedAccesses, false); 241 } 242 243 _is_initialized = true; 244 } 245 246 bool VM_Version::use_biased_locking() { 247 // TODO-AARCH64 measure performance and revise 248 249 // The cost of CAS on uniprocessor ARM v6 and later is low compared to the 250 // overhead related to slightly longer Biased Locking execution path. 251 // Testing shows no improvement when running with Biased Locking enabled 252 // on an ARMv6 and higher uniprocessor systems. The situation is different on 253 // ARMv5 and MP systems. 254 // 255 // Therefore the Biased Locking is enabled on ARMv5 and ARM MP only. 256 // 257 return os::is_MP(); 258 }