[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Starting a JIT backend for Ravi yet again
- From: Alexander Nasonov <alnsn@...>
- Date: Wed, 13 Sep 2017 23:06:08 +0100
Doug Currie wrote:
> Have you considered SLJIT?
>
> https://sourceforge.net/projects/sljit/
C API is very verbose. To see what I mean, take a look at my bpfjit code [1].
To address this issue, I started Lua bindings:
https://github.com/alnsn/luaSljit
but I never finished the project.
Emit calls are much shorter in Lua and you can easily emit one asm
instruction per line (unlike C which needs several lines).
For instance, this code will generate fast_divide32 function
local sljit = require 'sljit'
local mul, sh1, sh2 = ...
return sljit.create_compiler()
:emit_enter{args=1, saveds=1, scratches=1}
:emit_op2('MUL', 'R0', 'S0', sljit.imm(mul))
:emit_op2('LSHR', 'R0', 'R0', sljit.imm(32))
:emit_op2('ISUB', 'S0', 'S0', 'R0')
:emit_op2('ILSHR', 'S0', 'S0', sljit.imm(sh1))
:emit_op2('IADD', 'R0', 'R0', 'S0')
:emit_op2('ILSHR', 'R0', 'R0', sljit.imm(sh2))
:emit_return('MOV_UI', 'R0', 0)
:generate_code()
--
Alex
[1] https://github.com/alnsn/bpfjit/tree/master/src/bpfjit.c
It the function below, it's about 6 line per a single asm instruction.
/*
* Emit code for BPF_LD+BPF_H+BPF_ABS A <- P[k:2].
*/
static int
emit_read16(struct sljit_compiler *compiler, sljit_si src, uint32_t k)
{
int status;
BJ_ASSERT(k <= UINT32_MAX - 1);
/* A = buf[k]; */
status = sljit_emit_op1(compiler,
SLJIT_MOV_UB,
BJ_AREG, 0,
SLJIT_MEM1(src), k);
if (status != SLJIT_SUCCESS)
return status;
/* tmp1 = buf[k+1]; */
status = sljit_emit_op1(compiler,
SLJIT_MOV_UB,
BJ_TMP1REG, 0,
SLJIT_MEM1(src), k+1);
if (status != SLJIT_SUCCESS)
return status;
/* A = A << 8; */
status = sljit_emit_op2(compiler,
SLJIT_SHL,
BJ_AREG, 0,
BJ_AREG, 0,
SLJIT_IMM, 8);
if (status != SLJIT_SUCCESS)
return status;
/* A = A + tmp1; */
status = sljit_emit_op2(compiler,
SLJIT_ADD,
BJ_AREG, 0,
BJ_AREG, 0,
BJ_TMP1REG, 0);
return status;
}