Skip to content

Commit

Permalink
RISCV64: Add FFI and JIT support
Browse files Browse the repository at this point in the history
Contributed by infiWang.
  • Loading branch information
Buristan committed Dec 20, 2024
1 parent 1923338 commit 2178df1
Show file tree
Hide file tree
Showing 11 changed files with 3,650 additions and 22 deletions.
930 changes: 930 additions & 0 deletions src/jit/dis_riscv.lua

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions src/jit/dis_riscv64.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
----------------------------------------------------------------------------
-- LuaJIT RISC-V 64 disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the default riscv little-endian functions from the
-- RISC-V disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------

local dis_riscv = require((string.match(..., ".*%.") or "").."dis_riscv")
return {
create = dis_riscv.create,
disass = dis_riscv.disass,
regname = dis_riscv.regname
}
99 changes: 98 additions & 1 deletion src/lib_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,84 @@ 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_xthead()
{
/*
** 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;
}

static uint32_t riscv_probe(int (*func)(void), uint32_t flag)
{
return func() ? flag : 0;
}
#endif

/* Arch-dependent CPU detection. */
static uint32_t jit_cpudetect(lua_State *L)
{
Expand Down Expand Up @@ -729,7 +807,26 @@ static uint32_t jit_cpudetect(lua_State *L)
#endif
#endif
#elif LJ_TARGET_RISCV64
/* No optional CPU features to detect (for now). */
#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_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
Expand Down
1 change: 0 additions & 1 deletion src/lj_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,6 @@
#define LJ_TARGET_MASKSHIFT 1
#define LJ_TARGET_MASKROT 1
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
#define LJ_ARCH_NOJIT 1 /* NYI */

#define LJ_ARCH_NOMEMPROF 1
#define LJ_ARCH_NOSYSPROF 1
Expand Down
4 changes: 4 additions & 0 deletions src/lj_asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ IRFLDEF(FLOFS)
#include "lj_emit_ppc.h"
#elif LJ_TARGET_MIPS
#include "lj_emit_mips.h"
#elif LJ_TARGET_RISCV64
#include "lj_emit_riscv.h"
#else
#error "Missing instruction emitter for target CPU"
#endif
Expand Down Expand Up @@ -1641,6 +1643,8 @@ static void asm_loop(ASMState *as)
#include "lj_asm_ppc.h"
#elif LJ_TARGET_MIPS
#include "lj_asm_mips.h"
#elif LJ_TARGET_RISCV64
#include "lj_asm_riscv64.h"
#else
#error "Missing assembler for target CPU"
#endif
Expand Down
Loading

0 comments on commit 2178df1

Please sign in to comment.