Skip to content

Commit f7dd2ba

Browse files
committed
RISCV64: Add FFI and JIT support
Contributed by infiWang.
1 parent 7f34d48 commit f7dd2ba

11 files changed

+3650
-22
lines changed

src/jit/dis_riscv.lua

+930
Large diffs are not rendered by default.

src/jit/dis_riscv64.lua

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
----------------------------------------------------------------------------
2+
-- LuaJIT RISC-V 64 disassembler wrapper module.
3+
--
4+
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
5+
-- Released under the MIT license. See Copyright Notice in luajit.h
6+
----------------------------------------------------------------------------
7+
-- This module just exports the default riscv little-endian functions from the
8+
-- RISC-V disassembler module. All the interesting stuff is there.
9+
------------------------------------------------------------------------------
10+
11+
local dis_riscv = require((string.match(..., ".*%.") or "").."dis_riscv")
12+
return {
13+
create = dis_riscv.create,
14+
disass = dis_riscv.disass,
15+
regname = dis_riscv.regname
16+
}

src/lib_jit.c

+98-1
Original file line numberDiff line numberDiff line change
@@ -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. */
646724
static 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

src/lj_arch.h

-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,6 @@
439439
#define LJ_TARGET_MASKSHIFT 1
440440
#define LJ_TARGET_MASKROT 1
441441
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
442-
#define LJ_ARCH_NOJIT 1 /* NYI */
443442

444443
#define LJ_ARCH_NOMEMPROF 1
445444
#define LJ_ARCH_NOSYSPROF 1

src/lj_asm.c

+4
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ IRFLDEF(FLOFS)
185185
#include "lj_emit_ppc.h"
186186
#elif LJ_TARGET_MIPS
187187
#include "lj_emit_mips.h"
188+
#elif LJ_TARGET_RISCV64
189+
#include "lj_emit_riscv.h"
188190
#else
189191
#error "Missing instruction emitter for target CPU"
190192
#endif
@@ -1641,6 +1643,8 @@ static void asm_loop(ASMState *as)
16411643
#include "lj_asm_ppc.h"
16421644
#elif LJ_TARGET_MIPS
16431645
#include "lj_asm_mips.h"
1646+
#elif LJ_TARGET_RISCV64
1647+
#include "lj_asm_riscv64.h"
16441648
#else
16451649
#error "Missing assembler for target CPU"
16461650
#endif

0 commit comments

Comments
 (0)