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