@@ -642,6 +642,84 @@ JIT_PARAMDEF(JIT_PARAMINIT)
642642#include <sys/utsname.h>
643643#endif
644644
645+ #if LJ_TARGET_RISCV64 && LJ_TARGET_POSIX
646+
647+ #if LJ_TARGET_LINUX
648+ #include <unistd.h>
649+
650+ struct riscv_hwprobe hwprobe_requests [] = {
651+ {RISCV_HWPROBE_KEY_IMA_EXT_0 }
652+ };
653+
654+ const uint64_t * hwprobe_ext = & hwprobe_requests [0 ].value ;
655+
656+ int hwprobe_ret = 0 ;
657+ #endif
658+
659+ static int riscv_compressed ()
660+ {
661+ #if defined(__riscv_c ) || defined(__riscv_compressed )
662+ /* Don't bother checking for RVC -- would crash before getting here. */
663+ return 1 ;
664+ #elif LJ_TARGET_LINUX
665+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_IMA_C )) ? 1 : 0 ;
666+ #else
667+ return 0 ;
668+ #endif
669+ }
670+
671+ static int riscv_zba ()
672+ {
673+ #if defined(__riscv_b ) || defined(__riscv_zba )
674+ /* Don't bother checking for Zba -- would crash before getting here. */
675+ return 1 ;
676+ #elif LJ_TARGET_LINUX
677+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZBA )) ? 1 : 0 ;
678+ #else
679+ return 0 ;
680+ #endif
681+ }
682+
683+ static int riscv_zbb ()
684+ {
685+ #if defined(__riscv_b ) || defined(__riscv_zbb )
686+ /* Don't bother checking for Zbb -- would crash before getting here. */
687+ return 1 ;
688+ #elif LJ_TARGET_LINUX
689+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZBB )) ? 1 : 0 ;
690+ #else
691+ return 0 ;
692+ #endif
693+ }
694+
695+ static int riscv_zicond ()
696+ {
697+ #if defined(__riscv_zicond )
698+ /* Don't bother checking for Zicond -- would crash before getting here. */
699+ return 1 ;
700+ #elif LJ_TARGET_LINUX
701+ return (hwprobe_ret == 0 && ((* hwprobe_ext ) & RISCV_HWPROBE_EXT_ZICOND )) ? 1 : 0 ;
702+ #else
703+ return 0 ;
704+ #endif
705+ }
706+
707+ static int riscv_xthead ()
708+ {
709+ /*
710+ ** Hardcoded as there's no easy way of detection:
711+ ** - SIGILL have some trouble with libluajit as we speak
712+ ** - Checking mvendorid looks good, but might not be reliable.
713+ */
714+ return 0 ;
715+ }
716+
717+ static uint32_t riscv_probe (int (* func )(void ), uint32_t flag )
718+ {
719+ return func () ? flag : 0 ;
720+ }
721+ #endif
722+
645723/* Arch-dependent CPU detection. */
646724static uint32_t jit_cpudetect (lua_State * L )
647725{
@@ -729,7 +807,26 @@ static uint32_t jit_cpudetect(lua_State *L)
729807#endif
730808#endif
731809#elif LJ_TARGET_RISCV64
732- /* No optional CPU features to detect (for now). */
810+ #if LJ_HASJIT
811+
812+ #if LJ_TARGET_LINUX
813+ /* HWPROBE-based detection of RVC, Zba, Zbb and Zicond. */
814+ hwprobe_ret = syscall (__NR_riscv_hwprobe , & hwprobe_requests ,
815+ sizeof (hwprobe_requests ) / sizeof (struct riscv_hwprobe ), 0 ,
816+ NULL , 0 );
817+
818+ flags |= riscv_probe (riscv_compressed , JIT_F_RVC );
819+ flags |= riscv_probe (riscv_zba , JIT_F_RVZba );
820+ flags |= riscv_probe (riscv_zbb , JIT_F_RVZbb );
821+ flags |= riscv_probe (riscv_zicond , JIT_F_RVZicond );
822+ flags |= riscv_probe (riscv_xthead , JIT_F_RVXThead );
823+
824+ #endif
825+
826+ /* Detect V/P? */
827+ /* V have no hardware available, P not ratified yet. */
828+ #endif
829+
733830#else
734831#error "Missing CPU detection for this architecture"
735832#endif
0 commit comments