Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RISC-V 64 Support for LuaJIT v2.1 #236

Open
wants to merge 22 commits into
base: v2.1-agentzh
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
34a74ff
riscv(support): add RISC-V 64 arch base definition
infiWang Mar 5, 2024
155917e
riscv(dynasm): add RISC-V support
infiWang Mar 5, 2024
3f2a9a2
riscv(interp): add register definition
infiWang Mar 5, 2024
ac5e7a8
riscv(interp): add frame definition
infiWang Mar 5, 2024
8a1761f
riscv(interp): add helper macros and typedefs
infiWang Mar 5, 2024
7dcaa4d
riscv(interp): add base assembly interpreter VM
infiWang Mar 6, 2024
eb87e6f
riscv(support): add target definition
infiWang Mar 6, 2024
ad11ee8
riscv(ffi): add call convention and support framework
infiWang Mar 6, 2024
e36801c
riscv(support): add extension detection
infiWang Mar 6, 2024
686ebf5
riscv(jit): add insn emitter
infiWang Mar 6, 2024
6cd6f3f
riscv(jit): add IR assembler
infiWang Mar 6, 2024
d8c992d
riscv(interp): add VM builder support
infiWang Mar 6, 2024
7a0691d
riscv(misc): add bytecode listing support
infiWang Mar 6, 2024
6f1f257
riscv(jit): add hooks in interpreter
infiWang Mar 6, 2024
ab2db4b
riscv(interp): add DWARF info
infiWang Mar 6, 2024
2e8e5ab
riscv(jit): add GDBJIT support
infiWang Mar 6, 2024
012b47e
riscv(support,linux): add Linux specfic icache sync codepath
infiWang Mar 6, 2024
2b0c38c
riscv(support,linux): make mremap() non-moving due to VA space woes
infiWang Mar 6, 2024
e425d91
riscv(misc): add disassmbler support
infiWang Mar 6, 2024
52af6d8
riscv(misc): add support in Makefile
infiWang Mar 6, 2024
9615a22
riscv(support,linux): use HWPROBE for ISE detection
infiWang Aug 21, 2024
ea214b2
riscv(interp): strip excessive extended branch (^B+J)
infiWang Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
riscv(support,linux): use HWPROBE for ISE detection
Current SIGILL handler appears to have weird issues with libluajit on
some platform. Considering 6.6 kernel is becoming more common, switch
to HWPROBE for better compatibility.
  • Loading branch information
infiWang committed Jan 23, 2025
commit 9615a2204ab9f28c926ccdfc07e7104a849f7db9
79 changes: 38 additions & 41 deletions src/lib_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,23 +698,26 @@ JIT_PARAMDEF(JIT_PARAMINIT)
#endif

#if LJ_TARGET_RISCV64 && LJ_TARGET_POSIX
#include <setjmp.h>
#include <signal.h>
static sigjmp_buf sigbuf = {0};
static void detect_sigill(int sig)
{
siglongjmp(sigbuf, 1);
}

#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 defined(__GNUC__)
/* c.nop; c.nop; */
__asm__(".4byte 0x00010001");
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_IMA_C)) ? 1 : 0;
#else
return 0;
#endif
Expand All @@ -725,11 +728,8 @@ 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 defined(__GNUC__)
/* Don't bother verifying the result, just check if the instruction exists. */
/* add.uw zero, zero, zero */
__asm__(".4byte 0x0800003b");
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_EXT_ZBA)) ? 1 : 0;
#else
return 0;
#endif
Expand All @@ -740,11 +740,8 @@ 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 defined(__GNUC__)
register int t asm ("a0");
/* addi a0, zero, 255; sext.b a0, a0; */
__asm__("addi a0, zero, 255\n\t.4byte 0x60451513");
return t < 0;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_EXT_ZBB)) ? 1 : 0;
#else
return 0;
#endif
Expand All @@ -755,10 +752,8 @@ static int riscv_zicond()
#if defined(__riscv_zicond)
/* Don't bother checking for Zicond -- would crash before getting here. */
return 1;
#elif defined(__GNUC__)
/* czero.eqz zero, zero, zero; */
__asm__(".4byte 0x0e005033");
return 1;
#elif LJ_TARGET_LINUX
return (hwprobe_ret == 0 && ((*hwprobe_ext) & RISCV_HWPROBE_EXT_ZICOND)) ? 1 : 0;
#else
return 0;
#endif
Expand All @@ -769,6 +764,8 @@ 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
Expand All @@ -782,23 +779,19 @@ static int riscv_xthead()
&& defined(__riscv_xtheadmac))
/* Don't bother checking for XThead -- would crash before getting here. */
return 1;
#elif defined(__GNUC__)
register int t asm ("a0");
/* C906 & C910 & C908 all have "xtheadc", XTheadBb subset "xtheadc". */
/* Therefore assume XThead* are present if XTheadBb is present. */
/* addi a0, zero, 255; th.ext a0, a0, 7, 0; */
__asm__("addi a0, zero, 255\n\t.4byte 0x1c05250b");
return t == -1; /* In case of collision with other vendor extensions. */
#else
return 0;
/*
** 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)
{
if (sigsetjmp(sigbuf, 1) == 0) {
return func() ? flag : 0;
} else return 0;
return func() ? flag : 0;
}
#endif

Expand Down Expand Up @@ -877,17 +870,21 @@ static uint32_t jit_cpudetect(void)

#elif LJ_TARGET_RISCV64
#if LJ_HASJIT
/* SIGILL-based detection of RVC, Zba, Zbb and XThead. Welcome to the future. */
struct sigaction old = {0}, act = {0};
act.sa_handler = detect_sigill;
sigaction(SIGILL, &act, &old);

#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);
sigaction(SIGILL, &old, NULL);

#endif

/* Detect V/P? */
/* V have no hardware available, P not ratified yet. */
Expand Down
29 changes: 29 additions & 0 deletions src/lj_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,35 @@

#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 ""
Expand Down