Bug 552374 - nanojit: clean up asm_spill() and friends a little. r=edwsmith.

--HG--
extra : convert_revision : 5806c6f3bf1257fc3142f5eb8718e01071bcbb35
This commit is contained in:
Nicholas Nethercote 2010-03-21 15:08:03 -07:00
parent 19cf26c03a
commit 5d4adc4b29
8 changed files with 130 additions and 132 deletions

View File

@ -583,13 +583,13 @@ namespace nanojit
Register Assembler::deprecated_prepResultReg(LIns *ins, RegisterMask allow)
{
#ifdef NANOJIT_IA32
const bool pop = (allow & rmask(FST0)) &&
(!ins->isInReg() || ins->getReg() != FST0);
#else
const bool pop = false;
// We used to have to worry about possibly popping the x87 stack here.
// But this function is no longer used on i386, and this assertion
// ensures that.
NanoAssert(0);
#endif
Register r = findRegFor(ins, allow);
deprecated_freeRsrcOf(ins, pop);
deprecated_freeRsrcOf(ins);
return r;
}
@ -627,38 +627,46 @@ namespace nanojit
// which case the restore will have already been generated, so we now
// generate the spill (unless the restore was actually a
// rematerialize, in which case it's not necessary).
//
// As for 'pop': it's only relevant on i386 and if 'allow' includes
// FST0, in which case we have to pop if 'ins' isn't in FST0 in the
// post-regstate. This could be because 'ins' is unused, 'ins' is in
// a spill slot, or 'ins' is in an XMM register.
#ifdef NANOJIT_IA32
// If 'allow' includes FST0 we have to pop if 'ins' isn't in FST0 in
// the post-regstate. This could be because 'ins' is unused, 'ins' is
// in a spill slot, or 'ins' is in an XMM register.
const bool pop = (allow & rmask(FST0)) &&
(!ins->isInReg() || ins->getReg() != FST0);
#else
const bool pop = false;
#endif
Register r = findRegFor(ins, allow);
asm_spilli(ins, pop);
asm_maybe_spill(ins, pop);
#ifdef NANOJIT_IA32
if (!ins->isInAr() && pop && r == FST0) {
// This can only happen with a LIR_fcall to an impure function
// whose return value was ignored (ie. if ins->isInReg() was false
// prior to the findRegFor() call).
FSTP(FST0); // pop the fpu result since it isn't used
}
#endif
return r;
}
void Assembler::asm_spilli(LInsp ins, bool pop)
void Assembler::asm_maybe_spill(LInsp ins, bool pop)
{
int d = ins->isInAr() ? arDisp(ins) : 0;
Register r = ins->getReg();
verbose_only( RefBuf b;
if (d && (_logc->lcbits & LC_Assembly)) {
setOutputForEOL(" <= spill %s",
_thisfrag->lirbuf->printer->formatRef(&b, ins)); } )
asm_spill(r, d, pop, ins->isN64());
if (ins->isInAr()) {
verbose_only( RefBuf b;
if (_logc->lcbits & LC_Assembly) {
setOutputForEOL(" <= spill %s",
_thisfrag->lirbuf->printer->formatRef(&b, ins)); } )
asm_spill(r, d, pop, ins->isN64());
}
}
// XXX: This function is error-prone and should be phased out; see bug 513615.
void Assembler::deprecated_freeRsrcOf(LIns *ins, bool pop)
void Assembler::deprecated_freeRsrcOf(LIns *ins)
{
if (ins->isInReg()) {
asm_spilli(ins, pop);
asm_maybe_spill(ins, /*pop*/false);
_allocator.retire(ins->getReg()); // free any register associated with entry
ins->clearReg();
}

View File

@ -344,22 +344,22 @@ namespace nanojit
void assignSaved(RegAlloc &saved, RegisterMask skip);
LInsp findVictim(RegisterMask allow);
Register getBaseReg(LIns *i, int &d, RegisterMask allow);
Register getBaseReg(LIns *ins, int &d, RegisterMask allow);
void getBaseReg2(RegisterMask allowValue, LIns* value, Register& rv,
RegisterMask allowBase, LIns* base, Register& rb, int &d);
#if NJ_USES_QUAD_CONSTANTS
const uint64_t*
findQuadConstant(uint64_t q);
#endif
int findMemFor(LIns* i);
Register findRegFor(LIns* i, RegisterMask allow);
int findMemFor(LIns* ins);
Register findRegFor(LIns* ins, RegisterMask allow);
void findRegFor2(RegisterMask allowa, LIns* ia, Register &ra,
RegisterMask allowb, LIns *ib, Register &rb);
Register findSpecificRegFor(LIns* i, Register r);
Register findSpecificRegForUnallocated(LIns* i, Register r);
Register deprecated_prepResultReg(LIns *i, RegisterMask allow);
Register prepareResultReg(LIns *i, RegisterMask allow);
void deprecated_freeRsrcOf(LIns *i, bool pop);
Register findSpecificRegFor(LIns* ins, Register r);
Register findSpecificRegForUnallocated(LIns* ins, Register r);
Register deprecated_prepResultReg(LIns *ins, RegisterMask allow);
Register prepareResultReg(LIns *ins, RegisterMask allow);
void deprecated_freeRsrcOf(LIns *ins);
void freeResourcesOf(LIns *ins);
void evictIfActive(Register r);
void evict(LIns* vic);
@ -423,25 +423,25 @@ namespace nanojit
void asm_store32(LOpcode op, LIns *val, int d, LIns *base);
void asm_store64(LOpcode op, LIns *val, int d, LIns *base);
void asm_restore(LInsp, Register);
void asm_spilli(LInsp i, bool pop);
void asm_maybe_spill(LInsp ins, bool pop);
void asm_spill(Register rr, int d, bool pop, bool quad);
void asm_load64(LInsp i);
void asm_ret(LInsp p);
void asm_load64(LInsp ins);
void asm_ret(LInsp ins);
#ifdef NANOJIT_64BIT
void asm_immq(LInsp i);
void asm_immq(LInsp ins);
#endif
void asm_immf(LInsp i);
void asm_fcond(LInsp i);
void asm_cond(LInsp i);
void asm_arith(LInsp i);
void asm_neg_not(LInsp i);
void asm_load32(LInsp i);
void asm_cmov(LInsp i);
void asm_param(LInsp i);
void asm_immi(LInsp i);
void asm_immf(LInsp ins);
void asm_fcond(LInsp ins);
void asm_cond(LInsp ins);
void asm_arith(LInsp ins);
void asm_neg_not(LInsp ins);
void asm_load32(LInsp ins);
void asm_cmov(LInsp ins);
void asm_param(LInsp ins);
void asm_immi(LInsp ins);
#if NJ_SOFTFLOAT_SUPPORTED
void asm_qlo(LInsp i);
void asm_qhi(LInsp i);
void asm_qlo(LInsp ins);
void asm_qhi(LInsp ins);
void asm_qjoin(LIns *ins);
#endif
void asm_fneg(LInsp ins);

View File

@ -875,7 +875,7 @@ Assembler::asm_call(LInsp ins)
if (!deprecated_isKnownReg(rr)) {
int d = deprecated_disp(ins);
NanoAssert(d != 0);
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
// The result doesn't have a register allocated, so store the
// result (in R0,R1) directly to its stack slot.
@ -1192,7 +1192,7 @@ Assembler::asm_qjoin(LIns *ins)
// okay if r gets recycled.
r = findRegFor(lo, GpRegs);
STR(r, FP, d);
deprecated_freeRsrcOf(ins, false); // if we had a reg in use, emit a ST to flush it to mem
deprecated_freeRsrcOf(ins); // if we had a reg in use, emit a ST to flush it to mem
}
void
@ -1279,28 +1279,27 @@ Assembler::asm_spill(Register rr, int d, bool pop, bool quad)
{
(void) pop;
(void) quad;
if (d) {
if (_config.arm_vfp && IsFpReg(rr)) {
if (isS8(d >> 2)) {
FSTD(rr, FP, d);
} else {
FSTD(rr, IP, 0);
asm_add_imm(IP, FP, d);
}
NanoAssert(d);
if (_config.arm_vfp && IsFpReg(rr)) {
if (isS8(d >> 2)) {
FSTD(rr, FP, d);
} else {
NIns merged;
STR(rr, FP, d);
// See if we can merge this store into an immediately following one,
// one, by creating or extending a STM instruction.
if (/* is it safe to poke _nIns[1] ? */
does_next_instruction_exist(_nIns, codeStart, codeEnd,
exitStart, exitEnd)
&& /* can we merge _nIns[0] into _nIns[1] ? */
do_peep_2_1(&merged, _nIns[0], _nIns[1])) {
_nIns[1] = merged;
_nIns++;
verbose_only( asm_output("merge next into STMDB"); )
}
FSTD(rr, IP, 0);
asm_add_imm(IP, FP, d);
}
} else {
NIns merged;
STR(rr, FP, d);
// See if we can merge this store into an immediately following one,
// one, by creating or extending a STM instruction.
if (/* is it safe to poke _nIns[1] ? */
does_next_instruction_exist(_nIns, codeStart, codeEnd,
exitStart, exitEnd)
&& /* can we merge _nIns[0] into _nIns[1] ? */
do_peep_2_1(&merged, _nIns[0], _nIns[1])) {
_nIns[1] = merged;
_nIns++;
verbose_only( asm_output("merge next into STMDB"); )
}
}
}
@ -1320,7 +1319,7 @@ Assembler::asm_load64(LInsp ins)
Register rb = findRegFor(base, GpRegs);
NanoAssert(IsGpReg(rb));
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
//outputf("--- load64: Finished register allocation.");
@ -1531,10 +1530,11 @@ Assembler::asm_immf(LInsp ins)
int d = deprecated_disp(ins);
Register rr = ins->deprecated_getReg();
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
if (_config.arm_vfp && deprecated_isKnownReg(rr)) {
asm_spill(rr, d, false, true);
if (d)
asm_spill(rr, d, false, true);
underrunProtect(4*4);
asm_immf_nochk(rr, ins->imm64_0(), ins->imm64_1());

View File

@ -590,7 +590,7 @@ namespace nanojit
SW(r, d+mswoff(), FP);
r = findRegFor(lo, GpRegs); // okay if r gets recycled.
SW(r, d+lswoff(), FP);
deprecated_freeRsrcOf(ins, false); // if we had a reg in use, flush it to mem
deprecated_freeRsrcOf(ins); // if we had a reg in use, flush it to mem
TAG("asm_qjoin(ins=%p{%s})", ins, lirNames[ins->opcode()]);
}
@ -640,10 +640,11 @@ namespace nanojit
int d = deprecated_disp(ins);
Register rr = ins->deprecated_getReg();
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
if (cpu_has_fpu && deprecated_isKnownReg(rr)) {
asm_spill(rr, d, false, true);
if (d)
asm_spill(rr, d, false, true);
asm_li_d(rr, ins->imm64_1(), ins->imm64_0());
}
else {
@ -678,7 +679,7 @@ namespace nanojit
Register rbase = findRegFor(base, GpRegs);
NanoAssert(IsGpReg(rbase));
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
if (cpu_has_fpu && deprecated_isKnownReg(rd)) {
NanoAssert(IsFpReg(rd));
@ -1471,15 +1472,14 @@ namespace nanojit
{
USE(pop);
USE(quad);
if (d) {
if (IsFpReg(rr)) {
NanoAssert(quad);
asm_ldst64(true, rr, d, FP);
}
else {
NanoAssert(!quad);
asm_ldst(OP_SW, rr, d, FP);
}
NanoAssert(d);
if (IsFpReg(rr)) {
NanoAssert(quad);
asm_ldst64(true, rr, d, FP);
}
else {
NanoAssert(!quad);
asm_ldst(OP_SW, rr, d, FP);
}
TAG("asm_spill(rr=%d, d=%d, pop=%d, quad=%d)", rr, d, pop, quad);
}

View File

@ -224,7 +224,7 @@ namespace nanojit
Register rr = ins->deprecated_getReg();
if (deprecated_isKnownReg(rr) && (rmask(rr) & FpRegs)) {
// FPR already assigned, fine, use it
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
} else {
// use a GPR register; its okay to copy doubles with GPR's
// but *not* okay to copy non-doubles with FPR's
@ -811,20 +811,19 @@ namespace nanojit
void Assembler::asm_spill(Register rr, int d, bool /* pop */, bool quad) {
(void)quad;
if (d) {
if (IsFpReg(rr)) {
NanoAssert(quad);
STFD(rr, d, FP);
}
#ifdef NANOJIT_64BIT
else if (quad) {
STD(rr, d, FP);
}
#endif
else {
NanoAssert(!quad);
STW(rr, d, FP);
}
NanoAssert(d);
if (IsFpReg(rr)) {
NanoAssert(quad);
STFD(rr, d, FP);
}
#ifdef NANOJIT_64BIT
else if (quad) {
STD(rr, d, FP);
}
#endif
else {
NanoAssert(!quad);
STW(rr, d, FP);
}
}
@ -1072,7 +1071,7 @@ namespace nanojit
Register r = ins->deprecated_getReg();
if (deprecated_isKnownReg(r) && (rmask(r) & FpRegs)) {
// FPR already assigned, fine, use it
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
} else {
// use a GPR register; its okay to copy doubles with GPR's
// but *not* okay to copy non-doubles with FPR's

View File

@ -317,12 +317,11 @@ namespace nanojit
{
underrunProtect(24);
(void)quad;
if (d) {
if (rmask(rr) & FpRegs) {
STDF32(rr, d, FP);
} else {
STW32(rr, d, FP);
}
NanoAssert(d);
if (rmask(rr) & FpRegs) {
STDF32(rr, d, FP);
} else {
STW32(rr, d, FP);
}
}
@ -359,7 +358,7 @@ namespace nanojit
if (dr)
asm_mmq(FP, dr, rb, db);
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
if (rr != deprecated_UnknownReg)
{
@ -823,7 +822,7 @@ namespace nanojit
// @todo, if we used xor, ldsd, fldz, etc above, we don't need mem here
int d = deprecated_disp(ins);
deprecated_freeRsrcOf(ins, false);
deprecated_freeRsrcOf(ins);
if (d)
{
STW32(L2, d+4, FP);

View File

@ -1759,17 +1759,16 @@ namespace nanojit
}
void Assembler::asm_spill(Register rr, int d, bool /*pop*/, bool quad) {
if (d) {
if (!IsFpReg(rr)) {
if (quad)
MOVQMR(rr, d, FP);
else
MOVLMR(rr, d, FP);
} else {
// store 64bits from XMM to memory
NanoAssert(quad);
MOVSDMR(rr, d, FP);
}
NanoAssert(d);
if (!IsFpReg(rr)) {
if (quad)
MOVQMR(rr, d, FP);
else
MOVLMR(rr, d, FP);
} else {
// store 64bits from XMM to memory
NanoAssert(quad);
MOVSDMR(rr, d, FP);
}
}

View File

@ -465,21 +465,14 @@ namespace nanojit
void Assembler::asm_spill(Register rr, int d, bool pop, bool quad)
{
(void)quad;
if (d)
{
if (rmask(rr) & GpRegs) {
ST(FP, d, rr);
} else if (rmask(rr) & XmmRegs) {
SSE_STQ(d, FP, rr);
} else {
NanoAssert(rmask(rr) & x87Regs);
FSTQ((pop?1:0), d, FP);
}
}
else if (pop && (rmask(rr) & x87Regs))
{
// pop the fpu result since it isn't used
FSTP(FST0);
NanoAssert(d);
if (rmask(rr) & GpRegs) {
ST(FP, d, rr);
} else if (rmask(rr) & XmmRegs) {
SSE_STQ(d, FP, rr);
} else {
NanoAssert(rmask(rr) & x87Regs);
FSTQ((pop?1:0), d, FP);
}
}
@ -501,7 +494,7 @@ namespace nanojit
//
if (ins->isInReg()) {
Register rr = ins->getReg();
asm_spilli(ins, false); // if also in memory in post-state, spill it now
asm_maybe_spill(ins, false); // if also in memory in post-state, spill it now
switch (ins->opcode()) {
case LIR_ldf:
if (rmask(rr) & XmmRegs) {