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 }