mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
Embed 64 bit constants directly in the IR, using two slots.
Contributed by Peter Cawley.
This commit is contained in:
parent
a4067978b6
commit
7fb75ccc4c
17
src/lj_asm.c
17
src/lj_asm.c
@ -334,7 +334,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
|
|||||||
RA_DBGX((as, "remat $i $r", ir, r));
|
RA_DBGX((as, "remat $i $r", ir, r));
|
||||||
#if !LJ_SOFTFP
|
#if !LJ_SOFTFP
|
||||||
if (ir->o == IR_KNUM) {
|
if (ir->o == IR_KNUM) {
|
||||||
emit_loadn(as, r, ir_knum(ir));
|
emit_loadk64(as, r, ir);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (emit_canremat(REF_BASE) && ir->o == IR_BASE) {
|
if (emit_canremat(REF_BASE) && ir->o == IR_BASE) {
|
||||||
@ -695,15 +695,14 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref)
|
|||||||
if (ra_noreg(left)) {
|
if (ra_noreg(left)) {
|
||||||
if (irref_isk(lref)) {
|
if (irref_isk(lref)) {
|
||||||
if (ir->o == IR_KNUM) {
|
if (ir->o == IR_KNUM) {
|
||||||
cTValue *tv = ir_knum(ir);
|
|
||||||
/* FP remat needs a load except for +0. Still better than eviction. */
|
/* FP remat needs a load except for +0. Still better than eviction. */
|
||||||
if (tvispzero(tv) || !(as->freeset & RSET_FPR)) {
|
if (tvispzero(ir_knum(ir)) || !(as->freeset & RSET_FPR)) {
|
||||||
emit_loadn(as, dest, tv);
|
emit_loadk64(as, dest, ir);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if LJ_64
|
#if LJ_64
|
||||||
} else if (ir->o == IR_KINT64) {
|
} else if (ir->o == IR_KINT64) {
|
||||||
emit_loadu64(as, dest, ir_kint64(ir)->u64);
|
emit_loadk64(as, dest, ir);
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
} else if (ir->o != IR_KPRI) {
|
} else if (ir->o != IR_KPRI) {
|
||||||
@ -1963,8 +1962,14 @@ static void asm_setup_regsp(ASMState *as)
|
|||||||
ra_setup(as);
|
ra_setup(as);
|
||||||
|
|
||||||
/* Clear reg/sp for constants. */
|
/* Clear reg/sp for constants. */
|
||||||
for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++)
|
for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++) {
|
||||||
ir->prev = REGSP_INIT;
|
ir->prev = REGSP_INIT;
|
||||||
|
if (irt_is64(ir->t) && ir->o != IR_KNULL) {
|
||||||
|
/* Make life easier for backends by putting address of constant in i. */
|
||||||
|
ir->i = (int32_t)(intptr_t)(ir+1);
|
||||||
|
ir++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* REF_BASE is used for implicit references to the BASE register. */
|
/* REF_BASE is used for implicit references to the BASE register. */
|
||||||
lastir->prev = REGSP_HINT(RID_BASE);
|
lastir->prev = REGSP_HINT(RID_BASE);
|
||||||
|
@ -306,6 +306,16 @@ static void asm_fusexref(ASMState *as, IRRef ref, RegSet allow)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fuse load of 64 bit IR constant into memory operand. */
|
||||||
|
static Reg asm_fuseloadk64(ASMState *as, IRIns *ir)
|
||||||
|
{
|
||||||
|
const uint64_t *k = &ir_k64(ir)->u64;
|
||||||
|
as->mrm.ofs = ptr2addr(k);
|
||||||
|
as->mrm.base = RID_NONE;
|
||||||
|
as->mrm.idx = RID_NONE;
|
||||||
|
return RID_MRM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fuse load into memory operand. */
|
/* Fuse load into memory operand. */
|
||||||
static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
|
static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
|
||||||
{
|
{
|
||||||
@ -325,19 +335,13 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
|
|||||||
if (ir->o == IR_KNUM) {
|
if (ir->o == IR_KNUM) {
|
||||||
RegSet avail = as->freeset & ~as->modset & RSET_FPR;
|
RegSet avail = as->freeset & ~as->modset & RSET_FPR;
|
||||||
lua_assert(allow != RSET_EMPTY);
|
lua_assert(allow != RSET_EMPTY);
|
||||||
if (!(avail & (avail-1))) { /* Fuse if less than two regs available. */
|
if (!(avail & (avail-1))) /* Fuse if less than two regs available. */
|
||||||
as->mrm.ofs = ptr2addr(ir_knum(ir));
|
return asm_fuseloadk64(as, ir);
|
||||||
as->mrm.base = as->mrm.idx = RID_NONE;
|
|
||||||
return RID_MRM;
|
|
||||||
}
|
|
||||||
} else if (ir->o == IR_KINT64) {
|
} else if (ir->o == IR_KINT64) {
|
||||||
RegSet avail = as->freeset & ~as->modset & RSET_GPR;
|
RegSet avail = as->freeset & ~as->modset & RSET_GPR;
|
||||||
lua_assert(allow != RSET_EMPTY);
|
lua_assert(allow != RSET_EMPTY);
|
||||||
if (!(avail & (avail-1))) { /* Fuse if less than two regs available. */
|
if (!(avail & (avail-1))) /* Fuse if less than two regs available. */
|
||||||
as->mrm.ofs = ptr2addr(ir_kint64(ir));
|
return asm_fuseloadk64(as, ir);
|
||||||
as->mrm.base = as->mrm.idx = RID_NONE;
|
|
||||||
return RID_MRM;
|
|
||||||
}
|
|
||||||
} else if (mayfuse(as, ref)) {
|
} else if (mayfuse(as, ref)) {
|
||||||
RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR;
|
RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR;
|
||||||
if (ir->o == IR_SLOAD) {
|
if (ir->o == IR_SLOAD) {
|
||||||
@ -711,7 +715,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
|||||||
emit_rr(as, XO_CVTSD2SS, dest, dest);
|
emit_rr(as, XO_CVTSD2SS, dest, dest);
|
||||||
emit_rr(as, XO_SUBSD, dest, bias); /* Subtract 2^52+2^51 bias. */
|
emit_rr(as, XO_SUBSD, dest, bias); /* Subtract 2^52+2^51 bias. */
|
||||||
emit_rr(as, XO_XORPS, dest, bias); /* Merge bias and integer. */
|
emit_rr(as, XO_XORPS, dest, bias); /* Merge bias and integer. */
|
||||||
emit_loadn(as, bias, k);
|
emit_rma(as, XO_MOVSD, bias, k);
|
||||||
emit_mrm(as, XO_MOVD, dest, asm_fuseload(as, lref, RSET_GPR));
|
emit_mrm(as, XO_MOVD, dest, asm_fuseload(as, lref, RSET_GPR));
|
||||||
return;
|
return;
|
||||||
} else { /* Integer to FP conversion. */
|
} else { /* Integer to FP conversion. */
|
||||||
|
@ -219,8 +219,9 @@ static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p)
|
|||||||
|
|
||||||
#if !LJ_SOFTFP
|
#if !LJ_SOFTFP
|
||||||
/* Load a number constant into an FPR. */
|
/* Load a number constant into an FPR. */
|
||||||
static void emit_loadn(ASMState *as, Reg r, cTValue *tv)
|
static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
|
||||||
{
|
{
|
||||||
|
cTValue *tv = ir_knum(ir);
|
||||||
int32_t i;
|
int32_t i;
|
||||||
if ((as->flags & JIT_F_VFPV3) && !tv->u32.lo) {
|
if ((as->flags & JIT_F_VFPV3) && !tv->u32.lo) {
|
||||||
uint32_t hi = tv->u32.hi;
|
uint32_t hi = tv->u32.hi;
|
||||||
|
@ -112,8 +112,8 @@ static void emit_lsptr(ASMState *as, MIPSIns mi, Reg r, void *p, RegSet allow)
|
|||||||
emit_tsi(as, mi, r, base, i);
|
emit_tsi(as, mi, r, base, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define emit_loadn(as, r, tv) \
|
#define emit_loadk64(as, r, ir) \
|
||||||
emit_lsptr(as, MIPSI_LDC1, ((r) & 31), (void *)(tv), RSET_GPR)
|
emit_lsptr(as, MIPSI_LDC1, ((r) & 31), (void *)&ir_knum((ir))->u64, RSET_GPR)
|
||||||
|
|
||||||
/* Get/set global_State fields. */
|
/* Get/set global_State fields. */
|
||||||
static void emit_lsglptr(ASMState *as, MIPSIns mi, Reg r, int32_t ofs)
|
static void emit_lsglptr(ASMState *as, MIPSIns mi, Reg r, int32_t ofs)
|
||||||
|
@ -115,8 +115,8 @@ static void emit_lsptr(ASMState *as, PPCIns pi, Reg r, void *p, RegSet allow)
|
|||||||
emit_tai(as, pi, r, base, i);
|
emit_tai(as, pi, r, base, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define emit_loadn(as, r, tv) \
|
#define emit_loadk64(as, r, ir) \
|
||||||
emit_lsptr(as, PPCI_LFD, ((r) & 31), (void *)(tv), RSET_GPR)
|
emit_lsptr(as, PPCI_LFD, ((r) & 31), (void *)&ir_knum((ir))->u64, RSET_GPR)
|
||||||
|
|
||||||
/* Get/set global_State fields. */
|
/* Get/set global_State fields. */
|
||||||
static void emit_lsglptr(ASMState *as, PPCIns pi, Reg r, int32_t ofs)
|
static void emit_lsglptr(ASMState *as, PPCIns pi, Reg r, int32_t ofs)
|
||||||
|
@ -313,13 +313,23 @@ static void emit_loadu64(ASMState *as, Reg r, uint64_t u64)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* movsd r, [&tv->n] / xorps r, r */
|
/* Load 64 bit IR constant into register. */
|
||||||
static void emit_loadn(ASMState *as, Reg r, cTValue *tv)
|
static void emit_loadk64(ASMState *as, Reg r, IRIns *ir)
|
||||||
{
|
{
|
||||||
if (tvispzero(tv)) /* Use xor only for +0. */
|
const uint64_t *k = &ir_k64(ir)->u64;
|
||||||
|
if (rset_test(RSET_FPR, r)) {
|
||||||
|
if (*k == 0) {
|
||||||
emit_rr(as, XO_XORPS, r, r);
|
emit_rr(as, XO_XORPS, r, r);
|
||||||
else
|
} else {
|
||||||
emit_rma(as, XO_MOVSD, r, &tv->n);
|
emit_rma(as, XO_MOVSD, r, k);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (*k == 0) {
|
||||||
|
emit_rr(as, XO_ARITH(XOg_XOR), r, r);
|
||||||
|
} else {
|
||||||
|
emit_rma(as, XO_MOV, r | REX_64, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Emit control-flow instructions -------------------------------------- */
|
/* -- Emit control-flow instructions -------------------------------------- */
|
||||||
|
@ -238,6 +238,8 @@ static void gc_traverse_trace(global_State *g, GCtrace *T)
|
|||||||
IRIns *ir = &T->ir[ref];
|
IRIns *ir = &T->ir[ref];
|
||||||
if (ir->o == IR_KGC)
|
if (ir->o == IR_KGC)
|
||||||
gc_markobj(g, ir_kgc(ir));
|
gc_markobj(g, ir_kgc(ir));
|
||||||
|
if (irt_is64(ir->t) && ir->o != IR_KNULL)
|
||||||
|
ref++;
|
||||||
}
|
}
|
||||||
if (T->link) gc_marktrace(g, T->link);
|
if (T->link) gc_marktrace(g, T->link);
|
||||||
if (T->nextroot) gc_marktrace(g, T->nextroot);
|
if (T->nextroot) gc_marktrace(g, T->nextroot);
|
||||||
|
36
src/lj_ir.c
36
src/lj_ir.c
@ -91,7 +91,7 @@ static void lj_ir_growbot(jit_State *J)
|
|||||||
IRIns *baseir = J->irbuf + J->irbotlim;
|
IRIns *baseir = J->irbuf + J->irbotlim;
|
||||||
MSize szins = J->irtoplim - J->irbotlim;
|
MSize szins = J->irtoplim - J->irbotlim;
|
||||||
lua_assert(szins != 0);
|
lua_assert(szins != 0);
|
||||||
lua_assert(J->cur.nk == J->irbotlim);
|
lua_assert(J->cur.nk == J->irbotlim || J->cur.nk-1 == J->irbotlim);
|
||||||
if (J->cur.nins + (szins >> 1) < J->irtoplim) {
|
if (J->cur.nins + (szins >> 1) < J->irtoplim) {
|
||||||
/* More than half of the buffer is free on top: shift up by a quarter. */
|
/* More than half of the buffer is free on top: shift up by a quarter. */
|
||||||
MSize ofs = szins >> 2;
|
MSize ofs = szins >> 2;
|
||||||
@ -173,6 +173,18 @@ static LJ_AINLINE IRRef ir_nextk(jit_State *J)
|
|||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get ref of next 64 bit IR constant and optionally grow IR.
|
||||||
|
** Note: this may invalidate all IRIns *!
|
||||||
|
*/
|
||||||
|
static LJ_AINLINE IRRef ir_nextk64(jit_State *J)
|
||||||
|
{
|
||||||
|
IRRef ref = J->cur.nk - 2;
|
||||||
|
lua_assert(J->state != LJ_TRACE_ASM);
|
||||||
|
if (LJ_UNLIKELY(ref < J->irbotlim)) lj_ir_growbot(J);
|
||||||
|
J->cur.nk = ref;
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
/* Intern int32_t constant. */
|
/* Intern int32_t constant. */
|
||||||
TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k)
|
TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k)
|
||||||
{
|
{
|
||||||
@ -266,19 +278,18 @@ TValue *lj_ir_k64_reserve(jit_State *J)
|
|||||||
return ir_k64_add(J, kp, 0); /* Set to 0. Final value is set later. */
|
return ir_k64_add(J, kp, 0); /* Set to 0. Final value is set later. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Intern 64 bit constant, given by its address. */
|
/* Intern 64 bit constant, given by its 64 bit pattern. */
|
||||||
TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv)
|
TRef lj_ir_k64(jit_State *J, IROp op, uint64_t u64)
|
||||||
{
|
{
|
||||||
IRIns *ir, *cir = J->cur.ir;
|
IRIns *ir, *cir = J->cur.ir;
|
||||||
IRRef ref;
|
IRRef ref;
|
||||||
IRType t = op == IR_KNUM ? IRT_NUM : IRT_I64;
|
IRType t = op == IR_KNUM ? IRT_NUM : IRT_I64;
|
||||||
for (ref = J->chain[op]; ref; ref = cir[ref].prev)
|
for (ref = J->chain[op]; ref; ref = cir[ref].prev)
|
||||||
if (ir_k64(&cir[ref]) == tv)
|
if (ir_k64(&cir[ref])->u64 == u64)
|
||||||
goto found;
|
goto found;
|
||||||
ref = ir_nextk(J);
|
ref = ir_nextk64(J);
|
||||||
ir = IR(ref);
|
ir = IR(ref);
|
||||||
lua_assert(checkptrGC(tv));
|
ir[1].tv.u64 = u64;
|
||||||
setmref(ir->ptr, tv);
|
|
||||||
ir->t.irt = t;
|
ir->t.irt = t;
|
||||||
ir->o = op;
|
ir->o = op;
|
||||||
ir->prev = J->chain[op];
|
ir->prev = J->chain[op];
|
||||||
@ -290,13 +301,13 @@ found:
|
|||||||
/* Intern FP constant, given by its 64 bit pattern. */
|
/* Intern FP constant, given by its 64 bit pattern. */
|
||||||
TRef lj_ir_knum_u64(jit_State *J, uint64_t u64)
|
TRef lj_ir_knum_u64(jit_State *J, uint64_t u64)
|
||||||
{
|
{
|
||||||
return lj_ir_k64(J, IR_KNUM, lj_ir_k64_find(J, u64));
|
return lj_ir_k64(J, IR_KNUM, u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Intern 64 bit integer constant. */
|
/* Intern 64 bit integer constant. */
|
||||||
TRef lj_ir_kint64(jit_State *J, uint64_t u64)
|
TRef lj_ir_kint64(jit_State *J, uint64_t u64)
|
||||||
{
|
{
|
||||||
return lj_ir_k64(J, IR_KINT64, lj_ir_k64_find(J, u64));
|
return lj_ir_k64(J, IR_KINT64, u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether a number is int and return it. -0 is NOT considered an int. */
|
/* Check whether a number is int and return it. -0 is NOT considered an int. */
|
||||||
@ -367,7 +378,7 @@ TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr)
|
|||||||
IRRef ref;
|
IRRef ref;
|
||||||
lua_assert((void *)(uintptr_t)u32ptr(ptr) == ptr);
|
lua_assert((void *)(uintptr_t)u32ptr(ptr) == ptr);
|
||||||
for (ref = J->chain[op]; ref; ref = cir[ref].prev)
|
for (ref = J->chain[op]; ref; ref = cir[ref].prev)
|
||||||
if (mref(cir[ref].ptr, void) == ptr)
|
if (ir_kptr(&cir[ref]) == ptr)
|
||||||
goto found;
|
goto found;
|
||||||
ref = ir_nextk(J);
|
ref = ir_nextk(J);
|
||||||
ir = IR(ref);
|
ir = IR(ref);
|
||||||
@ -432,9 +443,8 @@ void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir)
|
|||||||
case IR_KPRI: setpriV(tv, irt_toitype(ir->t)); break;
|
case IR_KPRI: setpriV(tv, irt_toitype(ir->t)); break;
|
||||||
case IR_KINT: setintV(tv, ir->i); break;
|
case IR_KINT: setintV(tv, ir->i); break;
|
||||||
case IR_KGC: setgcV(L, tv, ir_kgc(ir), irt_toitype(ir->t)); break;
|
case IR_KGC: setgcV(L, tv, ir_kgc(ir), irt_toitype(ir->t)); break;
|
||||||
case IR_KPTR: case IR_KKPTR: case IR_KNULL:
|
case IR_KPTR: case IR_KKPTR: setlightudV(tv, ir_kptr(ir)); break;
|
||||||
setlightudV(tv, mref(ir->ptr, void));
|
case IR_KNULL: setlightudV(tv, NULL); break;
|
||||||
break;
|
|
||||||
case IR_KNUM: setnumV(tv, ir_knum(ir)->n); break;
|
case IR_KNUM: setnumV(tv, ir_knum(ir)->n); break;
|
||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
case IR_KINT64: {
|
case IR_KINT64: {
|
||||||
|
15
src/lj_ir.h
15
src/lj_ir.h
@ -522,7 +522,9 @@ typedef uint32_t TRef;
|
|||||||
** +-------+-------+---+---+---+---+
|
** +-------+-------+---+---+---+---+
|
||||||
** | op1 | op2 | t | o | r | s |
|
** | op1 | op2 | t | o | r | s |
|
||||||
** +-------+-------+---+---+---+---+
|
** +-------+-------+---+---+---+---+
|
||||||
** | op12/i/gco | ot | prev | (alternative fields in union)
|
** | op12/i/gco32 | ot | prev | (alternative fields in union)
|
||||||
|
** +-------+-------+---+---+---+---+
|
||||||
|
** | TValue/gco64 | (2nd IR slot for 64 bit constants)
|
||||||
** +---------------+-------+-------+
|
** +---------------+-------+-------+
|
||||||
** 32 16 16
|
** 32 16 16
|
||||||
**
|
**
|
||||||
@ -550,8 +552,9 @@ typedef union IRIns {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
int32_t i; /* 32 bit signed integer literal (overlaps op12). */
|
int32_t i; /* 32 bit signed integer literal (overlaps op12). */
|
||||||
GCRef gcr; /* GCobj constant (overlaps op12). */
|
GCRef gcr; /* GCobj constant (overlaps op12 or entire slot). */
|
||||||
MRef ptr; /* Pointer constant (overlaps op12). */
|
MRef ptr; /* Pointer constant (overlaps op12 or entire slot). */
|
||||||
|
TValue tv; /* TValue constant (overlaps entire slot). */
|
||||||
} IRIns;
|
} IRIns;
|
||||||
|
|
||||||
/* TODO_GC64: major changes required. */
|
/* TODO_GC64: major changes required. */
|
||||||
@ -560,10 +563,10 @@ typedef union IRIns {
|
|||||||
#define ir_ktab(ir) (gco2tab(ir_kgc((ir))))
|
#define ir_ktab(ir) (gco2tab(ir_kgc((ir))))
|
||||||
#define ir_kfunc(ir) (gco2func(ir_kgc((ir))))
|
#define ir_kfunc(ir) (gco2func(ir_kgc((ir))))
|
||||||
#define ir_kcdata(ir) (gco2cd(ir_kgc((ir))))
|
#define ir_kcdata(ir) (gco2cd(ir_kgc((ir))))
|
||||||
#define ir_knum(ir) check_exp((ir)->o == IR_KNUM, mref((ir)->ptr, cTValue))
|
#define ir_knum(ir) check_exp((ir)->o == IR_KNUM, &(ir)[1].tv)
|
||||||
#define ir_kint64(ir) check_exp((ir)->o == IR_KINT64, mref((ir)->ptr,cTValue))
|
#define ir_kint64(ir) check_exp((ir)->o == IR_KINT64, &(ir)[1].tv)
|
||||||
#define ir_k64(ir) \
|
#define ir_k64(ir) \
|
||||||
check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64, mref((ir)->ptr,cTValue))
|
check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64, &(ir)[1].tv)
|
||||||
#define ir_kptr(ir) \
|
#define ir_kptr(ir) \
|
||||||
check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, mref((ir)->ptr, void))
|
check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, mref((ir)->ptr, void))
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs);
|
|||||||
/* Interning of constants. */
|
/* Interning of constants. */
|
||||||
LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k);
|
LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k);
|
||||||
LJ_FUNC void lj_ir_k64_freeall(jit_State *J);
|
LJ_FUNC void lj_ir_k64_freeall(jit_State *J);
|
||||||
LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv);
|
LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, uint64_t u64);
|
||||||
LJ_FUNC TValue *lj_ir_k64_reserve(jit_State *J);
|
LJ_FUNC TValue *lj_ir_k64_reserve(jit_State *J);
|
||||||
LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64);
|
LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64);
|
||||||
LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64);
|
LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64);
|
||||||
|
@ -355,8 +355,8 @@ enum {
|
|||||||
/* Fold state is used to fold instructions on-the-fly. */
|
/* Fold state is used to fold instructions on-the-fly. */
|
||||||
typedef struct FoldState {
|
typedef struct FoldState {
|
||||||
IRIns ins; /* Currently emitted instruction. */
|
IRIns ins; /* Currently emitted instruction. */
|
||||||
IRIns left; /* Instruction referenced by left operand. */
|
IRIns left[2]; /* Instruction referenced by left operand. */
|
||||||
IRIns right; /* Instruction referenced by right operand. */
|
IRIns right[2]; /* Instruction referenced by right operand. */
|
||||||
} FoldState;
|
} FoldState;
|
||||||
|
|
||||||
/* JIT compiler state. */
|
/* JIT compiler state. */
|
||||||
|
@ -136,8 +136,8 @@
|
|||||||
/* Some local macros to save typing. Undef'd at the end. */
|
/* Some local macros to save typing. Undef'd at the end. */
|
||||||
#define IR(ref) (&J->cur.ir[(ref)])
|
#define IR(ref) (&J->cur.ir[(ref)])
|
||||||
#define fins (&J->fold.ins)
|
#define fins (&J->fold.ins)
|
||||||
#define fleft (&J->fold.left)
|
#define fleft (J->fold.left)
|
||||||
#define fright (&J->fold.right)
|
#define fright (J->fold.right)
|
||||||
#define knumleft (ir_knum(fleft)->n)
|
#define knumleft (ir_knum(fleft)->n)
|
||||||
#define knumright (ir_knum(fright)->n)
|
#define knumright (ir_knum(fright)->n)
|
||||||
|
|
||||||
@ -2393,10 +2393,14 @@ retry:
|
|||||||
if (fins->op1 >= J->cur.nk) {
|
if (fins->op1 >= J->cur.nk) {
|
||||||
key += (uint32_t)IR(fins->op1)->o << 10;
|
key += (uint32_t)IR(fins->op1)->o << 10;
|
||||||
*fleft = *IR(fins->op1);
|
*fleft = *IR(fins->op1);
|
||||||
|
if (fins->op1 < REF_TRUE)
|
||||||
|
fleft[1] = IR(fins->op1)[1];
|
||||||
}
|
}
|
||||||
if (fins->op2 >= J->cur.nk) {
|
if (fins->op2 >= J->cur.nk) {
|
||||||
key += (uint32_t)IR(fins->op2)->o;
|
key += (uint32_t)IR(fins->op2)->o;
|
||||||
*fright = *IR(fins->op2);
|
*fright = *IR(fins->op2);
|
||||||
|
if (fins->op2 < REF_TRUE)
|
||||||
|
fright[1] = IR(fins->op2)[1];
|
||||||
} else {
|
} else {
|
||||||
key += (fins->op2 & 0x3ffu); /* Literal mask. Must include IRCONV_*MASK. */
|
key += (fins->op2 & 0x3ffu); /* Literal mask. Must include IRCONV_*MASK. */
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
/* Some local macros to save typing. Undef'd at the end. */
|
/* Some local macros to save typing. Undef'd at the end. */
|
||||||
#define IR(ref) (&J->cur.ir[(ref)])
|
#define IR(ref) (&J->cur.ir[(ref)])
|
||||||
#define fins (&J->fold.ins)
|
#define fins (&J->fold.ins)
|
||||||
#define fleft (&J->fold.left)
|
#define fleft (J->fold.left)
|
||||||
#define fright (&J->fold.right)
|
#define fright (J->fold.right)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Caveat #1: return value is not always a TRef -- only use with tref_ref().
|
** Caveat #1: return value is not always a TRef -- only use with tref_ref().
|
||||||
|
@ -220,6 +220,8 @@ static void sink_sweep_ins(jit_State *J)
|
|||||||
for (ir = IR(J->cur.nk); ir < irbase; ir++) {
|
for (ir = IR(J->cur.nk); ir < irbase; ir++) {
|
||||||
irt_clearmark(ir->t);
|
irt_clearmark(ir->t);
|
||||||
ir->prev = REGSP_INIT;
|
ir->prev = REGSP_INIT;
|
||||||
|
if (irt_is64(ir->t) && ir->o != IR_KNULL)
|
||||||
|
ir++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,6 +354,8 @@ static void split_ir(jit_State *J)
|
|||||||
ir->prev = ref; /* Identity substitution for loword. */
|
ir->prev = ref; /* Identity substitution for loword. */
|
||||||
hisubst[ref] = 0;
|
hisubst[ref] = 0;
|
||||||
}
|
}
|
||||||
|
if (irt_is64(ir->t) && ir->o != IR_KNULL)
|
||||||
|
ref++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process old IR instructions. */
|
/* Process old IR instructions. */
|
||||||
|
@ -61,7 +61,10 @@ static void rec_check_ir(jit_State *J)
|
|||||||
case IRMref: lua_assert(op1 >= nk);
|
case IRMref: lua_assert(op1 >= nk);
|
||||||
lua_assert(i >= REF_BIAS ? op1 < i : op1 > i); break;
|
lua_assert(i >= REF_BIAS ? op1 < i : op1 > i); break;
|
||||||
case IRMlit: break;
|
case IRMlit: break;
|
||||||
case IRMcst: lua_assert(i < REF_BIAS); continue;
|
case IRMcst: lua_assert(i < REF_BIAS);
|
||||||
|
if (irt_is64(ir->t) && ir->o != IR_KNULL)
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
switch (irm_op2(mode)) {
|
switch (irm_op2(mode)) {
|
||||||
case IRMnone: lua_assert(op2 == 0); break;
|
case IRMnone: lua_assert(op2 == 0); break;
|
||||||
|
@ -371,8 +371,8 @@ static TRef snap_replay_const(jit_State *J, IRIns *ir)
|
|||||||
case IR_KPRI: return TREF_PRI(irt_type(ir->t));
|
case IR_KPRI: return TREF_PRI(irt_type(ir->t));
|
||||||
case IR_KINT: return lj_ir_kint(J, ir->i);
|
case IR_KINT: return lj_ir_kint(J, ir->i);
|
||||||
case IR_KGC: return lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t));
|
case IR_KGC: return lj_ir_kgc(J, ir_kgc(ir), irt_t(ir->t));
|
||||||
case IR_KNUM: return lj_ir_k64(J, IR_KNUM, ir_knum(ir));
|
case IR_KNUM: case IR_KINT64:
|
||||||
case IR_KINT64: return lj_ir_k64(J, IR_KINT64, ir_kint64(ir));
|
return lj_ir_k64(J, (IROp)ir->o, ir_k64(ir)->u64);
|
||||||
case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir)); /* Continuation. */
|
case IR_KPTR: return lj_ir_kptr(J, ir_kptr(ir)); /* Continuation. */
|
||||||
default: lua_assert(0); return TREF_NIL; break;
|
default: lua_assert(0); return TREF_NIL; break;
|
||||||
}
|
}
|
||||||
@ -555,8 +555,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T)
|
|||||||
if (irref_isk(irs->op2) && irref_isk((irs+1)->op2)) {
|
if (irref_isk(irs->op2) && irref_isk((irs+1)->op2)) {
|
||||||
uint64_t k = (uint32_t)T->ir[irs->op2].i +
|
uint64_t k = (uint32_t)T->ir[irs->op2].i +
|
||||||
((uint64_t)T->ir[(irs+1)->op2].i << 32);
|
((uint64_t)T->ir[(irs+1)->op2].i << 32);
|
||||||
val = lj_ir_k64(J, t == IRT_I64 ? IR_KINT64 : IR_KNUM,
|
val = lj_ir_k64(J, t == IRT_I64 ? IR_KINT64 : IR_KNUM, k);
|
||||||
lj_ir_k64_find(J, k));
|
|
||||||
} else {
|
} else {
|
||||||
val = emitir_raw(IRT(IR_HIOP, t), val,
|
val = emitir_raw(IRT(IR_HIOP, t), val,
|
||||||
snap_pref(J, T, map, nent, seen, (irs+1)->op2));
|
snap_pref(J, T, map, nent, seen, (irs+1)->op2));
|
||||||
@ -651,7 +650,7 @@ static void snap_restoredata(GCtrace *T, ExitState *ex,
|
|||||||
uint64_t tmp;
|
uint64_t tmp;
|
||||||
if (irref_isk(ref)) {
|
if (irref_isk(ref)) {
|
||||||
if (ir->o == IR_KNUM || ir->o == IR_KINT64) {
|
if (ir->o == IR_KNUM || ir->o == IR_KINT64) {
|
||||||
src = mref(ir->ptr, int32_t);
|
src = (int32_t *)&ir[1];
|
||||||
} else if (sz == 8) {
|
} else if (sz == 8) {
|
||||||
tmp = (uint64_t)(uint32_t)ir->i;
|
tmp = (uint64_t)(uint32_t)ir->i;
|
||||||
src = (int32_t *)&tmp;
|
src = (int32_t *)&tmp;
|
||||||
|
Loading…
Reference in New Issue
Block a user