mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-19 21:43:27 +00:00
Fix PHI stack slot syncing.
This commit is contained in:
parent
afc17b3c1a
commit
0d824b7d14
65
src/lj_asm.c
65
src/lj_asm.c
@ -1079,6 +1079,64 @@ static void asm_phi_shuffle(ASMState *as)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy unsynced left/right PHI spill slots. Rarely needed. */
|
||||||
|
static void asm_phi_copyspill(ASMState *as)
|
||||||
|
{
|
||||||
|
int need = 0;
|
||||||
|
IRIns *ir;
|
||||||
|
for (ir = IR(as->orignins-1); ir->o == IR_PHI; ir--)
|
||||||
|
if (ra_hasspill(ir->s) && ra_hasspill(IR(ir->op1)->s))
|
||||||
|
need |= irt_isfp(ir->t) ? 2 : 1; /* Unsynced spill slot? */
|
||||||
|
if ((need & 1)) { /* Copy integer spill slots. */
|
||||||
|
#if !LJ_TARGET_X86ORX64
|
||||||
|
Reg r = RID_TMP;
|
||||||
|
#else
|
||||||
|
Reg r = RID_RET;
|
||||||
|
if ((as->freeset & RSET_GPR))
|
||||||
|
r = rset_pickbot((as->freeset & RSET_GPR));
|
||||||
|
else
|
||||||
|
emit_spload(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
|
||||||
|
#endif
|
||||||
|
for (ir = IR(as->orignins-1); ir->o == IR_PHI; ir--) {
|
||||||
|
if (ra_hasspill(ir->s)) {
|
||||||
|
IRIns *irl = IR(ir->op1);
|
||||||
|
if (ra_hasspill(irl->s) && !irt_isfp(ir->t)) {
|
||||||
|
emit_spstore(as, irl, r, sps_scale(irl->s));
|
||||||
|
emit_spload(as, ir, r, sps_scale(ir->s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if LJ_TARGET_X86ORX64
|
||||||
|
if (!rset_test(as->freeset, r))
|
||||||
|
emit_spstore(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if !LJ_SOFTFP
|
||||||
|
if ((need & 2)) { /* Copy FP spill slots. */
|
||||||
|
#if LJ_TARGET_X86
|
||||||
|
Reg r = RID_XMM0;
|
||||||
|
#else
|
||||||
|
Reg r = RID_FPRET;
|
||||||
|
#endif
|
||||||
|
if ((as->freeset & RSET_FPR))
|
||||||
|
r = rset_pickbot((as->freeset & RSET_FPR));
|
||||||
|
if (!rset_test(as->freeset, r))
|
||||||
|
emit_spload(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
|
||||||
|
for (ir = IR(as->orignins-1); ir->o == IR_PHI; ir--) {
|
||||||
|
if (ra_hasspill(ir->s)) {
|
||||||
|
IRIns *irl = IR(ir->op1);
|
||||||
|
if (ra_hasspill(irl->s) && irt_isfp(ir->t)) {
|
||||||
|
emit_spstore(as, irl, r, sps_scale(irl->s));
|
||||||
|
emit_spload(as, ir, r, sps_scale(ir->s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rset_test(as->freeset, r))
|
||||||
|
emit_spstore(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Emit renames for left PHIs which are only spilled outside the loop. */
|
/* Emit renames for left PHIs which are only spilled outside the loop. */
|
||||||
static void asm_phi_fixup(ASMState *as)
|
static void asm_phi_fixup(ASMState *as)
|
||||||
{
|
{
|
||||||
@ -1132,7 +1190,7 @@ static void asm_phi(ASMState *as, IRIns *ir)
|
|||||||
if (ra_hasreg(irl->r) || ra_hasreg(irr->r))
|
if (ra_hasreg(irl->r) || ra_hasreg(irr->r))
|
||||||
lj_trace_err(as->J, LJ_TRERR_NYIPHI);
|
lj_trace_err(as->J, LJ_TRERR_NYIPHI);
|
||||||
ra_spill(as, ir);
|
ra_spill(as, ir);
|
||||||
irl->s = irr->s = ir->s; /* Sync left/right PHI spill slots. */
|
irr->s = ir->s; /* Set right PHI spill slot. Sync left slot later. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1142,6 +1200,7 @@ static void asm_loop_fixup(ASMState *as);
|
|||||||
/* Middle part of a loop. */
|
/* Middle part of a loop. */
|
||||||
static void asm_loop(ASMState *as)
|
static void asm_loop(ASMState *as)
|
||||||
{
|
{
|
||||||
|
MCode *mcspill;
|
||||||
/* LOOP is a guard, so the snapno is up to date. */
|
/* LOOP is a guard, so the snapno is up to date. */
|
||||||
as->loopsnapno = as->snapno;
|
as->loopsnapno = as->snapno;
|
||||||
if (as->gcsteps)
|
if (as->gcsteps)
|
||||||
@ -1151,10 +1210,14 @@ static void asm_loop(ASMState *as)
|
|||||||
as->sectref = 0;
|
as->sectref = 0;
|
||||||
if (!neverfuse(as)) as->fuseref = 0;
|
if (!neverfuse(as)) as->fuseref = 0;
|
||||||
asm_phi_shuffle(as);
|
asm_phi_shuffle(as);
|
||||||
|
mcspill = as->mcp;
|
||||||
|
asm_phi_copyspill(as);
|
||||||
asm_loop_fixup(as);
|
asm_loop_fixup(as);
|
||||||
as->mcloop = as->mcp;
|
as->mcloop = as->mcp;
|
||||||
RA_DBGX((as, "===== LOOP ====="));
|
RA_DBGX((as, "===== LOOP ====="));
|
||||||
if (!as->realign) RA_DBG_FLUSH();
|
if (!as->realign) RA_DBG_FLUSH();
|
||||||
|
if (as->mcp != mcspill)
|
||||||
|
emit_jmp(as, mcspill);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- Target-specific assembler ------------------------------------------- */
|
/* -- Target-specific assembler ------------------------------------------- */
|
||||||
|
@ -231,6 +231,8 @@ static void emit_branch(ASMState *as, ARMIns ai, MCode *target)
|
|||||||
as->mcp = p;
|
as->mcp = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define emit_jmp(as, target) emit_branch(as, ARMI_B, (target))
|
||||||
|
|
||||||
static void emit_call(ASMState *as, void *target)
|
static void emit_call(ASMState *as, void *target)
|
||||||
{
|
{
|
||||||
MCode *p = --as->mcp;
|
MCode *p = --as->mcp;
|
||||||
|
@ -146,6 +146,12 @@ static void emit_branch(ASMState *as, MIPSIns mi, Reg rs, Reg rt, MCode *target)
|
|||||||
as->mcp = p;
|
as->mcp = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void emit_jmp(ASMState *as, MCode *target)
|
||||||
|
{
|
||||||
|
*--as->mcp = MIPSI_NOP;
|
||||||
|
emit_branch(as, MIPSI_B, RID_ZERO, RID_ZERO, (target));
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_call(ASMState *as, void *target)
|
static void emit_call(ASMState *as, void *target)
|
||||||
{
|
{
|
||||||
MCode *p = as->mcp;
|
MCode *p = as->mcp;
|
||||||
|
@ -142,12 +142,18 @@ typedef MCode *MCLabel;
|
|||||||
|
|
||||||
static void emit_condbranch(ASMState *as, PPCIns pi, PPCCC cc, MCode *target)
|
static void emit_condbranch(ASMState *as, PPCIns pi, PPCCC cc, MCode *target)
|
||||||
{
|
{
|
||||||
MCode *p = as->mcp;
|
MCode *p = --as->mcp;
|
||||||
ptrdiff_t delta = ((char *)target - (char *)p) + 4;
|
ptrdiff_t delta = (char *)target - (char *)p;
|
||||||
lua_assert(((delta + 0x8000) >> 16) == 0);
|
lua_assert(((delta + 0x8000) >> 16) == 0);
|
||||||
pi ^= (delta & 0x8000) * (PPCF_Y/0x8000);
|
pi ^= (delta & 0x8000) * (PPCF_Y/0x8000);
|
||||||
*--p = pi | PPCF_CC(cc) | ((uint32_t)delta & 0xffffu);
|
*p = pi | PPCF_CC(cc) | ((uint32_t)delta & 0xffffu);
|
||||||
as->mcp = p;
|
}
|
||||||
|
|
||||||
|
static void emit_jmp(ASMState *as, MCode *target)
|
||||||
|
{
|
||||||
|
MCode *p = --as->mcp;
|
||||||
|
ptrdiff_t delta = (char *)target - (char *)p;
|
||||||
|
*p = PPCI_B | (delta & 0x03fffffcu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_call(ASMState *as, void *target)
|
static void emit_call(ASMState *as, void *target)
|
||||||
|
@ -383,6 +383,15 @@ static void emit_jcc(ASMState *as, int cc, MCode *target)
|
|||||||
as->mcp = p - 6;
|
as->mcp = p - 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* jmp target */
|
||||||
|
static void emit_jmp(ASMState *as, MCode *target)
|
||||||
|
{
|
||||||
|
MCode *p = as->mcp;
|
||||||
|
*(int32_t *)(p-4) = jmprel(p, target);
|
||||||
|
p[-5] = XI_JMP;
|
||||||
|
as->mcp = p - 5;
|
||||||
|
}
|
||||||
|
|
||||||
/* call target */
|
/* call target */
|
||||||
static void emit_call_(ASMState *as, MCode *target)
|
static void emit_call_(ASMState *as, MCode *target)
|
||||||
{
|
{
|
||||||
|
@ -101,6 +101,8 @@ enum {
|
|||||||
#define SPS_FIXED 2
|
#define SPS_FIXED 2
|
||||||
#define SPS_FIRST 2
|
#define SPS_FIRST 2
|
||||||
|
|
||||||
|
#define SPOFS_TMP 0
|
||||||
|
|
||||||
#define sps_scale(slot) (4 * (int32_t)(slot))
|
#define sps_scale(slot) (4 * (int32_t)(slot))
|
||||||
#define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
|
#define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
|
||||||
|
|
||||||
|
@ -102,6 +102,8 @@ enum {
|
|||||||
#define SPS_FIXED 5
|
#define SPS_FIXED 5
|
||||||
#define SPS_FIRST 4
|
#define SPS_FIRST 4
|
||||||
|
|
||||||
|
#define SPOFS_TMP 0
|
||||||
|
|
||||||
#define sps_scale(slot) (4 * (int32_t)(slot))
|
#define sps_scale(slot) (4 * (int32_t)(slot))
|
||||||
#define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
|
#define sps_align(slot) (((slot) - SPS_FIXED + 1) & ~1)
|
||||||
|
|
||||||
|
@ -139,6 +139,8 @@ enum {
|
|||||||
#define SPS_FIRST 2
|
#define SPS_FIRST 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SPOFS_TMP 0
|
||||||
|
|
||||||
#define sps_scale(slot) (4 * (int32_t)(slot))
|
#define sps_scale(slot) (4 * (int32_t)(slot))
|
||||||
#define sps_align(slot) (((slot) - SPS_FIXED + 3) & ~3)
|
#define sps_align(slot) (((slot) - SPS_FIXED + 3) & ~3)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user