1 /*
2 * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
4 * Copyright (c) 2023, Rivos Inc. All rights reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 */
26
27 #include "classfile/vmIntrinsics.hpp"
28 #include "runtime/java.hpp"
29 #include "runtime/os.inline.hpp"
30 #include "runtime/vm_version.hpp"
31 #include "utilities/formatBuffer.hpp"
32 #include "utilities/macros.hpp"
33
34 #include <ctype.h>
35
36 uint32_t VM_Version::_initial_vector_length = 0;
37
38 #define DEF_RV_EXT_FEATURE(PRETTY, LINUX_BIT, FSTRING, FLAGF) \
39 VM_Version::ext_##PRETTY##RVExtFeatureValue VM_Version::ext_##PRETTY;
40 RV_EXT_FEATURE_FLAGS(DEF_RV_EXT_FEATURE)
41 #undef DEF_RV_EXT_FEATURE
42
43 #define DEF_RV_NON_EXT_FEATURE(PRETTY, LINUX_BIT, FSTRING, FLAGF) \
44 VM_Version::PRETTY##RVNonExtFeatureValue VM_Version::PRETTY;
45 RV_NON_EXT_FEATURE_FLAGS(DEF_RV_NON_EXT_FEATURE)
46 #undef DEF_RV_NON_EXT_FEATURE
47
48 #define ADD_RV_EXT_FEATURE_IN_LIST(PRETTY, LINUX_BIT, FSTRING, FLAGF) \
49 &VM_Version::ext_##PRETTY,
50 #define ADD_RV_NON_EXT_FEATURE_IN_LIST(PRETTY, LINUX_BIT, FSTRING, FLAGF) \
51 &VM_Version::PRETTY,
52 VM_Version::RVFeatureValue* VM_Version::_feature_list[] = {
53 RV_EXT_FEATURE_FLAGS(ADD_RV_EXT_FEATURE_IN_LIST)
54 RV_NON_EXT_FEATURE_FLAGS(ADD_RV_NON_EXT_FEATURE_IN_LIST)
55 nullptr};
56 #undef ADD_RV_NON_EXT_FEATURE_IN_LIST
57 #undef ADD_RV_EXT_FEATURE_IN_LIST
58
59 VM_Version::RVExtFeatures* VM_Version::_rv_ext_features = new VM_Version::RVExtFeatures();
60
61 void VM_Version::useRVA20U64Profile() {
62 RV_USE_RVA20U64;
63 }
64
65 void VM_Version::useRVA22U64Profile() {
66 RV_USE_RVA22U64;
67 }
68
69 void VM_Version::useRVA23U64Profile() {
70 RV_USE_RVA23U64;
71 }
72
73 void VM_Version::initialize() {
74 common_initialize();
75 #ifdef COMPILER2
76 c2_initialize();
77 #endif // COMPILER2
78 }
79
80 void VM_Version::common_initialize() {
81 _supports_atomic_getset4 = true;
82 _supports_atomic_getadd4 = true;
83 _supports_atomic_getset8 = true;
84 _supports_atomic_getadd8 = true;
85
86 setup_cpu_available_features();
87
88 // check if satp.mode is supported, currently supports up to SV48(RV64)
89 if (satp_mode.value() > VM_SV48 || satp_mode.value() < VM_MBARE) {
90 vm_exit_during_initialization(
91 err_msg(
92 "Unsupported satp mode: SV%d. Only satp modes up to sv48 are supported for now.",
93 (int)satp_mode.value()));
94 }
95
96 if (UseRVA20U64) {
97 useRVA20U64Profile();
98 }
99 if (UseRVA22U64) {
100 useRVA22U64Profile();
101 }
102 if (UseRVA23U64) {
103 useRVA23U64Profile();
104 }
105
106 if (UseZic64b) {
107 if (CacheLineSize != 64) {
108 assert(!FLAG_IS_DEFAULT(CacheLineSize), "default cache line size should be 64 bytes");
109 warning("CacheLineSize is assumed to be 64 bytes because Zic64b is enabled");
110 FLAG_SET_DEFAULT(CacheLineSize, 64);
111 }
112 } else {
113 if (!FLAG_IS_DEFAULT(CacheLineSize) && !is_power_of_2(CacheLineSize)) {
114 warning("CacheLineSize must be a power of 2");
115 FLAG_SET_DEFAULT(CacheLineSize, DEFAULT_CACHE_LINE_SIZE);
116 }
117 }
118
119 if (FLAG_IS_DEFAULT(UseFMA)) {
120 FLAG_SET_DEFAULT(UseFMA, true);
121 }
122
123 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
124 FLAG_SET_DEFAULT(AllocatePrefetchDistance, 0);
125 }
126
127 if (UseVectorizedMismatchIntrinsic) {
128 warning("VectorizedMismatch intrinsic is not available on this CPU.");
129 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
130 }
131
132 if (FLAG_IS_DEFAULT(UseCopySignIntrinsic)) {
133 FLAG_SET_DEFAULT(UseCopySignIntrinsic, true);
134 }
135
136 if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) {
137 FLAG_SET_DEFAULT(UseSignumIntrinsic, true);
138 }
139
140 if (UseRVC && !ext_c.enabled()) {
141 warning("RVC is not supported on this CPU");
142 FLAG_SET_DEFAULT(UseRVC, false);
143
144 if (UseRVA20U64) {
145 warning("UseRVA20U64 is not supported on this CPU");
146 FLAG_SET_DEFAULT(UseRVA20U64, false);
147 }
148 }
149
150 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
151 FLAG_SET_DEFAULT(AvoidUnalignedAccesses,
152 unaligned_scalar.value() != MISALIGNED_SCALAR_FAST);
153 }
154
155 if (!AvoidUnalignedAccesses) {
156 if (FLAG_IS_DEFAULT(UsePoly1305Intrinsics)) {
157 FLAG_SET_DEFAULT(UsePoly1305Intrinsics, true);
158 }
159 } else if (UsePoly1305Intrinsics) {
160 warning("Intrinsics for Poly1305 crypto hash functions not available on this CPU.");
161 }
162
163 // See JDK-8026049
164 // This machine has fast unaligned memory accesses
165 if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
166 FLAG_SET_DEFAULT(UseUnalignedAccesses,
167 (unaligned_scalar.value() == MISALIGNED_SCALAR_FAST));
168 }
169
170 #ifdef __riscv_ztso
171 // Hotspot is compiled with TSO support, it will only run on hardware which
172 // supports Ztso
173 if (FLAG_IS_DEFAULT(UseZtso)) {
174 FLAG_SET_DEFAULT(UseZtso, true);
175 }
176 #endif
177
178 if (UseZbb) {
179 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
180 FLAG_SET_DEFAULT(UsePopCountInstruction, true);
181 }
182 } else {
183 FLAG_SET_DEFAULT(UsePopCountInstruction, false);
184 }
185
186 if (UseZicboz && zicboz_block_size.value() > 0) {
187 assert(is_power_of_2(zicboz_block_size.value()), "Sanity");
188 if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
189 FLAG_SET_DEFAULT(UseBlockZeroing, true);
190 }
191 if (FLAG_IS_DEFAULT(BlockZeroingLowLimit)) {
192 FLAG_SET_DEFAULT(BlockZeroingLowLimit, 4 * zicboz_block_size.value());
193 }
194 } else if (UseBlockZeroing) {
195 warning("Block zeroing is not available");
196 FLAG_SET_DEFAULT(UseBlockZeroing, false);
197 }
198
199 if (UseRVV) {
200 // read vector length from vector CSR vlenb
201 _initial_vector_length = cpu_vector_length();
202 }
203
204 // Misc Intrinsics that could depend on RVV.
205
206 if (!AvoidUnalignedAccesses && (UseZba || UseRVV)) {
207 if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
208 FLAG_SET_DEFAULT(UseCRC32Intrinsics, true);
209 }
210 } else {
211 if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
212 warning("CRC32 intrinsic are not available on this CPU.");
213 }
214 FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
215 }
216
217 if (UseCRC32CIntrinsics) {
218 warning("CRC32C intrinsics are not available on this CPU.");
219 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
220 }
221 }
222
223 #ifdef COMPILER2
224 void VM_Version::c2_initialize() {
225 if (!UseRVV) {
226 FLAG_SET_DEFAULT(MaxVectorSize, 0);
227 } else {
228 if (!FLAG_IS_DEFAULT(MaxVectorSize) && MaxVectorSize != _initial_vector_length) {
229 warning("Current system does not support RVV vector length for MaxVectorSize %d. Set MaxVectorSize to %d",
230 (int)MaxVectorSize, _initial_vector_length);
231 }
232 MaxVectorSize = _initial_vector_length;
233 if (MaxVectorSize < 16) {
234 warning("RVV does not support vector length less than 16 bytes. Disabling RVV.");
235 UseRVV = false;
236 FLAG_SET_DEFAULT(MaxVectorSize, 0);
237 }
238 }
239
240 if (FLAG_IS_DEFAULT(AlignVector)) {
241 FLAG_SET_DEFAULT(AlignVector,
242 unaligned_vector.value() != MISALIGNED_VECTOR_FAST);
243 }
244
245 // NOTE: Make sure codes dependent on UseRVV are put after MaxVectorSize initialize,
246 // as there are extra checks inside it which could disable UseRVV
247 // in some situations.
248
249 // Base64
250 if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) {
251 FLAG_SET_DEFAULT(UseBASE64Intrinsics, true);
252 }
253
254 if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) {
255 FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true);
256 }
257
258 if (!UseZicbop) {
259 if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
260 warning("Zicbop is not available on this CPU");
261 }
262 FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0);
263 } else {
264 // Limit AllocatePrefetchDistance so that it does not exceed the
265 // static constraint of 512 defined in runtime/globals.hpp.
266 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
267 FLAG_SET_DEFAULT(AllocatePrefetchDistance, MIN2(512, 3 * (int)CacheLineSize));
268 }
269 if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize)) {
270 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, (int)CacheLineSize);
271 }
272 if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) {
273 FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3 * (int)CacheLineSize);
274 }
275 if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes)) {
276 FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3 * (int)CacheLineSize);
277 }
278
279 if (PrefetchCopyIntervalInBytes != -1 &&
280 ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) {
281 warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768");
282 PrefetchCopyIntervalInBytes &= ~7;
283 if (PrefetchCopyIntervalInBytes >= 32768) {
284 PrefetchCopyIntervalInBytes = 32760;
285 }
286 }
287 if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) {
288 warning("AllocatePrefetchDistance must be multiple of 8");
289 AllocatePrefetchDistance &= ~7;
290 }
291 if (AllocatePrefetchStepSize & 7) {
292 warning("AllocatePrefetchStepSize must be multiple of 8");
293 AllocatePrefetchStepSize &= ~7;
294 }
295 }
296
297 if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
298 FLAG_SET_DEFAULT(UseMulAddIntrinsic, true);
299 }
300
301 if (!AvoidUnalignedAccesses) {
302 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
303 FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, true);
304 }
305 } else if (UseMultiplyToLenIntrinsic) {
306 warning("Intrinsics for BigInteger.multiplyToLen() not available on this CPU.");
307 FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, false);
308 }
309
310 if (!AvoidUnalignedAccesses) {
311 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
312 FLAG_SET_DEFAULT(UseSquareToLenIntrinsic, true);
313 }
314 } else if (UseSquareToLenIntrinsic) {
315 warning("Intrinsics for BigInteger.squareToLen() not available on this CPU.");
316 FLAG_SET_DEFAULT(UseSquareToLenIntrinsic, false);
317 }
318
319 if (!AvoidUnalignedAccesses) {
320 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
321 FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, true);
322 }
323 } else if (UseMontgomeryMultiplyIntrinsic) {
324 warning("Intrinsics for BigInteger.montgomeryMultiply() not available on this CPU.");
325 FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, false);
326 }
327
328 if (!AvoidUnalignedAccesses) {
329 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
330 FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, true);
331 }
332 } else if (UseMontgomerySquareIntrinsic) {
333 warning("Intrinsics for BigInteger.montgomerySquare() not available on this CPU.");
334 FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, false);
335 }
336
337 // Adler32
338 if (UseRVV) {
339 if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
340 FLAG_SET_DEFAULT(UseAdler32Intrinsics, true);
341 }
342 } else if (UseAdler32Intrinsics) {
343 if (!FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
344 warning("Adler32 intrinsic requires RVV instructions (not available on this CPU).");
345 }
346 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
347 }
348
349 // ChaCha20
350 if (UseRVV && MaxVectorSize >= 32) {
351 // performance tests on hardwares (MaxVectorSize == 16, 32) show that
352 // it brings regression when MaxVectorSize == 16.
353 if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
354 FLAG_SET_DEFAULT(UseChaCha20Intrinsics, true);
355 }
356 } else if (UseChaCha20Intrinsics) {
357 if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
358 warning("Chacha20 intrinsic requires RVV instructions (not available on this CPU)");
359 }
360 FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
361 }
362
363 if (!AvoidUnalignedAccesses) {
364 if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) {
365 FLAG_SET_DEFAULT(UseMD5Intrinsics, true);
366 }
367 } else if (UseMD5Intrinsics) {
368 warning("Intrinsics for MD5 crypto hash functions not available on this CPU.");
369 FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
370 }
371
372 // SHA's
373 if (FLAG_IS_DEFAULT(UseSHA)) {
374 FLAG_SET_DEFAULT(UseSHA, true);
375 }
376
377 // SHA-1, no RVV required though.
378 if (UseSHA && !AvoidUnalignedAccesses) {
379 if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
380 FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
381 }
382 } else if (UseSHA1Intrinsics) {
383 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
384 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
385 }
386
387 // SHA-2, depends on Zvkn.
388 if (UseSHA) {
389 if (UseZvkn) {
390 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
391 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
392 }
393 if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
394 FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
395 }
396 } else {
397 if (UseSHA256Intrinsics) {
398 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU, UseZvkn needed.");
399 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
400 }
401 if (UseSHA512Intrinsics) {
402 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU, UseZvkn needed.");
403 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
404 }
405 }
406 } else {
407 if (UseSHA256Intrinsics) {
408 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU, as UseSHA disabled.");
409 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
410 }
411 if (UseSHA512Intrinsics) {
412 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU, as UseSHA disabled.");
413 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
414 }
415 }
416
417 // SHA-3
418 if (UseSHA3Intrinsics) {
419 warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
420 FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
421 }
422
423 // AES
424 if (UseZvkn) {
425 UseAES = UseAES || FLAG_IS_DEFAULT(UseAES);
426 UseAESIntrinsics =
427 UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics));
428 if (UseAESIntrinsics && !UseAES) {
429 warning("UseAESIntrinsics enabled, but UseAES not, enabling");
430 UseAES = true;
431 }
432
433 if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics) && UseZbb) {
434 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true);
435 }
436
437 if (UseAESCTRIntrinsics && !UseZbb) {
438 warning("Cannot enable UseAESCTRIntrinsics on cpu without UseZbb support.");
439 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
440 }
441 } else {
442 if (UseAES) {
443 warning("AES instructions are not available on this CPU");
444 FLAG_SET_DEFAULT(UseAES, false);
445 }
446 if (UseAESIntrinsics) {
447 warning("AES intrinsics are not available on this CPU");
448 FLAG_SET_DEFAULT(UseAESIntrinsics, false);
449 }
450 if (UseAESCTRIntrinsics) {
451 warning("Cannot enable UseAESCTRIntrinsics on cpu without UseZvkn support.");
452 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
453 }
454 }
455
456 if (UseZvkg) {
457 if (FLAG_IS_DEFAULT(UseGHASHIntrinsics) && UseZvbb) {
458 FLAG_SET_DEFAULT(UseGHASHIntrinsics, true);
459 }
460
461 if (UseGHASHIntrinsics && !UseZvbb) {
462 warning("Cannot enable UseGHASHIntrinsics on cpu without UseZvbb support");
463 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
464 }
465 } else {
466 if (UseGHASHIntrinsics) {
467 warning("Cannot enable UseGHASHIntrinsics on cpu without UseZvkg support");
468 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
469 }
470 }
471 }
472
473 #endif // COMPILER2
474
475 void VM_Version::initialize_cpu_information(void) {
476 // do nothing if cpu info has been initialized
477 if (_initialized) {
478 return;
479 }
480
481 _no_of_cores = os::processor_count();
482 _no_of_threads = _no_of_cores;
483 _no_of_sockets = _no_of_cores;
484 os::snprintf_checked(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "RISCV64");
485 os::snprintf_checked(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "RISCV64 %s", cpu_info_string());
486 _initialized = true;
487 }
488
489 bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
490 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
491 switch (id) {
492 case vmIntrinsics::_floatToFloat16:
493 case vmIntrinsics::_float16ToFloat:
494 if (!supports_float16_float_conversion()) {
495 return false;
496 }
497 break;
498 default:
499 break;
500 }
501 return true;
502 }