mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
JIT-compile bitfield stores
This commit implements compilation of bitfield stores. The generated IR is not good – in fact, it’s downright terrible – but it is certainly a big improvement over these operations being banished to the interpreter.
This commit is contained in:
parent
bc01981736
commit
bbec2d4760
@ -401,8 +401,20 @@ static int crec_isnonzero(CType *s, void *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
|
/* Load a C type from a bitfield ------------------------------------------ */
|
||||||
void *svisnz)
|
static TRef crec_bitfield_load(jit_State *J, CTypeID sid, TRef tr) {
|
||||||
|
uint32_t pos = ctype_bitpos(sid);
|
||||||
|
uint32_t bsz = ctype_bitbsz(sid);
|
||||||
|
CTSize shift = 32 - bsz;
|
||||||
|
lua_assert(ctype_isbitfield(sid));
|
||||||
|
lua_assert(bsz > 0 && "Zero sized bitfield is invalid");
|
||||||
|
tr = emitir(IRT(IR_BSHL, IRT_INT), tr, lj_ir_kint(J, shift - pos));
|
||||||
|
return emitir(IRT(IR_BSHR, IRT_INT), tr, lj_ir_kint(J, shift));
|
||||||
|
/* if crosses container boundary: interpreter will throw */
|
||||||
|
}
|
||||||
|
|
||||||
|
static TRef crec_ct_ct(jit_State *J, CType *d, CTypeID bitfield_val,
|
||||||
|
CType *s, TRef dp, TRef sp, void *svisnz)
|
||||||
{
|
{
|
||||||
IRType dt = crec_ct2irt(ctype_ctsG(J2G(J)), d);
|
IRType dt = crec_ct2irt(ctype_ctsG(J2G(J)), d);
|
||||||
IRType st = crec_ct2irt(ctype_ctsG(J2G(J)), s);
|
IRType st = crec_ct2irt(ctype_ctsG(J2G(J)), s);
|
||||||
@ -449,6 +461,23 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
|
|||||||
else if (st == IRT_INT)
|
else if (st == IRT_INT)
|
||||||
sp = lj_opt_narrow_toint(J, sp);
|
sp = lj_opt_narrow_toint(J, sp);
|
||||||
xstore:
|
xstore:
|
||||||
|
if (bitfield_val) {
|
||||||
|
CTSize bsz, pos;
|
||||||
|
TRef target;
|
||||||
|
CTSize shift;
|
||||||
|
TRef k, loaded;
|
||||||
|
lua_assert(ctype_isbitfield(bitfield_val));
|
||||||
|
bsz = ctype_bitbsz(bitfield_val);
|
||||||
|
pos = ctype_bitpos(bitfield_val);
|
||||||
|
k = lj_ir_kint(J, 8*pos);
|
||||||
|
target = emitir(IRT(IR_XLOAD, IRT_INT), dp, k);
|
||||||
|
shift = ~(((uint32_t)-1 >> (32 - bsz)) << pos);
|
||||||
|
lua_assert(bsz && "Zero sized bitfield is invalid!");
|
||||||
|
loaded = emitir(IRT(IR_BAND, IRT_INT), target, lj_ir_kint(J, shift));
|
||||||
|
sp = emitir(IRT(IR_BSHL, IRT_INT), sp, lj_ir_kint(J, pos));
|
||||||
|
sp = emitir(IRT(IR_BAND, IRT_INT), sp, lj_ir_kint(J, ~shift));
|
||||||
|
sp = emitir(IRT(IR_BOR, IRT_INT), sp, loaded);
|
||||||
|
}
|
||||||
if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J);
|
if (dt == IRT_I64 || dt == IRT_U64) lj_needsplit(J);
|
||||||
if (dp == 0) return sp;
|
if (dp == 0) return sp;
|
||||||
emitir(IRT(IR_XSTORE, dt), dp, sp);
|
emitir(IRT(IR_XSTORE, dt), dp, sp);
|
||||||
@ -558,22 +587,6 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load a C type from a bitfield ------------------------------------------ */
|
|
||||||
static TRef crec_bitfield_load(jit_State *J, CTypeID sid, TRef tr) {
|
|
||||||
uint32_t pos = ctype_bitpos(sid);
|
|
||||||
uint32_t bsz = ctype_bitbsz(sid);
|
|
||||||
lua_assert(ctype_isbitfield(sid));
|
|
||||||
lua_assert(bsz > 0 && "Zero sized bitfield is invalid");
|
|
||||||
if (!(sid & CTF_BOOL)) {
|
|
||||||
CTSize shift = 32 - bsz;
|
|
||||||
tr = emitir(IRT(IR_BSHL, IRT_INT), tr, lj_ir_kint(J, shift - pos));
|
|
||||||
return emitir(IRT(IR_BSHR, IRT_INT), tr, lj_ir_kint(J, shift));
|
|
||||||
/* if crosses container boundary: interpreter will throw */
|
|
||||||
} else {
|
|
||||||
lj_trace_err(J, LJ_TRERR_NYICONV);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Convert C type to TValue (load) ------------------------------------- */
|
/* -- Convert C type to TValue (load) ------------------------------------- */
|
||||||
|
|
||||||
static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
|
static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp)
|
||||||
@ -633,8 +646,8 @@ boolfield:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -- Convert TValue to C type (store) ------------------------------------ */
|
/* -- Convert TValue to C type (store) ------------------------------------ */
|
||||||
|
static TRef crec_ct_tv_(jit_State *J, CType *d, CTypeID bitfield_val, TRef dp,
|
||||||
static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
|
TRef sp, cTValue *sval)
|
||||||
{
|
{
|
||||||
CTState *cts = ctype_ctsG(J2G(J));
|
CTState *cts = ctype_ctsG(J2G(J));
|
||||||
CTypeID sid = CTID_P_VOID;
|
CTypeID sid = CTID_P_VOID;
|
||||||
@ -725,7 +738,11 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
|
|||||||
s = ctype_get(cts, sid);
|
s = ctype_get(cts, sid);
|
||||||
doconv:
|
doconv:
|
||||||
if (ctype_isenum(d->info)) d = ctype_child(cts, d);
|
if (ctype_isenum(d->info)) d = ctype_child(cts, d);
|
||||||
return crec_ct_ct(J, d, s, dp, sp, svisnz);
|
return crec_ct_ct(J, d, bitfield_val, s, dp, sp, svisnz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval) {
|
||||||
|
return crec_ct_tv_(J, d, 0, dp, sp, sval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- C data metamethods -------------------------------------------------- */
|
/* -- C data metamethods -------------------------------------------------- */
|
||||||
@ -876,8 +893,6 @@ again:
|
|||||||
J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
|
J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
|
||||||
return; /* Interpreter will throw for newindex. */
|
return; /* Interpreter will throw for newindex. */
|
||||||
} else if (ctype_isbitfield(fct->info)) {
|
} else if (ctype_isbitfield(fct->info)) {
|
||||||
if (rd->data != 0)
|
|
||||||
lj_trace_err(J, LJ_TRERR_NYICONV);
|
|
||||||
isbitfield = 1;
|
isbitfield = 1;
|
||||||
bitfield_val = fct->info;
|
bitfield_val = fct->info;
|
||||||
sid = ctype_underlying_type(bitfield_val);
|
sid = ctype_underlying_type(bitfield_val);
|
||||||
@ -930,7 +945,7 @@ again:
|
|||||||
} else { /* __newindex metamethod. */
|
} else { /* __newindex metamethod. */
|
||||||
rd->nres = 0;
|
rd->nres = 0;
|
||||||
J->needsnap = 1;
|
J->needsnap = 1;
|
||||||
crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]);
|
crec_ct_tv_(J, ct, bitfield_val, ptr, J->base[2], &rd->argv[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user