@@ -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,10 +752,8 @@ 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
@@ -769,6 +764,8 @@ static int riscv_zfa()
769764#if defined(__riscv_zfa )
770765 /* Don't bother checking for Zfa -- would crash before getting here. */
771766 return 1 ;
767+ #elif LJ_TARGET_LINUX
768+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZFA )) ? 1 : 0 ;
772769#else
773770 return 0 ;
774771#endif
@@ -782,23 +779,19 @@ static int riscv_xthead()
782779 && defined(__riscv_xtheadmac ))
783780 /* Don't bother checking for XThead -- would crash before getting here. */
784781 return 1 ;
785- #elif defined(__GNUC__ )
786- register int t asm ("a0" );
787- /* C906 & C910 & C908 all have "xtheadc", XTheadBb subset "xtheadc". */
788- /* Therefore assume XThead* are present if XTheadBb is present. */
789- /* addi a0, zero, 255; th.ext a0, a0, 7, 0; */
790- __asm__("addi a0, zero, 255\n\t.4byte 0x1c05250b" );
791- return t == -1 ; /* In case of collision with other vendor extensions. */
792782#else
793- return 0 ;
783+ /*
784+ ** Hardcoded as there's no easy way of detection:
785+ ** - SIGILL have some trouble with libluajit as we speak
786+ ** - Checking mvendorid looks good, but might not be reliable.
787+ */
788+ return 0 ;
794789#endif
795790}
796791
797792static uint32_t riscv_probe (int (* func )(void ), uint32_t flag )
798793{
799- if (sigsetjmp (sigbuf , 1 ) == 0 ) {
800- return func () ? flag : 0 ;
801- } else return 0 ;
794+ return func () ? flag : 0 ;
802795}
803796#endif
804797
@@ -877,17 +870,21 @@ static uint32_t jit_cpudetect(void)
877870
878871#elif LJ_TARGET_RISCV64
879872#if LJ_HASJIT
880- /* SIGILL-based detection of RVC, Zba, Zbb and XThead. Welcome to the future. */
881- struct sigaction old = {0 }, act = {0 };
882- act .sa_handler = detect_sigill ;
883- sigaction (SIGILL , & act , & old );
873+
874+ #if LJ_TARGET_LINUX
875+ /* HWPROBE-based detection of RVC, Zba, Zbb and Zicond. */
876+ hwprobe_ret = syscall (__NR_riscv_hwprobe , & hwprobe_requests ,
877+ sizeof (hwprobe_requests ) / sizeof (struct riscv_hwprobe ), 0 ,
878+ NULL , 0 );
879+
884880 flags |= riscv_probe (riscv_compressed , JIT_F_RVC );
885881 flags |= riscv_probe (riscv_zba , JIT_F_RVZba );
886882 flags |= riscv_probe (riscv_zbb , JIT_F_RVZbb );
887883 flags |= riscv_probe (riscv_zicond , JIT_F_RVZicond );
888884 flags |= riscv_probe (riscv_zfa , JIT_F_RVZfa );
889885 flags |= riscv_probe (riscv_xthead , JIT_F_RVXThead );
890- sigaction (SIGILL , & old , NULL );
886+
887+ #endif
891888
892889 /* Detect V/P? */
893890 /* V have no hardware available, P not ratified yet. */
0 commit comments