mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 552374 - nanojit: clean up asm_spill() and friends a little. r=edwsmith.
--HG-- extra : convert_revision : 5806c6f3bf1257fc3142f5eb8718e01071bcbb35
This commit is contained in:
parent
19cf26c03a
commit
5d4adc4b29
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user