Generalize deferred constant handling in backend to 64 bit.

master
Mike Pall 2016-11-21 15:43:17 +01:00
parent 2b77da35bc
commit a56654460d
4 changed files with 34 additions and 8 deletions

View File

@ -91,7 +91,7 @@ typedef struct ASMState {
MCode *realign; /* Realign loop if not NULL. */
#ifdef RID_NUM_KREF
int32_t krefk[RID_NUM_KREF];
intptr_t krefk[RID_NUM_KREF];
#endif
IRRef1 phireg[RID_MAX]; /* PHI register references. */
uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent instruction to RegSP map. */
@ -144,7 +144,7 @@ static LJ_AINLINE void checkmclim(ASMState *as)
#define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref)))
#define ra_krefk(as, ref) (as->krefk[(ref)])
static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, int32_t k)
static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, intptr_t k)
{
IRRef ref = (IRRef)(r - RID_MIN_KREF);
as->krefk[ref] = k;
@ -324,7 +324,11 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
lua_assert(!rset_test(as->freeset, r));
ra_free(as, r);
ra_modified(as, r);
#if LJ_64
emit_loadu64(as, r, ra_krefk(as, ref));
#else
emit_loadi(as, r, ra_krefk(as, ref));
#endif
return r;
}
ir = IR(ref);
@ -526,7 +530,7 @@ static void ra_evictk(ASMState *as)
#ifdef RID_NUM_KREF
/* Allocate a register for a constant. */
static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow)
{
/* First try to find a register which already holds the same constant. */
RegSet pick, work = ~as->freeset & RSET_GPR;
@ -535,9 +539,31 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
IRRef ref;
r = rset_pickbot(work);
ref = regcost_ref(as->cost[r]);
#if LJ_64
if (ref < ASMREF_L) {
if (ra_iskref(ref)) {
if (k == ra_krefk(as, ref))
return r;
} else {
IRIns *ir = IR(ref);
if ((ir->o == IR_KINT64 && k == (int64_t)ir_kint64(ir)->u64) ||
#if LJ_GC64
(ir->o == IR_KINT && k == ir->i) ||
(ir->o == IR_KGC && k == (intptr_t)ir_kgc(ir)) ||
((ir->o == IR_KPTR || ir->o == IR_KKPTR) &&
k == (intptr_t)ir_kptr(ir))
#else
(ir->o != IR_KINT64 && k == ir->i)
#endif
)
return r;
}
}
#else
if (ref < ASMREF_L &&
k == (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i))
return r;
#endif
rset_clear(work, r);
}
pick = as->freeset & allow;
@ -557,7 +583,7 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
}
/* Allocate a specific register for a constant. */
static void ra_allockreg(ASMState *as, int32_t k, Reg r)
static void ra_allockreg(ASMState *as, intptr_t k, Reg r)
{
Reg kr = ra_allock(as, k, RID2RSET(r));
if (kr != r) {

View File

@ -207,7 +207,7 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i)
#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
static Reg ra_allock(ASMState *as, int32_t k, RegSet allow);
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
/* Get/set from constant pointer. */
static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p)

View File

@ -94,8 +94,8 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i)
#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
static Reg ra_allock(ASMState *as, int32_t k, RegSet allow);
static void ra_allockreg(ASMState *as, int32_t k, Reg r);
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
static void ra_allockreg(ASMState *as, intptr_t k, Reg r);
/* Get/set from constant pointer. */
static void emit_lsptr(ASMState *as, MIPSIns mi, Reg r, void *p, RegSet allow)

View File

@ -98,7 +98,7 @@ static void emit_loadi(ASMState *as, Reg r, int32_t i)
#define emit_loada(as, r, addr) emit_loadi(as, (r), i32ptr((addr)))
static Reg ra_allock(ASMState *as, int32_t k, RegSet allow);
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow);
/* Get/set from constant pointer. */
static void emit_lsptr(ASMState *as, PPCIns pi, Reg r, void *p, RegSet allow)