@@ -698,23 +698,26 @@ JIT_PARAMDEF(JIT_PARAMINIT)
698
698
#endif
699
699
700
700
#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
708
713
709
714
static int riscv_compressed ()
710
715
{
711
716
#if defined(__riscv_c ) || defined(__riscv_compressed )
712
717
/* Don't bother checking for RVC -- would crash before getting here. */
713
718
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 ;
718
721
#else
719
722
return 0 ;
720
723
#endif
@@ -725,11 +728,8 @@ static int riscv_zba()
725
728
#if defined(__riscv_b ) || defined(__riscv_zba )
726
729
/* Don't bother checking for Zba -- would crash before getting here. */
727
730
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 ;
733
733
#else
734
734
return 0 ;
735
735
#endif
@@ -740,11 +740,8 @@ static int riscv_zbb()
740
740
#if defined(__riscv_b ) || defined(__riscv_zbb )
741
741
/* Don't bother checking for Zbb -- would crash before getting here. */
742
742
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 ;
748
745
#else
749
746
return 0 ;
750
747
#endif
@@ -755,34 +752,26 @@ static int riscv_zicond()
755
752
#if defined(__riscv_zicond )
756
753
/* Don't bother checking for Zicond -- would crash before getting here. */
757
754
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 ;
762
757
#else
763
758
return 0 ;
764
759
#endif
765
760
}
766
761
767
762
static int riscv_xthead ()
768
763
{
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 ;
779
770
}
780
771
781
772
static uint32_t riscv_probe (int (* func )(void ), uint32_t flag )
782
773
{
783
- if (sigsetjmp (sigbuf , 1 ) == 0 ) {
784
- return func () ? flag : 0 ;
785
- } else return 0 ;
774
+ return func () ? flag : 0 ;
786
775
}
787
776
#endif
788
777
@@ -861,16 +850,20 @@ static uint32_t jit_cpudetect(void)
861
850
862
851
#elif LJ_TARGET_RISCV64
863
852
#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
+
868
860
flags |= riscv_probe (riscv_compressed , JIT_F_RVC );
869
861
flags |= riscv_probe (riscv_zba , JIT_F_RVZba );
870
862
flags |= riscv_probe (riscv_zbb , JIT_F_RVZbb );
871
863
flags |= riscv_probe (riscv_zicond , JIT_F_RVZicond );
872
864
flags |= riscv_probe (riscv_xthead , JIT_F_RVXThead );
873
- sigaction (SIGILL , & old , NULL );
865
+
866
+ #endif
874
867
875
868
/* Detect V/P? */
876
869
/* V have no hardware available, P not ratified yet. */
0 commit comments