@@ -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,10 +752,8 @@ 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
@@ -769,30 +764,26 @@ static int riscv_zfa()
769
764
#if defined(__riscv_zfa )
770
765
/* Don't bother checking for Zfa -- would crash before getting here. */
771
766
return 1 ;
767
+ #elif LJ_TARGET_LINUX
768
+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZFA )) ? 1 : 0 ;
772
769
#else
773
770
return 0 ;
774
771
#endif
775
772
}
776
773
777
774
static int riscv_xthead ()
778
775
{
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 ;
789
782
}
790
783
791
784
static uint32_t riscv_probe (int (* func )(void ), uint32_t flag )
792
785
{
793
- if (sigsetjmp (sigbuf , 1 ) == 0 ) {
794
- return func () ? flag : 0 ;
795
- } else return 0 ;
786
+ return func () ? flag : 0 ;
796
787
}
797
788
#endif
798
789
@@ -871,17 +862,21 @@ static uint32_t jit_cpudetect(void)
871
862
872
863
#elif LJ_TARGET_RISCV64
873
864
#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
+
878
872
flags |= riscv_probe (riscv_compressed , JIT_F_RVC );
879
873
flags |= riscv_probe (riscv_zba , JIT_F_RVZba );
880
874
flags |= riscv_probe (riscv_zbb , JIT_F_RVZbb );
881
875
flags |= riscv_probe (riscv_zicond , JIT_F_RVZicond );
882
876
flags |= riscv_probe (riscv_zfa , JIT_F_RVZfa );
883
877
flags |= riscv_probe (riscv_xthead , JIT_F_RVXThead );
884
- sigaction (SIGILL , & old , NULL );
878
+
879
+ #endif
885
880
886
881
/* Detect V/P? */
887
882
/* V have no hardware available, P not ratified yet. */
0 commit comments