@@ -698,23 +698,26 @@ JIT_PARAMDEF(JIT_PARAMINIT)
698698#endif
699699
700700#if LJ_TARGET_RISCV64 && LJ_TARGET_POSIX
701- #include <setjmp.h>
702- #include <signal.h>
703- static sigjmp_buf sigbuf = {0 };
704- static void detect_sigill (int sig )
705- {
706- siglongjmp (sigbuf , 1 );
707- }
701+
702+ #if LJ_TARGET_LINUX
703+ #include <unistd.h>
704+
705+ struct riscv_hwprobe hwprobe_requests [] = {
706+ {RISCV_HWPROBE_KEY_IMA_EXT_0 }
707+ };
708+
709+ const uint64_t * hwprobe_ext = & hwprobe_requests [0 ].value ;
710+
711+ int hwprobe_ret = 0 ;
712+ #endif
708713
709714static int riscv_compressed ()
710715{
711716#if defined(__riscv_c ) || defined(__riscv_compressed )
712717 /* Don't bother checking for RVC -- would crash before getting here. */
713718 return 1 ;
714- #elif defined(__GNUC__ )
715- /* c.nop; c.nop; */
716- __asm__(".4byte 0x00010001" );
717- return 1 ;
719+ #elif LJ_TARGET_LINUX
720+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_IMA_C )) ? 1 : 0 ;
718721#else
719722 return 0 ;
720723#endif
@@ -725,11 +728,8 @@ static int riscv_zba()
725728#if defined(__riscv_b ) || defined(__riscv_zba )
726729 /* Don't bother checking for Zba -- would crash before getting here. */
727730 return 1 ;
728- #elif defined(__GNUC__ )
729- /* Don't bother verifying the result, just check if the instruction exists. */
730- /* add.uw zero, zero, zero */
731- __asm__(".4byte 0x0800003b" );
732- return 1 ;
731+ #elif LJ_TARGET_LINUX
732+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZBA )) ? 1 : 0 ;
733733#else
734734 return 0 ;
735735#endif
@@ -740,11 +740,8 @@ static int riscv_zbb()
740740#if defined(__riscv_b ) || defined(__riscv_zbb )
741741 /* Don't bother checking for Zbb -- would crash before getting here. */
742742 return 1 ;
743- #elif defined(__GNUC__ )
744- register int t asm ("a0" );
745- /* addi a0, zero, 255; sext.b a0, a0; */
746- __asm__("addi a0, zero, 255\n\t.4byte 0x60451513" );
747- return t < 0 ;
743+ #elif LJ_TARGET_LINUX
744+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZBB )) ? 1 : 0 ;
748745#else
749746 return 0 ;
750747#endif
@@ -755,34 +752,26 @@ static int riscv_zicond()
755752#if defined(__riscv_zicond )
756753 /* Don't bother checking for Zicond -- would crash before getting here. */
757754 return 1 ;
758- #elif defined(__GNUC__ )
759- /* czero.eqz zero, zero, zero; */
760- __asm__(".4byte 0x0e005033" );
761- return 1 ;
755+ #elif LJ_TARGET_LINUX
756+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZICOND )) ? 1 : 0 ;
762757#else
763758 return 0 ;
764759#endif
765760}
766761
767762static int riscv_xthead ()
768763{
769- #if defined(__GNUC__ )
770- register int t asm ("a0" );
771- /* C906 & C910 & C908 all have "xtheadc", XTheadBb subset "xtheadc". */
772- /* Therefore assume XThead* are present if XTheadBb is present. */
773- /* addi a0, zero, 255; th.ext a0, a0, 7, 0; */
774- __asm__("addi a0, zero, 255\n\t.4byte 0x1c05250b" );
775- return t == -1 ; /* In case of collision with other vendor extensions. */
776- #else
777- return 0 ;
778- #endif
764+ /*
765+ ** Hardcoded as there's no easy way of detection:
766+ ** - SIGILL have some trouble with libluajit as we speak
767+ ** - Checking mvendorid looks good, but might not be reliable.
768+ */
769+ return 0 ;
779770}
780771
781772static uint32_t riscv_probe (int (* func )(void ), uint32_t flag )
782773{
783- if (sigsetjmp (sigbuf , 1 ) == 0 ) {
784- return func () ? flag : 0 ;
785- } else return 0 ;
774+ return func () ? flag : 0 ;
786775}
787776#endif
788777
@@ -861,16 +850,20 @@ static uint32_t jit_cpudetect(void)
861850
862851#elif LJ_TARGET_RISCV64
863852#if LJ_HASJIT
864- /* SIGILL-based detection of RVC, Zba, Zbb and XThead. Welcome to the future. */
865- struct sigaction old = {0 }, act = {0 };
866- act .sa_handler = detect_sigill ;
867- sigaction (SIGILL , & act , & old );
853+
854+ #if LJ_TARGET_LINUX
855+ /* HWPROBE-based detection of RVC, Zba, Zbb and Zicond. */
856+ hwprobe_ret = syscall (__NR_riscv_hwprobe , & hwprobe_requests ,
857+ sizeof (hwprobe_requests ) / sizeof (struct riscv_hwprobe ), 0 ,
858+ NULL , 0 );
859+
868860 flags |= riscv_probe (riscv_compressed , JIT_F_RVC );
869861 flags |= riscv_probe (riscv_zba , JIT_F_RVZba );
870862 flags |= riscv_probe (riscv_zbb , JIT_F_RVZbb );
871863 flags |= riscv_probe (riscv_zicond , JIT_F_RVZicond );
872864 flags |= riscv_probe (riscv_xthead , JIT_F_RVXThead );
873- sigaction (SIGILL , & old , NULL );
865+
866+ #endif
874867
875868 /* Detect V/P? */
876869 /* V have no hardware available, P not ratified yet. */
0 commit comments