@@ -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,30 +764,26 @@ 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
775772}
776773
777774static int riscv_xthead ()
778775{
779- #if defined(__GNUC__ )
780- register int t asm ("a0" );
781- /* C906 & C910 & C908 all have "xtheadc", XTheadBb subset "xtheadc". */
782- /* Therefore assume XThead* are present if XTheadBb is present. */
783- /* addi a0, zero, 255; th.ext a0, a0, 7, 0; */
784- __asm__("addi a0, zero, 255\n\t.4byte 0x1c05250b" );
785- return t == -1 ; /* In case of collision with other vendor extensions. */
786- #else
787- return 0 ;
788- #endif
776+ /*
777+ ** Hardcoded as there's no easy way of detection:
778+ ** - SIGILL have some trouble with libluajit as we speak
779+ ** - Checking mvendorid looks good, but might not be reliable.
780+ */
781+ return 0 ;
789782}
790783
791784static uint32_t riscv_probe (int (* func )(void ), uint32_t flag )
792785{
793- if (sigsetjmp (sigbuf , 1 ) == 0 ) {
794- return func () ? flag : 0 ;
795- } else return 0 ;
786+ return func () ? flag : 0 ;
796787}
797788#endif
798789
@@ -871,17 +862,21 @@ static uint32_t jit_cpudetect(void)
871862
872863#elif LJ_TARGET_RISCV64
873864#if LJ_HASJIT
874- /* SIGILL-based detection of RVC, Zba, Zbb and XThead. Welcome to the future. */
875- struct sigaction old = {0 }, act = {0 };
876- act .sa_handler = detect_sigill ;
877- sigaction (SIGILL , & act , & old );
865+
866+ #if LJ_TARGET_LINUX
867+ /* HWPROBE-based detection of RVC, Zba, Zbb and Zicond. */
868+ hwprobe_ret = syscall (__NR_riscv_hwprobe , & hwprobe_requests ,
869+ sizeof (hwprobe_requests ) / sizeof (struct riscv_hwprobe ), 0 ,
870+ NULL , 0 );
871+
878872 flags |= riscv_probe (riscv_compressed , JIT_F_RVC );
879873 flags |= riscv_probe (riscv_zba , JIT_F_RVZba );
880874 flags |= riscv_probe (riscv_zbb , JIT_F_RVZbb );
881875 flags |= riscv_probe (riscv_zicond , JIT_F_RVZicond );
882876 flags |= riscv_probe (riscv_zfa , JIT_F_RVZfa );
883877 flags |= riscv_probe (riscv_xthead , JIT_F_RVXThead );
884- sigaction (SIGILL , & old , NULL );
878+
879+ #endif
885880
886881 /* Detect V/P? */
887882 /* V have no hardware available, P not ratified yet. */
0 commit comments