More portability cleanups for assembler backend.

This commit is contained in:
Mike Pall 2011-05-22 17:01:06 +02:00
parent 919ba5fd74
commit d0115c65f5
2 changed files with 30 additions and 19 deletions

View File

@ -260,10 +260,8 @@ static void ra_setup(ASMState *as)
as->weakset = RSET_EMPTY;
as->phiset = RSET_EMPTY;
memset(as->phireg, 0, sizeof(as->phireg));
memset(as->cost, 0, sizeof(as->cost));
for (r = RID_MIN_GPR; r < RID_MAX; r++)
if (!rset_test(RSET_INIT, r))
as->cost[r] = REGCOST(~0u, 0u);
as->cost[r] = REGCOST(~0u, 0u);
}
/* Rematerialize constants. */
@ -369,7 +367,7 @@ static Reg ra_evict(ASMState *as, RegSet allow)
IRRef ref;
RegCost cost = ~(RegCost)0;
lua_assert(allow != RSET_EMPTY);
if (allow < RID2RSET(RID_MAX_GPR)) {
if (RID_NUM_FPR == 0 || allow < RID2RSET(RID_MAX_GPR)) {
GPRDEF(MINCOST)
} else {
FPRDEF(MINCOST)
@ -539,6 +537,7 @@ static void ra_destreg(ASMState *as, IRIns *ir, Reg r)
}
}
#if LJ_TARGET_X86ORX64
/* Propagate dest register to left reference. Emit moves as needed.
** This is a required fixup step for all 2-operand machine instructions.
*/
@ -583,6 +582,7 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref)
}
}
}
#endif
/* -- Snapshot handling --------- ----------------------------------------- */
@ -866,7 +866,7 @@ static void asm_phi_shuffle(ASMState *as)
if (!blocked) break; /* Finished. */
if (!(as->freeset & blocked)) { /* Break cycles if none are free. */
asm_phi_break(as, blocked, blockedby, RSET_GPR);
asm_phi_break(as, blocked, blockedby, RSET_FPR);
if (!LJ_SOFTFP) asm_phi_break(as, blocked, blockedby, RSET_FPR);
checkmclim(as);
} /* Else retry some more renames. */
}
@ -921,7 +921,8 @@ static void asm_phi_fixup(ASMState *as)
/* Setup right PHI reference. */
static void asm_phi(ASMState *as, IRIns *ir)
{
RegSet allow = (irt_isfp(ir->t) ? RSET_FPR : RSET_GPR) & ~as->phiset;
RegSet allow = ((!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR) &
~as->phiset;
RegSet afree = (as->freeset & allow);
IRIns *irl = IR(ir->op1);
IRIns *irr = IR(ir->op2);
@ -1009,13 +1010,13 @@ static void asm_head_side(ASMState *as)
IRRef1 sloadins[RID_MAX];
RegSet allow = RSET_ALL; /* Inverse of all coalesced registers. */
RegSet live = RSET_EMPTY; /* Live parent registers. */
Reg pbase = as->parent->ir[REF_BASE].r; /* Parent base register (if any). */
IRIns *irp = &as->parent->ir[REF_BASE]; /* Parent base. */
int32_t spadj, spdelta;
int pass2 = 0;
int pass3 = 0;
IRRef i;
allow = asm_head_side_base(as, pbase, allow);
allow = asm_head_side_base(as, irp, allow);
/* Scan all parent SLOADs and collect register dependencies. */
for (i = as->stopins; i > REF_BASE; i--) {
@ -1129,7 +1130,7 @@ static void asm_head_side(ASMState *as)
lj_trace_err(as->J, LJ_TRERR_NYICOAL);
ra_rename(as, rset_pickbot(live & RSET_GPR), rset_pickbot(tmpset));
}
if (live & RSET_FPR) {
if (!LJ_SOFTFP && (live & RSET_FPR)) {
RegSet tmpset = as->freeset & ~live & allow & RSET_FPR;
if (tmpset == RSET_EMPTY)
lj_trace_err(as->J, LJ_TRERR_NYICOAL);
@ -1144,7 +1145,7 @@ static void asm_head_side(ASMState *as)
if (as->topslot > as->T->topslot) { /* Need to check for higher slot? */
as->T->topslot = (uint8_t)as->topslot; /* Remember for child traces. */
/* Reuse the parent exit in the context of the parent trace. */
asm_stack_check(as, as->topslot, pbase, allow & RSET_GPR, as->J->exitno);
asm_stack_check(as, as->topslot, irp, allow & RSET_GPR, as->J->exitno);
}
}
@ -1191,7 +1192,7 @@ static void asm_tail_link(ASMState *as)
/* Root traces that grow the stack need to check the stack at the end. */
if (!as->parent && as->topslot)
asm_stack_check(as, as->topslot, RID_BASE, as->freeset & RSET_GPR, snapno);
asm_stack_check(as, as->topslot, NULL, as->freeset & RSET_GPR, snapno);
}
/* -- Trace setup --------------------------------------------------------- */
@ -1283,7 +1284,7 @@ static void asm_setup_regsp(ASMState *as)
as->modset = RSET_SCRATCH;
break;
case IR_POW:
if (irt_isnum(ir->t)) {
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
#if LJ_TARGET_X86ORX64
ir->prev = REGSP_HINT(RID_XMM0);
if (inloop)
@ -1341,8 +1342,13 @@ static void asm_setup_regsp(ASMState *as)
break;
#endif
/* Do not propagate hints across type conversions. */
case IR_CONV: case IR_TOBIT:
case IR_TOBIT:
break;
case IR_CONV:
if (irt_isfp(ir->t) || (ir->op2 & IRCONV_SRCMASK) == IRT_NUM ||
(ir->op2 & IRCONV_SRCMASK) == IRT_FLOAT)
break;
/* fallthrough */
default:
/* Propagate hints across likely 'op reg, imm' or 'op reg'. */
if (irref_isk(ir->op2) && !irref_isk(ir->op1)) {
@ -1367,6 +1373,10 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
ASMState as_;
ASMState *as = &as_;
/* Ensure an initialized instruction beyond the last one for HIOP checks. */
J->cur.nins = lj_ir_nextins(J);
J->cur.ir[J->cur.nins].o = IR_NOP;
/* Setup initial state. Copy some fields to reduce indirections. */
as->J = J;
as->T = T;

View File

@ -2191,9 +2191,10 @@ static void asm_hiop(ASMState *as, IRIns *ir)
/* Check Lua stack size for overflow. Use exit handler as fallback. */
static void asm_stack_check(ASMState *as, BCReg topslot,
Reg pbase, RegSet allow, ExitNo exitno)
IRIns *irp, RegSet allow, ExitNo exitno)
{
/* Try to get an unused temp. register, otherwise spill/restore eax. */
Reg pbase = irp ? irp->r : RID_BASE;
Reg r = allow ? rset_pickbot(allow) : RID_EAX;
emit_jcc(as, CC_B, exitstub_addr(as->J, exitno));
if (allow == RSET_EMPTY) /* Restore temp. register. */
@ -2344,7 +2345,7 @@ static void asm_head_root_base(ASMState *as)
}
/* Coalesce or reload BASE register for a side trace. */
static RegSet asm_head_side_base(ASMState *as, Reg pbase, RegSet allow)
static RegSet asm_head_side_base(ASMState *as, IRIns *irp, RegSet allow)
{
IRIns *ir = IR(REF_BASE);
Reg r = ir->r;
@ -2352,11 +2353,11 @@ static RegSet asm_head_side_base(ASMState *as, Reg pbase, RegSet allow)
ra_free(as, r);
if (rset_test(as->modset, r))
ir->r = RID_INIT; /* No inheritance for modified BASE register. */
if (pbase == r) {
if (irp->r == r) {
rset_clear(allow, r); /* Mark same BASE register as coalesced. */
} else if (ra_hasreg(pbase) && rset_test(as->freeset, pbase)) {
rset_clear(allow, pbase);
emit_rr(as, XO_MOV, r, pbase); /* Move from coalesced parent register. */
} else if (ra_hasreg(irp->r) && rset_test(as->freeset, irp->r)) {
rset_clear(allow, irp->r);
emit_rr(as, XO_MOV, r, irp->r); /* Move from coalesced parent reg. */
} else {
emit_getgl(as, r, jit_base); /* Otherwise reload BASE. */
}