mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 539379 - TM: Crash [@ ExecuteTrace] or [@ ExecuteTree]. r=edwsmith.
--HG-- extra : convert_revision : a5115ee971c8496182e9b4f6847ad91619b4a585
This commit is contained in:
parent
6a8645f974
commit
0c9683a5c5
@ -371,34 +371,39 @@ namespace nanojit
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
|
||||
void Assembler::findRegFor2(RegisterMask allow, LIns* ia, Register& ra, LIns* ib, Register& rb)
|
||||
void Assembler::findRegFor2(RegisterMask allowa, LIns* ia, Register& ra,
|
||||
RegisterMask allowb, LIns* ib, Register& rb)
|
||||
{
|
||||
// There should be some overlap between 'allowa' and 'allowb', else
|
||||
// there's no point calling this function.
|
||||
NanoAssert(allowa & allowb);
|
||||
|
||||
if (ia == ib) {
|
||||
ra = rb = findRegFor(ia, allow);
|
||||
ra = rb = findRegFor(ia, allowa & allowb); // use intersection(allowa, allowb)
|
||||
} else {
|
||||
// You might think we could just do this:
|
||||
//
|
||||
// ra = findRegFor(ia, allow);
|
||||
// rb = findRegFor(ib, allow & ~rmask(ra));
|
||||
// ra = findRegFor(ia, allowa);
|
||||
// rb = findRegFor(ib, allowb & ~rmask(ra));
|
||||
//
|
||||
// But if 'ib' was already in an allowed register, the first
|
||||
// findRegFor() call could evict it, whereupon the second
|
||||
// findRegFor() call would immediately restore it, which is
|
||||
// sub-optimal. What we effectively do instead is this:
|
||||
//
|
||||
// ra = findRegFor(ia, allow & ~rmask(rb));
|
||||
// rb = findRegFor(ib, allow & ~rmask(ra));
|
||||
// ra = findRegFor(ia, allowa & ~rmask(rb));
|
||||
// rb = findRegFor(ib, allowb & ~rmask(ra));
|
||||
//
|
||||
// but we have to determine what 'rb' initially is to avoid the
|
||||
// mutual dependency between the assignments.
|
||||
bool rbDone = !ib->isUnusedOrHasUnknownReg() && (rb = ib->getReg(), allow & rmask(rb));
|
||||
bool rbDone = !ib->isUnusedOrHasUnknownReg() && (rb = ib->getReg(), allowb & rmask(rb));
|
||||
if (rbDone) {
|
||||
allow &= ~rmask(rb); // ib already in an allowable reg, keep that one
|
||||
allowa &= ~rmask(rb); // ib already in an allowable reg, keep that one
|
||||
}
|
||||
ra = findRegFor(ia, allow);
|
||||
ra = findRegFor(ia, allowa);
|
||||
if (!rbDone) {
|
||||
allow &= ~rmask(ra);
|
||||
rb = findRegFor(ib, allow);
|
||||
allowb &= ~rmask(ra);
|
||||
rb = findRegFor(ib, allowb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -432,6 +437,27 @@ namespace nanojit
|
||||
return findRegFor(i, allow);
|
||||
}
|
||||
|
||||
// Like findRegFor2(), but used for stores where the base value has the
|
||||
// same type as the stored value, eg. in asm_store32() on 32-bit platforms
|
||||
// and asm_store64() on 64-bit platforms. Similar to getBaseReg(),
|
||||
// findRegFor2() can be called instead, but this function can optimize the
|
||||
// case where the base value is a LIR_alloc.
|
||||
void Assembler::getBaseReg2(RegisterMask allowValue, LIns* value, Register& rv,
|
||||
RegisterMask allowBase, LIns* base, Register& rb, int &d)
|
||||
{
|
||||
#if !PEDANTIC
|
||||
if (base->isop(LIR_alloc)) {
|
||||
rb = FP;
|
||||
d += findMemFor(base);
|
||||
rv = findRegFor(value, allowValue);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
(void) d;
|
||||
#endif
|
||||
findRegFor2(allowValue, value, rv, allowBase, base, rb);
|
||||
}
|
||||
|
||||
// Finds a register in 'allow' to hold the result of 'ins'. Used when we
|
||||
// encounter a use of 'ins'. The actions depend on the prior regstate of
|
||||
// 'ins':
|
||||
|
@ -327,13 +327,16 @@ namespace nanojit
|
||||
LInsp findVictim(RegisterMask allow);
|
||||
|
||||
Register getBaseReg(LIns *i, 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);
|
||||
void findRegFor2(RegisterMask allow, LIns* ia, Register &ra, LIns *ib, Register &rb);
|
||||
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 prepResultReg(LIns *i, RegisterMask allow);
|
||||
|
@ -1219,13 +1219,7 @@ Assembler::asm_store32(LOpcode op, LIns *value, int dr, LIns *base)
|
||||
}
|
||||
|
||||
Register ra, rb;
|
||||
if (base->isop(LIR_alloc)) {
|
||||
rb = FP;
|
||||
dr += findMemFor(base);
|
||||
ra = findRegFor(value, GpRegs);
|
||||
} else {
|
||||
findRegFor2(GpRegs, value, ra, base, rb);
|
||||
}
|
||||
getBaseReg2(GpRegs, value, ra, GpRegs, base, rb, dr);
|
||||
|
||||
if (isU12(-dr) || isU12(dr)) {
|
||||
STR(ra, rb, dr);
|
||||
@ -2102,7 +2096,7 @@ Assembler::asm_fcmp(LInsp ins)
|
||||
NanoAssert(op >= LIR_feq && op <= LIR_fge);
|
||||
|
||||
Register ra, rb;
|
||||
findRegFor2(FpRegs, lhs, ra, rhs, rb);
|
||||
findRegFor2(FpRegs, lhs, ra, FpRegs, rhs, rb);
|
||||
|
||||
int e_bit = (op != LIR_feq);
|
||||
|
||||
@ -2215,7 +2209,7 @@ Assembler::asm_cmp(LIns *cond)
|
||||
}
|
||||
} else {
|
||||
Register ra, rb;
|
||||
findRegFor2(GpRegs, lhs, ra, rhs, rb);
|
||||
findRegFor2(GpRegs, lhs, ra, GpRegs, rhs, rb);
|
||||
CMP(ra, rb);
|
||||
}
|
||||
}
|
||||
|
@ -972,7 +972,7 @@ namespace nanojit
|
||||
RegisterMask allow = FpRegs;
|
||||
Register rr = prepResultReg(ins, allow);
|
||||
Register ra, rb;
|
||||
findRegFor2(allow, lhs, ra, rhs, rb);
|
||||
findRegFor2(allow, lhs, ra, allow, rhs, rb);
|
||||
switch (op) {
|
||||
case LIR_fadd: FADD(rr, ra, rb); break;
|
||||
case LIR_fsub: FSUB(rr, ra, rb); break;
|
||||
|
@ -334,17 +334,13 @@ namespace nanojit
|
||||
{
|
||||
// make sure what is in a register
|
||||
Register ra, rb;
|
||||
if (base->isop(LIR_alloc)) {
|
||||
rb = FP;
|
||||
dr += findMemFor(base);
|
||||
ra = findRegFor(value, GpRegs);
|
||||
} else if (base->isconst()) {
|
||||
if (base->isconst()) {
|
||||
// absolute address
|
||||
dr += base->imm32();
|
||||
ra = findRegFor(value, GpRegs);
|
||||
rb = G0;
|
||||
} else {
|
||||
findRegFor2(GpRegs, value, ra, base, rb);
|
||||
getBaseReg2(GpRegs, value, ra, GpRegs, base, rb, dr);
|
||||
}
|
||||
STW32(ra, dr, rb);
|
||||
}
|
||||
@ -601,7 +597,7 @@ namespace nanojit
|
||||
else
|
||||
{
|
||||
Register ra, rb;
|
||||
findRegFor2(GpRegs, lhs, ra, rhs, rb);
|
||||
findRegFor2(GpRegs, lhs, ra, GpRegs, rhs, rb);
|
||||
SUBCC(ra, rb, G0);
|
||||
}
|
||||
}
|
||||
|
@ -1155,7 +1155,7 @@ namespace nanojit
|
||||
LIns *a = cond->oprnd1();
|
||||
Register ra, rb;
|
||||
if (a != b) {
|
||||
findRegFor2(GpRegs, a, ra, b, rb);
|
||||
findRegFor2(GpRegs, a, ra, GpRegs, b, rb);
|
||||
} else {
|
||||
// optimize-me: this will produce a const result!
|
||||
ra = rb = findRegFor(a, GpRegs);
|
||||
@ -1287,7 +1287,7 @@ namespace nanojit
|
||||
|
||||
void Assembler::fcmp(LIns *a, LIns *b) {
|
||||
Register ra, rb;
|
||||
findRegFor2(FpRegs, a, ra, b, rb);
|
||||
findRegFor2(FpRegs, a, ra, FpRegs, b, rb);
|
||||
UCOMISD(ra, rb);
|
||||
}
|
||||
|
||||
@ -1463,20 +1463,21 @@ namespace nanojit
|
||||
void Assembler::asm_store64(LOpcode op, LIns *value, int d, LIns *base) {
|
||||
NanoAssert(value->isQuad());
|
||||
|
||||
Register b = getBaseReg(base, d, BaseRegs);
|
||||
|
||||
switch (op) {
|
||||
case LIR_stqi: {
|
||||
Register r = findRegFor(value, GpRegs & ~rmask(b));
|
||||
Register r, b;
|
||||
getBaseReg2(GpRegs, value, r, BaseRegs, base, b, d);
|
||||
MOVQMR(r, d, b); // gpr store
|
||||
break;
|
||||
}
|
||||
case LIR_stfi: {
|
||||
Register b = getBaseReg(base, d, BaseRegs);
|
||||
Register r = findRegFor(value, FpRegs);
|
||||
MOVSDMR(r, d, b); // xmm store
|
||||
break;
|
||||
}
|
||||
case LIR_st32f: {
|
||||
Register b = getBaseReg(base, d, BaseRegs);
|
||||
Register r = findRegFor(value, FpRegs);
|
||||
Register t = registerAllocTmp(FpRegs & ~rmask(r));
|
||||
|
||||
|
@ -504,17 +504,13 @@ namespace nanojit
|
||||
GpRegs;
|
||||
|
||||
Register ra, rb;
|
||||
if (base->isop(LIR_alloc)) {
|
||||
rb = FP;
|
||||
dr += findMemFor(base);
|
||||
ra = findRegFor(value, SrcRegs);
|
||||
} else if (base->isconst()) {
|
||||
if (base->isconst()) {
|
||||
// absolute address
|
||||
rb = UnknownReg;
|
||||
dr += base->imm32();
|
||||
ra = findRegFor(value, SrcRegs);
|
||||
} else {
|
||||
findRegFor2(SrcRegs, value, ra, base, rb);
|
||||
getBaseReg2(SrcRegs, value, ra, GpRegs, base, rb, dr);
|
||||
}
|
||||
switch (op) {
|
||||
case LIR_stb:
|
||||
@ -854,7 +850,7 @@ namespace nanojit
|
||||
|
||||
} else {
|
||||
Register ra, rb;
|
||||
findRegFor2(GpRegs, lhs, ra, rhs, rb);
|
||||
findRegFor2(GpRegs, lhs, ra, GpRegs, rhs, rb);
|
||||
CMP(ra, rb);
|
||||
}
|
||||
}
|
||||
@ -1937,7 +1933,7 @@ namespace nanojit
|
||||
|
||||
evictIfActive(EAX);
|
||||
Register ra, rb;
|
||||
findRegFor2(XmmRegs, lhs, ra, rhs, rb);
|
||||
findRegFor2(XmmRegs, lhs, ra, XmmRegs, rhs, rb);
|
||||
|
||||
TEST_AH(mask);
|
||||
LAHF();
|
||||
@ -1961,7 +1957,7 @@ namespace nanojit
|
||||
// LESS_THAN 001 SETAE/JAE fails
|
||||
|
||||
Register ra, rb;
|
||||
findRegFor2(XmmRegs, lhs, ra, rhs, rb);
|
||||
findRegFor2(XmmRegs, lhs, ra, XmmRegs, rhs, rb);
|
||||
SSE_UCOMISD(ra, rb);
|
||||
}
|
||||
|
||||
|
@ -933,28 +933,28 @@ namespace nanojit
|
||||
#define FSTPQ(d,b) FSTQ(1,d,b)
|
||||
#define FCOM(p,d,b) do { count_fpuld(); FPUm(0xdc02|(p), d, b); asm_output("fcom%s %d(%s)",((p)?"p":""),d,gpn(b)); if (p) fpu_pop(); } while(0)
|
||||
#define FCOMdm(p,m) do { const double* const dm = m; \
|
||||
count_fpuld(); FPUdm(0xdc02|(p), dm); asm_output("fcom%s (%p)",((p)?"p":""),dm); if (p) fpu_pop(); } while(0)
|
||||
count_fpuld(); FPUdm(0xdc02|(p), dm); asm_output("fcom%s (%p)",((p)?"p":""),(void*)dm); if (p) fpu_pop(); } while(0)
|
||||
#define FLD32(d,b) do { count_ldq(); FPUm(0xd900, d, b); asm_output("fld32 %d(%s)",d,gpn(b)); fpu_push();} while(0)
|
||||
#define FLDQ(d,b) do { count_ldq(); FPUm(0xdd00, d, b); asm_output("fldq %d(%s)",d,gpn(b)); fpu_push();} while(0)
|
||||
#define FLDQdm(m) do { const double* const dm = m; \
|
||||
count_ldq(); FPUdm(0xdd00, dm); asm_output("fldq (%p)",dm); fpu_push();} while(0)
|
||||
count_ldq(); FPUdm(0xdd00, dm); asm_output("fldq (%p)",(void*)dm); fpu_push();} while(0)
|
||||
#define FILDQ(d,b) do { count_fpuld(); FPUm(0xdf05, d, b); asm_output("fildq %d(%s)",d,gpn(b)); fpu_push(); } while(0)
|
||||
#define FILD(d,b) do { count_fpuld(); FPUm(0xdb00, d, b); asm_output("fild %d(%s)",d,gpn(b)); fpu_push(); } while(0)
|
||||
#define FIST(p,d,b) do { count_fpu(); FPUm(0xdb02|(p), d, b); asm_output("fist%s %d(%s)",((p)?"p":""),d,gpn(b)); if(p) fpu_pop(); } while(0)
|
||||
#define FADD(d,b) do { count_fpu(); FPUm(0xdc00, d, b); asm_output("fadd %d(%s)",d,gpn(b)); } while(0)
|
||||
#define FADDdm(m) do { const double* const dm = m; \
|
||||
count_ldq(); FPUdm(0xdc00, dm); asm_output("fadd (%p)",dm); } while(0)
|
||||
count_ldq(); FPUdm(0xdc00, dm); asm_output("fadd (%p)",(void*)dm); } while(0)
|
||||
#define FSUB(d,b) do { count_fpu(); FPUm(0xdc04, d, b); asm_output("fsub %d(%s)",d,gpn(b)); } while(0)
|
||||
#define FSUBR(d,b) do { count_fpu(); FPUm(0xdc05, d, b); asm_output("fsubr %d(%s)",d,gpn(b)); } while(0)
|
||||
#define FSUBRdm(m) do { const double* const dm = m; \
|
||||
count_ldq(); FPUdm(0xdc05, dm); asm_output("fsubr (%p)",dm); } while(0)
|
||||
count_ldq(); FPUdm(0xdc05, dm); asm_output("fsubr (%p)",(void*)dm); } while(0)
|
||||
#define FMUL(d,b) do { count_fpu(); FPUm(0xdc01, d, b); asm_output("fmul %d(%s)",d,gpn(b)); } while(0)
|
||||
#define FMULdm(m) do { const double* const dm = m; \
|
||||
count_ldq(); FPUdm(0xdc01, dm); asm_output("fmul (%p)",dm); } while(0)
|
||||
count_ldq(); FPUdm(0xdc01, dm); asm_output("fmul (%p)",(void*)dm); } while(0)
|
||||
#define FDIV(d,b) do { count_fpu(); FPUm(0xdc06, d, b); asm_output("fdiv %d(%s)",d,gpn(b)); } while(0)
|
||||
#define FDIVR(d,b) do { count_fpu(); FPUm(0xdc07, d, b); asm_output("fdivr %d(%s)",d,gpn(b)); } while(0)
|
||||
#define FDIVRdm(m) do { const double* const dm = m; \
|
||||
count_ldq(); FPUdm(0xdc07, dm); asm_output("fdivr (%p)",dm); } while(0)
|
||||
count_ldq(); FPUdm(0xdc07, dm); asm_output("fdivr (%p)",(void*)dm); } while(0)
|
||||
#define FINCSTP() do { count_fpu(); FPUc(0xd9f7); asm_output("fincstp"); } while(0)
|
||||
#define FSTP(r) do { count_fpu(); FPU(0xddd8, r&7); asm_output("fstp %s",fpn(r)); fpu_pop();} while(0)
|
||||
#define FCOMP() do { count_fpu(); FPUc(0xD8D9); asm_output("fcomp"); fpu_pop();} while(0)
|
||||
|
Loading…
Reference in New Issue
Block a user