riscv(support): add extension detection

This commit is contained in:
gns 2026-08-11 20:36:09 +08:00
parent 23d49c6973
commit 89e0d60ad0
2 changed files with 160 additions and 0 deletions

View File

@ -647,6 +647,104 @@ JIT_PARAMDEF(JIT_PARAMINIT)
#include <sys/utsname.h>
#endif
#if LJ_TARGET_RISCV64 && LJ_TARGET_POSIX
#if LJ_TARGET_LINUX
#include <unistd.h>
struct riscv_hwprobe hwprobe_requests[] = {
{RISCV_HWPROBE_KEY_IMA_EXT_0}
};
const uint64_t *hwprobe_ext = &hwprobe_requests[0].value;
int hwprobe_ret = 0;
#endif
static int riscv_compressed()
{
#if defined(__riscv_c) || defined(__riscv_compressed)
/* Don't bother checking for RVC -- would crash before getting here. */
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_IMA_C)) ? 1 : 0;
#else
return 0;
#endif
}
static int riscv_zba()
{
#if defined(__riscv_b) || defined(__riscv_zba)
/* Don't bother checking for Zba -- would crash before getting here. */
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_EXT_ZBA)) ? 1 : 0;
#else
return 0;
#endif
}
static int riscv_zbb()
{
#if defined(__riscv_b) || defined(__riscv_zbb)
/* Don't bother checking for Zbb -- would crash before getting here. */
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_EXT_ZBB)) ? 1 : 0;
#else
return 0;
#endif
}
static int riscv_zicond()
{
#if defined(__riscv_zicond)
/* Don't bother checking for Zicond -- would crash before getting here. */
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_EXT_ZICOND)) ? 1 : 0;
#else
return 0;
#endif
}
static int riscv_zfa()
{
#if defined(__riscv_zfa)
/* Don't bother checking for Zfa -- would crash before getting here. */
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_EXT_ZFA)) ? 1 : 0;
#else
return 0;
#endif
}
static int riscv_xthead()
{
#if (defined(__riscv_xtheadba) \
&& defined(__riscv_xtheadbb) \
&& defined(__riscv_xtheadcondmov) \
&& defined(__riscv_xtheadmac))
/* Don't bother checking for XThead -- would crash before getting here. */
return 1;
#else
/*
** Hardcoded as there's no easy way of detection:
** - SIGILL have some trouble with libluajit as we speak
** - Checking mvendorid looks good, but might not be reliable.
*/
return 0;
#endif
}
static uint32_t riscv_probe(int (*func)(void), uint32_t flag)
{
return func() ? flag : 0;
}
#endif
/* Arch-dependent CPU feature detection. */
static uint32_t jit_cpudetect(void)
{
@ -724,6 +822,28 @@ static uint32_t jit_cpudetect(void)
}
#endif
#elif LJ_TARGET_RISCV64
#if LJ_HASJIT
#if LJ_TARGET_LINUX
/* HWPROBE-based detection of RVC, Zba, Zbb and Zicond. */
hwprobe_ret = syscall(__NR_riscv_hwprobe, &hwprobe_requests,
sizeof(hwprobe_requests) / sizeof(struct riscv_hwprobe), 0,
NULL, 0);
flags |= riscv_probe(riscv_compressed, JIT_F_RVC);
flags |= riscv_probe(riscv_zba, JIT_F_RVZba);
flags |= riscv_probe(riscv_zbb, JIT_F_RVZbb);
flags |= riscv_probe(riscv_zicond, JIT_F_RVZicond);
flags |= riscv_probe(riscv_zfa, JIT_F_RVZfa);
flags |= riscv_probe(riscv_xthead, JIT_F_RVXThead);
#endif
/* Detect V/P? */
/* V have no hardware available, P not ratified yet. */
#endif
#else
#error "Missing CPU detection for this architecture"
#endif

View File

@ -67,6 +67,46 @@
#endif
#endif
#elif LJ_TARGET_RISCV64
#define JIT_F_RVC (JIT_F_CPU << 0)
#define JIT_F_RVZba (JIT_F_CPU << 1)
#define JIT_F_RVZbb (JIT_F_CPU << 2)
#define JIT_F_RVZicond (JIT_F_CPU << 3)
#define JIT_F_RVZfa (JIT_F_CPU << 4)
#define JIT_F_RVXThead (JIT_F_CPU << 5)
#define JIT_F_CPUSTRING "\003RVC\003Zba\003Zbb\006Zicond\003Zfa\006XThead"
#if LJ_TARGET_LINUX
#include <sys/syscall.h>
#ifndef __NR_riscv_hwprobe
#ifndef __NR_arch_specific_syscall
#define __NR_arch_specific_syscall 244
#endif
#define __NR_riscv_hwprobe (__NR_arch_specific_syscall + 14)
#endif
struct riscv_hwprobe {
int64_t key;
uint64_t value;
};
#define RISCV_HWPROBE_KEY_MVENDORID 0
#define RISCV_HWPROBE_KEY_MARCHID 1
#define RISCV_HWPROBE_KEY_MIMPID 2
#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
#define RISCV_HWPROBE_IMA_C (1 << 1)
#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
#endif
#else
#define JIT_F_CPUSTRING ""