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 }