1 /*
2 * Copyright (c) 1997, 2026, 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 if (InlineTypePassFieldsAsArgs) {
223 warning("InlineTypePassFieldsAsArgs is not supported on this CPU");
224 FLAG_SET_DEFAULT(InlineTypePassFieldsAsArgs, false);
225 }
226 if (InlineTypeReturnedAsFields) {
227 warning("InlineTypeReturnedAsFields is not supported on this CPU");
228 FLAG_SET_DEFAULT(InlineTypeReturnedAsFields, false);
229 }
230 }
231
232 #ifdef COMPILER2
233 void VM_Version::c2_initialize() {
234 if (!UseRVV) {
235 FLAG_SET_DEFAULT(MaxVectorSize, 0);
236 } else {
237 if (!FLAG_IS_DEFAULT(MaxVectorSize) && MaxVectorSize != _initial_vector_length) {
238 warning("Current system does not support RVV vector length for MaxVectorSize %d. Set MaxVectorSize to %d",
239 (int)MaxVectorSize, _initial_vector_length);
240 }
241 MaxVectorSize = _initial_vector_length;
242 if (MaxVectorSize < 16) {
243 warning("RVV does not support vector length less than 16 bytes. Disabling RVV.");
244 UseRVV = false;
245 FLAG_SET_DEFAULT(MaxVectorSize, 0);
246 }
247 }
248
249 if (FLAG_IS_DEFAULT(AlignVector)) {
250 FLAG_SET_DEFAULT(AlignVector,
251 unaligned_vector.value() != MISALIGNED_VECTOR_FAST);
252 }
253
254 // NOTE: Make sure codes dependent on UseRVV are put after MaxVectorSize initialize,
255 // as there are extra checks inside it which could disable UseRVV
256 // in some situations.
257
258 // Base64
259 if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) {
260 FLAG_SET_DEFAULT(UseBASE64Intrinsics, true);
261 }
262
263 if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) {
264 FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true);
265 }
266
267 if (!UseZicbop) {
268 if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
269 warning("Zicbop is not available on this CPU");
270 }
271 FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0);
272 } else {
273 // Limit AllocatePrefetchDistance so that it does not exceed the
274 // static constraint of 512 defined in runtime/globals.hpp.
275 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
276 FLAG_SET_DEFAULT(AllocatePrefetchDistance, MIN2(512, 3 * (int)CacheLineSize));
277 }
278 if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize)) {
279 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, (int)CacheLineSize);
280 }
281 if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) {
282 FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3 * (int)CacheLineSize);
283 }
284 if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes)) {
285 FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3 * (int)CacheLineSize);
286 }
287
288 if (PrefetchCopyIntervalInBytes != -1 &&
289 ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) {
290 warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768");
291 PrefetchCopyIntervalInBytes &= ~7;
292 if (PrefetchCopyIntervalInBytes >= 32768) {
293 PrefetchCopyIntervalInBytes = 32760;
294 }
295 }
296 if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) {
297 warning("AllocatePrefetchDistance must be multiple of 8");
298 AllocatePrefetchDistance &= ~7;
299 }
300 if (AllocatePrefetchStepSize & 7) {
301 warning("AllocatePrefetchStepSize must be multiple of 8");
302 AllocatePrefetchStepSize &= ~7;
303 }
304 }
305
306 if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
307 FLAG_SET_DEFAULT(UseMulAddIntrinsic, true);
308 }
309
310 if (!AvoidUnalignedAccesses) {
311 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
312 FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, true);
313 }
314 } else if (UseMultiplyToLenIntrinsic) {
315 warning("Intrinsics for BigInteger.multiplyToLen() not available on this CPU.");
316 FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, false);
317 }
318
319 if (!AvoidUnalignedAccesses) {
320 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
321 FLAG_SET_DEFAULT(UseSquareToLenIntrinsic, true);
322 }
323 } else if (UseSquareToLenIntrinsic) {
324 warning("Intrinsics for BigInteger.squareToLen() not available on this CPU.");
325 FLAG_SET_DEFAULT(UseSquareToLenIntrinsic, false);
326 }
327
328 if (!AvoidUnalignedAccesses) {
329 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
330 FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, true);
331 }
332 } else if (UseMontgomeryMultiplyIntrinsic) {
333 warning("Intrinsics for BigInteger.montgomeryMultiply() not available on this CPU.");
334 FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, false);
335 }
336
337 if (!AvoidUnalignedAccesses) {
338 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
339 FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, true);
340 }
341 } else if (UseMontgomerySquareIntrinsic) {
342 warning("Intrinsics for BigInteger.montgomerySquare() not available on this CPU.");
343 FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, false);
344 }
345
346 // Adler32
347 if (UseRVV) {
348 if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
349 FLAG_SET_DEFAULT(UseAdler32Intrinsics, true);
350 }
351 } else if (UseAdler32Intrinsics) {
352 if (!FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
353 warning("Adler32 intrinsic requires RVV instructions (not available on this CPU).");
354 }
355 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
356 }
357
358 // ChaCha20
359 if (UseRVV && MaxVectorSize >= 32) {
360 // performance tests on hardwares (MaxVectorSize == 16, 32) show that
361 // it brings regression when MaxVectorSize == 16.
362 if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
363 FLAG_SET_DEFAULT(UseChaCha20Intrinsics, true);
364 }
365 } else if (UseChaCha20Intrinsics) {
366 if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
367 warning("Chacha20 intrinsic requires RVV instructions (not available on this CPU)");
368 }
369 FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
370 }
371
372 if (!AvoidUnalignedAccesses) {
373 if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) {
374 FLAG_SET_DEFAULT(UseMD5Intrinsics, true);
375 }
376 } else if (UseMD5Intrinsics) {
377 warning("Intrinsics for MD5 crypto hash functions not available on this CPU.");
378 FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
379 }
380
381 // SHA's
382 if (FLAG_IS_DEFAULT(UseSHA)) {
383 FLAG_SET_DEFAULT(UseSHA, true);
384 }
385
386 // SHA-1, no RVV required though.
387 if (UseSHA && !AvoidUnalignedAccesses) {
388 if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
389 FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
390 }
391 } else if (UseSHA1Intrinsics) {
392 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
393 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
394 }
395
396 // SHA-2, depends on Zvkn.
397 if (UseSHA) {
398 if (UseZvkn) {
399 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
400 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
401 }
402 if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
403 FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
404 }
405 } else {
406 if (UseSHA256Intrinsics) {
407 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU, UseZvkn needed.");
408 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
409 }
410 if (UseSHA512Intrinsics) {
411 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU, UseZvkn needed.");
412 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
413 }
414 }
415 } else {
416 if (UseSHA256Intrinsics) {
417 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU, as UseSHA disabled.");
418 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
419 }
420 if (UseSHA512Intrinsics) {
421 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU, as UseSHA disabled.");
422 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
423 }
424 }
425
426 // SHA-3
427 if (UseSHA3Intrinsics) {
428 warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
429 FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
430 }
431
432 // AES
433 if (UseZvkn) {
434 UseAES = UseAES || FLAG_IS_DEFAULT(UseAES);
435 UseAESIntrinsics =
436 UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics));
437 if (UseAESIntrinsics && !UseAES) {
438 warning("UseAESIntrinsics enabled, but UseAES not, enabling");
439 UseAES = true;
440 }
441
442 if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics) && UseZbb) {
443 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true);
444 }
445
446 if (UseAESCTRIntrinsics && !UseZbb) {
447 warning("Cannot enable UseAESCTRIntrinsics on cpu without UseZbb support.");
448 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
449 }
450 } else {
451 if (UseAES) {
452 warning("AES instructions are not available on this CPU");
453 FLAG_SET_DEFAULT(UseAES, false);
454 }
455 if (UseAESIntrinsics) {
456 warning("AES intrinsics are not available on this CPU");
457 FLAG_SET_DEFAULT(UseAESIntrinsics, false);
458 }
459 if (UseAESCTRIntrinsics) {
460 warning("Cannot enable UseAESCTRIntrinsics on cpu without UseZvkn support.");
461 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
462 }
463 }
464
465 if (UseZvkg) {
466 if (FLAG_IS_DEFAULT(UseGHASHIntrinsics) && UseZvbb) {
467 FLAG_SET_DEFAULT(UseGHASHIntrinsics, true);
468 }
469
470 if (UseGHASHIntrinsics && !UseZvbb) {
471 warning("Cannot enable UseGHASHIntrinsics on cpu without UseZvbb support");
472 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
473 }
474 } else {
475 if (UseGHASHIntrinsics) {
476 warning("Cannot enable UseGHASHIntrinsics on cpu without UseZvkg support");
477 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
478 }
479 }
480 }
481
482 #endif // COMPILER2
483
484 void VM_Version::initialize_cpu_information(void) {
485 // do nothing if cpu info has been initialized
486 if (_initialized) {
487 return;
488 }
489
490 _no_of_cores = os::processor_count();
491 _no_of_threads = _no_of_cores;
492 _no_of_sockets = _no_of_cores;
493 os::snprintf_checked(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "RISCV64");
494 os::snprintf_checked(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "RISCV64 %s", cpu_info_string());
495 _initialized = true;
496 }
497
498 bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
499 assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
500 switch (id) {
501 case vmIntrinsics::_floatToFloat16:
502 case vmIntrinsics::_float16ToFloat:
503 if (!supports_float16_float_conversion()) {
504 return false;
505 }
506 break;
507 default:
508 break;
509 }
510 return true;
511 }