mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
FFI: Compile bitfield loads/stores.
This commit is contained in:
parent
dc5eb65ccf
commit
fbfbd7b9e1
@ -448,8 +448,10 @@ int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp)
|
|||||||
setintV(o, (int32_t)val);
|
setintV(o, (int32_t)val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
uint32_t b = (val >> pos) & 1;
|
||||||
lua_assert(bsz == 1);
|
lua_assert(bsz == 1);
|
||||||
setboolV(o, (val >> pos) & 1);
|
setboolV(o, b);
|
||||||
|
setboolV(&cts->g->tmptv2, b); /* Remember for trace recorder. */
|
||||||
}
|
}
|
||||||
return 0; /* No GC step needed. */
|
return 0; /* No GC step needed. */
|
||||||
}
|
}
|
||||||
|
@ -751,6 +751,48 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Record bitfield load/store. */
|
||||||
|
static void crec_index_bf(jit_State *J, RecordFFData *rd, TRef ptr, CTInfo info)
|
||||||
|
{
|
||||||
|
IRType t = IRT_I8 + 2*lj_fls(ctype_bitcsz(info)) + ((info&CTF_UNSIGNED)?1:0);
|
||||||
|
TRef tr = emitir(IRT(IR_XLOAD, t), ptr, 0);
|
||||||
|
CTSize pos = ctype_bitpos(info), bsz = ctype_bitbsz(info), shift = 32 - bsz;
|
||||||
|
lua_assert(t <= IRT_U32); /* NYI: 64 bit bitfields. */
|
||||||
|
if (rd->data == 0) { /* __index metamethod. */
|
||||||
|
if ((info & CTF_BOOL)) {
|
||||||
|
tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << pos))));
|
||||||
|
/* Assume not equal to zero. Fixup and emit pending guard later. */
|
||||||
|
lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
|
||||||
|
J->postproc = LJ_POST_FIXGUARD;
|
||||||
|
tr = TREF_TRUE;
|
||||||
|
} else if (!(info & CTF_UNSIGNED)) {
|
||||||
|
tr = emitir(IRTI(IR_BSHL), tr, lj_ir_kint(J, shift - pos));
|
||||||
|
tr = emitir(IRTI(IR_BSAR), tr, lj_ir_kint(J, shift));
|
||||||
|
} else {
|
||||||
|
lua_assert(bsz < 32); /* Full-size fields cannot end up here. */
|
||||||
|
tr = emitir(IRTI(IR_BSHR), tr, lj_ir_kint(J, pos));
|
||||||
|
tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << bsz)-1)));
|
||||||
|
/* We can omit the U32 to NUM conversion, since bsz < 32. */
|
||||||
|
}
|
||||||
|
J->base[0] = tr;
|
||||||
|
} else { /* __newindex metamethod. */
|
||||||
|
CTState *cts = ctype_ctsG(J2G(J));
|
||||||
|
CType *ct = ctype_get(cts,
|
||||||
|
(info & CTF_BOOL) ? CTID_BOOL :
|
||||||
|
(info & CTF_UNSIGNED) ? CTID_UINT32 : CTID_INT32);
|
||||||
|
int32_t mask = (int32_t)(((1u << bsz)-1) << pos);
|
||||||
|
TRef sp = crec_ct_tv(J, ct, 0, J->base[2], &rd->argv[2]);
|
||||||
|
sp = emitir(IRTI(IR_BSHL), sp, lj_ir_kint(J, pos));
|
||||||
|
/* Use of the target type avoids forwarding conversions. */
|
||||||
|
sp = emitir(IRT(IR_BAND, t), sp, lj_ir_kint(J, mask));
|
||||||
|
tr = emitir(IRT(IR_BAND, t), tr, lj_ir_kint(J, (int32_t)~mask));
|
||||||
|
tr = emitir(IRT(IR_BOR, t), tr, sp);
|
||||||
|
emitir(IRT(IR_XSTORE, t), ptr, tr);
|
||||||
|
rd->nres = 0;
|
||||||
|
J->needsnap = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
|
void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
|
||||||
{
|
{
|
||||||
TRef idx, ptr = J->base[0];
|
TRef idx, ptr = J->base[0];
|
||||||
@ -825,6 +867,7 @@ again:
|
|||||||
CType *fct;
|
CType *fct;
|
||||||
fct = lj_ctype_getfield(cts, ct, name, &fofs);
|
fct = lj_ctype_getfield(cts, ct, name, &fofs);
|
||||||
if (fct) {
|
if (fct) {
|
||||||
|
ofs += (ptrdiff_t)fofs;
|
||||||
/* Always specialize to the field name. */
|
/* Always specialize to the field name. */
|
||||||
emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
|
emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
|
||||||
if (ctype_isconstval(fct->info)) {
|
if (ctype_isconstval(fct->info)) {
|
||||||
@ -836,12 +879,14 @@ 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)) {
|
||||||
lj_trace_err(J, LJ_TRERR_NYICONV);
|
if (ofs)
|
||||||
|
ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
|
||||||
|
crec_index_bf(J, rd, ptr, fct->info);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
lua_assert(ctype_isfield(fct->info));
|
lua_assert(ctype_isfield(fct->info));
|
||||||
sid = ctype_cid(fct->info);
|
sid = ctype_cid(fct->info);
|
||||||
}
|
}
|
||||||
ofs += (ptrdiff_t)fofs;
|
|
||||||
}
|
}
|
||||||
} else if (ctype_iscomplex(ct->info)) {
|
} else if (ctype_iscomplex(ct->info)) {
|
||||||
if (name->len == 2 &&
|
if (name->len == 2 &&
|
||||||
|
Loading…
Reference in New Issue
Block a user