vm_version_arm_64.cpp revision 12422:98fe046473c9
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
39bool VM_Version::_is_initialized = false;
40bool VM_Version::_has_simd = false;
41
42extern "C" {
43  typedef bool (*check_simd_t)();
44}
45
46
47#ifdef COMPILER2
48
49#define __ _masm->
50
51class 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
74extern "C" address check_simd_fault_instr;
75
76
77void 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
246bool 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}
259