mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
FFI: Record 64 bit integer comparisons and pointer comparisons.
This commit is contained in:
parent
83d8c86bbb
commit
f385af7084
@ -157,14 +157,13 @@ static int ffi_arith_ptr(lua_State *L, CTState *cts, FFIArith *fa, MMS mm)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!((mm == MM_add || mm == MM_sub) &&
|
if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(fa->ct[1]->info)))
|
||||||
ctype_isnum(fa->ct[1]->info))) return 0;
|
return 0;
|
||||||
lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[1],
|
lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[1],
|
||||||
(uint8_t *)&idx, fa->p[1], 0);
|
(uint8_t *)&idx, fa->p[1], 0);
|
||||||
if (mm == MM_sub) idx = -idx;
|
if (mm == MM_sub) idx = -idx;
|
||||||
} else if (mm == MM_add &&
|
} else if (mm == MM_add && ctype_isnum(ctp->info) &&
|
||||||
(ctype_isptr(fa->ct[1]->info) || ctype_isrefarray(fa->ct[1]->info))) {
|
(ctype_isptr(fa->ct[1]->info) || ctype_isrefarray(fa->ct[1]->info))) {
|
||||||
if (!ctype_isnum(ctp->info)) return 0;
|
|
||||||
/* Swap pointer and index. */
|
/* Swap pointer and index. */
|
||||||
ctp = fa->ct[1]; pp = fa->p[1];
|
ctp = fa->ct[1]; pp = fa->p[1];
|
||||||
lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[0],
|
lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[0],
|
||||||
@ -264,8 +263,10 @@ static int ffi_arith(lua_State *L)
|
|||||||
FFIArith fa;
|
FFIArith fa;
|
||||||
MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq);
|
MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq);
|
||||||
if (ffi_checkarith(L, cts, &fa)) {
|
if (ffi_checkarith(L, cts, &fa)) {
|
||||||
if (ffi_arith_int64(L, cts, &fa, mm) || ffi_arith_ptr(L, cts, &fa, mm))
|
if (ffi_arith_int64(L, cts, &fa, mm) || ffi_arith_ptr(L, cts, &fa, mm)) {
|
||||||
|
copyTV(L, &G(L)->tmptv2, L->top-1); /* Remember for trace recorder. */
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* NYI: per-cdata metamethods. */
|
/* NYI: per-cdata metamethods. */
|
||||||
{
|
{
|
||||||
@ -319,7 +320,7 @@ LJLIB_CF(ffi_meta___newindex) LJLIB_REC(cdata_index 1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The following functions must be in contiguous ORDER MM. */
|
/* The following functions must be in contiguous ORDER MM. */
|
||||||
LJLIB_CF(ffi_meta___eq)
|
LJLIB_CF(ffi_meta___eq) LJLIB_REC(cdata_arith MM_eq)
|
||||||
{
|
{
|
||||||
return ffi_arith(L);
|
return ffi_arith(L);
|
||||||
}
|
}
|
||||||
@ -329,12 +330,12 @@ LJLIB_CF(ffi_meta___len)
|
|||||||
return ffi_arith(L);
|
return ffi_arith(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
LJLIB_CF(ffi_meta___lt)
|
LJLIB_CF(ffi_meta___lt) LJLIB_REC(cdata_arith MM_lt)
|
||||||
{
|
{
|
||||||
return ffi_arith(L);
|
return ffi_arith(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
LJLIB_CF(ffi_meta___le)
|
LJLIB_CF(ffi_meta___le) LJLIB_REC(cdata_arith MM_le)
|
||||||
{
|
{
|
||||||
return ffi_arith(L);
|
return ffi_arith(L);
|
||||||
}
|
}
|
||||||
|
@ -2927,7 +2927,7 @@ static void asm_comp_(ASMState *as, IRIns *ir, int cc)
|
|||||||
IROp leftop = (IROp)(IR(lref)->o);
|
IROp leftop = (IROp)(IR(lref)->o);
|
||||||
Reg r64 = REX_64IR(ir, 0);
|
Reg r64 = REX_64IR(ir, 0);
|
||||||
int32_t imm = 0;
|
int32_t imm = 0;
|
||||||
lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t));
|
lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isaddr(ir->t));
|
||||||
/* Swap constants (only for ABC) and fusable loads to the right. */
|
/* Swap constants (only for ABC) and fusable loads to the right. */
|
||||||
if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
|
if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) {
|
||||||
if ((cc & 0xc) == 0xc) cc ^= 3; /* L <-> G, LE <-> GE */
|
if ((cc & 0xc) == 0xc) cc ^= 3; /* L <-> G, LE <-> GE */
|
||||||
|
@ -663,7 +663,20 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
|
|||||||
sp[i] = emitconv(sp[i], dt, IRT_INT,
|
sp[i] = emitconv(sp[i], dt, IRT_INT,
|
||||||
((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
|
((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
|
||||||
}
|
}
|
||||||
if (mm == MM_pow) {
|
if (mm < MM_add) {
|
||||||
|
/* Assume true comparison. Fixup and emit pending guard later. */
|
||||||
|
IROp op;
|
||||||
|
if (mm == MM_eq) {
|
||||||
|
op = IR_EQ;
|
||||||
|
} else {
|
||||||
|
op = mm == MM_lt ? IR_LT : IR_LE;
|
||||||
|
if (dt == IRT_U64)
|
||||||
|
op += (IR_ULT-IR_LT);
|
||||||
|
}
|
||||||
|
lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]);
|
||||||
|
J->postproc = LJ_POST_FIXGUARD;
|
||||||
|
return TREF_TRUE;
|
||||||
|
} else if (mm == MM_pow) {
|
||||||
tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1],
|
tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1],
|
||||||
lj_ir_kint(J, (int)dt-(int)IRT_I64));
|
lj_ir_kint(J, (int)dt-(int)IRT_I64));
|
||||||
} else {
|
} else {
|
||||||
@ -683,35 +696,41 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
|
|||||||
{
|
{
|
||||||
CTState *cts = ctype_ctsG(J2G(J));
|
CTState *cts = ctype_ctsG(J2G(J));
|
||||||
CType *ctp = s[0];
|
CType *ctp = s[0];
|
||||||
CTSize sz;
|
if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) {
|
||||||
if (!(mm == MM_add || mm == MM_sub))
|
if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) &&
|
||||||
return 0;
|
(ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
|
||||||
if (ctype_ispointer(ctp->info)) {
|
if (mm == MM_sub) { /* Pointer difference. */
|
||||||
sz = lj_ctype_size(cts, ctype_cid(ctp->info));
|
TRef tr;
|
||||||
if (mm == MM_sub && ctype_ispointer(s[1]->info)) {
|
CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
|
||||||
/* Pointer difference. */
|
if (sz == 0 || (sz & (sz-1)) != 0)
|
||||||
TRef tr;
|
return 0; /* NYI: integer division. */
|
||||||
if (sz == 0 || (sz & (sz-1)) != 0)
|
tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]);
|
||||||
return 0; /* NYI: integer division. */
|
tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
|
||||||
tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]);
|
|
||||||
tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
|
|
||||||
#if LJ_64
|
#if LJ_64
|
||||||
tr = emitconv(tr, IRT_NUM, IRT_INTP, 0);
|
tr = emitconv(tr, IRT_NUM, IRT_INTP, 0);
|
||||||
#endif
|
#endif
|
||||||
return tr;
|
return tr;
|
||||||
|
} else { /* Pointer comparison (unsigned). */
|
||||||
|
/* Assume true comparison. Fixup and emit pending guard later. */
|
||||||
|
IROp op = mm == MM_eq ? IR_EQ : mm == MM_lt ? IR_ULT : IR_ULE;
|
||||||
|
lj_ir_set(J, IRTG(op, IRT_PTR), sp[0], sp[1]);
|
||||||
|
J->postproc = LJ_POST_FIXGUARD;
|
||||||
|
return TREF_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!ctype_isnum(s[1]->info)) return 0;
|
if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(s[1]->info)))
|
||||||
} else if (mm == MM_add &&
|
return 0;
|
||||||
ctype_isnum(ctp->info) && ctype_ispointer(s[1]->info)) {
|
} else if (mm == MM_add && ctype_isnum(ctp->info) &&
|
||||||
|
(ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) {
|
||||||
TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */
|
TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */
|
||||||
ctp = s[1];
|
ctp = s[1];
|
||||||
sz = lj_ctype_size(cts, ctype_cid(ctp->info));
|
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TRef tr = sp[1];
|
TRef tr = sp[1];
|
||||||
IRType t = tref_type(tr);
|
IRType t = tref_type(tr);
|
||||||
|
CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info));
|
||||||
CTypeID id;
|
CTypeID id;
|
||||||
#if LJ_64
|
#if LJ_64
|
||||||
if (t == IRT_NUM || t == IRT_FLOAT)
|
if (t == IRT_NUM || t == IRT_FLOAT)
|
||||||
|
@ -819,6 +819,7 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
|
|||||||
/* Setup call to cdata comparison metamethod. */
|
/* Setup call to cdata comparison metamethod. */
|
||||||
static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm)
|
static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm)
|
||||||
{
|
{
|
||||||
|
lj_snap_add(J);
|
||||||
if (tref_iscdata(ix->val)) {
|
if (tref_iscdata(ix->val)) {
|
||||||
ix->tab = ix->val;
|
ix->tab = ix->val;
|
||||||
copyTV(J->L, &ix->tabv, &ix->valv);
|
copyTV(J->L, &ix->tabv, &ix->valv);
|
||||||
|
Loading…
Reference in New Issue
Block a user