Armv8.5 adds the FEAT_RNG feature so that true random numbers can be obtained from the cpu. This optimization is therefore proposed for the arm64 platform.
Signed-off-by: Tian Tao tiantao6@hisilicon.com --- stdlib/rand.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/stdlib/rand.c b/stdlib/rand.c index c250c065e4..f199dbd65f 100644 --- a/stdlib/rand.c +++ b/stdlib/rand.c @@ -19,10 +19,42 @@
#undef rand
+#ifdef __aarch64__ +// A global variable to indicate whether rndr instruction is supported +static int rndr_supported = 0; +// A function prototype to check rndr support +static void check_rndr_support (void) __attribute__ ((constructor)); +#endif
/* Return a random integer between 0 and RAND_MAX. */ int rand (void) { + // Use armv8.5 rndr instruction if supported +#ifdef __aarch64__ + if (rndr_supported) { + unsigned int r; + asm volatile("mrs %0, s3_3_c2_c4_0" : "=r" (r)); + // Discard the least random bit + r >>=1; + return (int) r; + } +#endif return (int) __random (); } + +#ifdef __aarch64__ +// A function to check rndr support and set the global variable accordingly +static void +check_rndr_support (void) +{ + unsigned long isar0; + // Read the ID_AA64ISAR0_EL1 register to check the rndr feature + asm volatile("mrs %0, id_aa64isar0_el1" : "=r" (isar0)); + // Check the bits [63:60] for the rndr feature + if ((isar0 >> 60) & 0xf) { + // Set the global variable to indicate rndr support + rndr_supported = 1; + } +} +#endif