* Bugfixed some popup dialogs, which would sometimes be too small or empty.

* Various small cleanups to emitters and microVU's regalloc code (no functional changes)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3162 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-06-05 04:07:58 +00:00
parent b7c9aa63cd
commit df3bda9183
6 changed files with 110 additions and 89 deletions

View File

@ -616,45 +616,15 @@ template< typename T > void xWrite( T val );
s32 Displacement; // offset applied to the Base/Index registers. s32 Displacement; // offset applied to the Base/Index registers.
public: public:
explicit ModSibBase( const xAddressInfo& src ) explicit ModSibBase( const xAddressInfo& src );
{ explicit ModSibBase( s32 disp );
Base = src.Base; ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 );
Index = src.Index;
Scale = src.Factor;
Displacement= src.Displacement;
Reduce(); virtual uint GetOperandSize() const;
} ModSibBase& Add( s32 imm );
ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 )
{
Base = base;
Index = index;
Scale = scale;
Displacement= displacement;
Reduce();
}
explicit ModSibBase( s32 disp )
{
Base = xEmptyReg;
Index = xEmptyReg;
Scale = 0;
Displacement= disp;
// no reduction necessary :D
}
virtual uint GetOperandSize() const { pxFail( "Invalid operation on ModSibBase" ); return 0; }
bool IsByteSizeDisp() const { return is_s8( Displacement ); } bool IsByteSizeDisp() const { return is_s8( Displacement ); }
ModSibBase& Add( s32 imm )
{
Displacement += imm;
return *this;
}
__forceinline ModSibBase operator+( const s32 imm ) const { return ModSibBase( *this ).Add( imm ); } __forceinline ModSibBase operator+( const s32 imm ) const { return ModSibBase( *this ).Add( imm ); }
__forceinline ModSibBase operator-( const s32 imm ) const { return ModSibBase( *this ).Add( -imm ); } __forceinline ModSibBase operator-( const s32 imm ) const { return ModSibBase( *this ).Add( -imm ); }
@ -690,8 +660,8 @@ template< typename T > void xWrite( T val );
public: \ public: \
explicit ModSib##bits( const xAddressInfo& src ) : _parent( src ) {} \ explicit ModSib##bits( const xAddressInfo& src ) : _parent( src ) {} \
explicit ModSib##bits( s32 disp ) : _parent( disp ) {} \ explicit ModSib##bits( s32 disp ) : _parent( disp ) {} \
ModSib##bits( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) : \ ModSib##bits( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) \
_parent( base, index, scale, displacement ) {} \ : _parent( base, index, scale, displacement ) {} \
\ \
virtual uint GetOperandSize() const { return bits / 8; } \ virtual uint GetOperandSize() const { return bits / 8; } \
\ \
@ -730,8 +700,9 @@ template< typename T > void xWrite( T val );
// xAddressReg types go in, and ModSibBase derived types come out. // xAddressReg types go in, and ModSibBase derived types come out.
// //
template< typename xModSibType > template< typename xModSibType >
struct xAddressIndexer class xAddressIndexer
{ {
public:
// passthrough instruction, allows ModSib to pass silently through ptr translation // passthrough instruction, allows ModSib to pass silently through ptr translation
// without doing anything and without compiler error. // without doing anything and without compiler error.
const xModSibType& operator[]( const xModSibType& src ) const { return src; } const xModSibType& operator[]( const xModSibType& src ) const { return src; }

View File

@ -30,6 +30,8 @@ Threading::WaitForTaskDialog::WaitForTaskDialog( const wxString& title, const wx
: wxDialogWithHelpers( NULL, _("Waiting for tasks...") ) : wxDialogWithHelpers( NULL, _("Waiting for tasks...") )
//, m_Timer(this) //, m_Timer(this)
{ {
SetMinWidth( 300 );
//m_sem = sem; //m_sem = sem;
//m_mutex = mutex; //m_mutex = mutex;
@ -42,7 +44,7 @@ Threading::WaitForTaskDialog::WaitForTaskDialog( const wxString& title, const wx
Connect( pxEvt_ThreadedTaskComplete, wxCommandEventHandler(WaitForTaskDialog::OnTaskComplete) ); Connect( pxEvt_ThreadedTaskComplete, wxCommandEventHandler(WaitForTaskDialog::OnTaskComplete) );
*this += 12; *this += 12;
*this += Heading(m_heading) | StdExpand(); *this += Heading(m_heading).Unwrapped() | StdExpand();
*this += 12; *this += 12;
// TODO : Implement a cancel button. Not quite sure the best way to do // TODO : Implement a cancel button. Not quite sure the best way to do

View File

@ -27,7 +27,7 @@ void x86capabilities::CountLogicalCores()
if( !GetProcessAffinityMask (GetCurrentProcess (), if( !GetProcessAffinityMask (GetCurrentProcess (),
&vProcessCPUs, &vSystemCPUs) ) return; &vProcessCPUs, &vSystemCPUs) ) return;
int CPUs = 0; uint CPUs = 0;
DWORD bit; DWORD bit;
for (bit = 1; bit != 0; bit <<= 1) for (bit = 1; bit != 0; bit <<= 1)

View File

@ -491,8 +491,36 @@ xAddressInfo& xAddressInfo::Add( const xAddressInfo& src )
return *this; return *this;
} }
ModSibBase::ModSibBase( const xAddressInfo& src )
{
Base = src.Base;
Index = src.Index;
Scale = src.Factor;
Displacement= src.Displacement;
Reduce();
}
ModSibBase::ModSibBase( s32 disp )
{
Base = xEmptyReg;
Index = xEmptyReg;
Scale = 0;
Displacement= disp;
// no reduction necessary :D
}
ModSibBase::ModSibBase( xAddressReg base, xAddressReg index, int scale, s32 displacement )
{
Base = base;
Index = index;
Scale = scale;
Displacement= displacement;
Reduce();
}
// ------------------------------------------------------------------------
// Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values. // Generates a 'reduced' ModSib form, which has valid Base, Index, and Scale values.
// Necessary because by default ModSib compounds registers into Index when possible. // Necessary because by default ModSib compounds registers into Index when possible.
// //
@ -570,6 +598,17 @@ void ModSibBase::Reduce()
} }
} }
uint ModSibBase::GetOperandSize() const
{
pxFail( "Invalid operation on ModSibBase" );
return 0;
}
ModSibBase& ModSibBase::Add( s32 imm )
{
Displacement += imm;
return *this;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Internal implementation of EmitSibMagic which has been custom tailored // Internal implementation of EmitSibMagic which has been custom tailored

View File

@ -36,7 +36,8 @@ static int pxMessageDialog( const wxString& caption, const wxString& content, co
// And in either case the emulation should be paused/suspended for the user. // And in either case the emulation should be paused/suspended for the user.
wxDialogWithHelpers dialog( NULL, caption ); wxDialogWithHelpers dialog( NULL, caption );
dialog += dialog.Heading( content ); dialog.SetMinWidth( (content.Length() > 256) ? 525 : 460 );
dialog += dialog.Heading( content ) | StdExpand();
return pxIssueConfirmation( dialog, buttons ); return pxIssueConfirmation( dialog, buttons );
} }

View File

@ -167,8 +167,8 @@ void mVUsaveReg(int reg, uptr offset, int xyzw, bool modXYZW);
void mVUloadReg(int reg, uptr offset, int xyzw); void mVUloadReg(int reg, uptr offset, int xyzw);
void mVUloadIreg(int reg, int xyzw, VURegs* vuRegs); void mVUloadIreg(int reg, int xyzw, VURegs* vuRegs);
struct microXMM { struct microMapXMM {
int reg; // VF Reg Number Stored (-1 = Temp; 0 = vf0 and will not be written back; 32 = ACC; 33 = I reg) int VFreg; // VF Reg Number Stored (-1 = Temp; 0 = vf0 and will not be written back; 32 = ACC; 33 = I reg)
int xyzw; // xyzw to write back (0 = Don't write back anything AND cached vfReg has all vectors valid) int xyzw; // xyzw to write back (0 = Don't write back anything AND cached vfReg has all vectors valid)
int count; // Count of when last used int count; // Count of when last used
bool isNeeded; // Is needed for current instruction bool isNeeded; // Is needed for current instruction
@ -177,27 +177,27 @@ struct microXMM {
#define xmmTotal 7 // Don't allocate PQ? #define xmmTotal 7 // Don't allocate PQ?
class microRegAlloc { class microRegAlloc {
private: private:
microXMM xmmReg[xmmTotal]; microMapXMM xmmMap[xmmTotal];
VURegs* vuRegs; VURegs* vuRegs;
int counter; int counter;
int findFreeRegRec(int startIdx) { int findFreeRegRec(int startIdx) {
for (int i = startIdx; i < xmmTotal; i++) { for (int i = startIdx; i < xmmTotal; i++) {
if (!xmmReg[i].isNeeded) { if (!xmmMap[i].isNeeded) {
int x = findFreeRegRec(i+1); int x = findFreeRegRec(i+1);
if (x == -1) return i; if (x == -1) return i;
return ((xmmReg[i].count < xmmReg[x].count) ? i : x); return ((xmmMap[i].count < xmmMap[x].count) ? i : x);
} }
} }
return -1; return -1;
} }
int findFreeReg() { int findFreeReg() {
for (int i = 0; i < xmmTotal; i++) { for (int i = 0; i < xmmTotal; i++) {
if (!xmmReg[i].isNeeded && (xmmReg[i].reg < 0)) { if (!xmmMap[i].isNeeded && (xmmMap[i].VFreg < 0)) {
return i; // Reg is not needed and was a temp reg return i; // Reg is not needed and was a temp reg
} }
} }
int x = findFreeRegRec(0); int x = findFreeRegRec(0);
if (x < 0) { DevCon.Error("microVU Allocation Error!"); return 0; } pxAssumeDev( x >= 0, "microVU register allocation failure!" );
return x; return x;
} }
@ -219,34 +219,38 @@ public:
} }
} }
void clearReg(int reg) { void clearReg(int reg) {
xmmReg[reg].reg = -1; microMapXMM& clear( xmmMap[reg] );
xmmReg[reg].count = 0; clear.VFreg = -1;
xmmReg[reg].xyzw = 0; clear.count = 0;
xmmReg[reg].isNeeded = 0; clear.xyzw = 0;
clear.isNeeded = 0;
} }
void clearRegVF(int VFreg) { void clearRegVF(int VFreg) {
for (int i = 0; i < xmmTotal; i++) { for (int i = 0; i < xmmTotal; i++) {
if (xmmReg[i].reg == VFreg) clearReg(i); if (xmmMap[i].VFreg == VFreg) clearReg(i);
} }
} }
void writeBackReg(int reg, bool invalidateRegs = 1) { void writeBackReg(int reg, bool invalidateRegs = 1) {
if ((xmmReg[reg].reg > 0) && xmmReg[reg].xyzw) { // Reg was modified and not Temp or vf0 microMapXMM& write( xmmMap[reg] );
if (xmmReg[reg].reg == 33) SSE_MOVSS_XMM_to_M32((uptr)&vuRegs->VI[REG_I].UL, reg);
else if (xmmReg[reg].reg == 32) mVUsaveReg(reg, (uptr)&vuRegs->ACC.UL[0], xmmReg[reg].xyzw, 1); if ((write.VFreg > 0) && write.xyzw) { // Reg was modified and not Temp or vf0
else mVUsaveReg(reg, (uptr)&vuRegs->VF[xmmReg[reg].reg].UL[0], xmmReg[reg].xyzw, 1); if (write.VFreg == 33) SSE_MOVSS_XMM_to_M32((uptr)&vuRegs->VI[REG_I].UL, reg);
else if (write.VFreg == 32) mVUsaveReg(reg, (uptr)&vuRegs->ACC.UL[0], write.xyzw, 1);
else mVUsaveReg(reg, (uptr)&vuRegs->VF[write.VFreg].UL[0], write.xyzw, 1);
if (invalidateRegs) { if (invalidateRegs) {
for (int i = 0; i < xmmTotal; i++) { for (int i = 0; i < xmmTotal; i++) {
if ((i == reg) || xmmReg[i].isNeeded) continue; microMapXMM& imap (xmmMap[i]);
if (xmmReg[i].reg == xmmReg[reg].reg) { if ((i == reg) || imap.isNeeded) continue;
if (xmmReg[i].xyzw && xmmReg[i].xyzw < 0xf) DevCon.Error("microVU Error: writeBackReg() [%d]", xmmReg[i].reg); if (imap.VFreg == write.VFreg) {
if (imap.xyzw && imap.xyzw < 0xf) DevCon.Error("microVU Error: writeBackReg() [%d]", imap.VFreg);
clearReg(i); // Invalidate any Cached Regs of same vf Reg clearReg(i); // Invalidate any Cached Regs of same vf Reg
} }
} }
} }
if (xmmReg[reg].xyzw == 0xf) { // Make Cached Reg if All Vectors were Modified if (write.xyzw == 0xf) { // Make Cached Reg if All Vectors were Modified
xmmReg[reg].count = counter; write.count = counter;
xmmReg[reg].xyzw = 0; write.xyzw = 0;
xmmReg[reg].isNeeded = 0; write.isNeeded = 0;
return; return;
} }
} }
@ -254,19 +258,22 @@ public:
} }
void clearNeeded(int reg) { void clearNeeded(int reg) {
if ((reg < 0) || (reg >= xmmTotal)) return; if ((reg < 0) || (reg >= xmmTotal)) return;
xmmReg[reg].isNeeded = 0;
if (xmmReg[reg].xyzw) { // Reg was modified microMapXMM& clear (xmmMap[reg]);
if (xmmReg[reg].reg > 0) { clear.isNeeded = 0;
if (clear.xyzw) { // Reg was modified
if (clear.VFreg > 0) {
int mergeRegs = 0; int mergeRegs = 0;
if (xmmReg[reg].xyzw < 0xf) { mergeRegs = 1; } // Try to merge partial writes if (clear.xyzw < 0xf) { mergeRegs = 1; } // Try to merge partial writes
for (int i = 0; i < xmmTotal; i++) { // Invalidate any other read-only regs of same vfReg for (int i = 0; i < xmmTotal; i++) { // Invalidate any other read-only regs of same vfReg
if (i == reg) continue; if (i == reg) continue;
if (xmmReg[i].reg == xmmReg[reg].reg) { microMapXMM& imap (xmmMap[i]);
if (xmmReg[i].xyzw && xmmReg[i].xyzw < 0xf) DevCon.Error("microVU Error: clearNeeded() [%d]", xmmReg[i].reg); if (imap.VFreg == clear.VFreg) {
if (imap.xyzw && imap.xyzw < 0xf) DevCon.Error("microVU Error: clearNeeded() [%d]", imap.VFreg);
if (mergeRegs == 1) { if (mergeRegs == 1) {
mVUmergeRegs(i, reg, xmmReg[reg].xyzw, 1); mVUmergeRegs(i, reg, clear.xyzw, 1);
xmmReg[i].xyzw = 0xf; imap.xyzw = 0xf;
xmmReg[i].count = counter; imap.count = counter;
mergeRegs = 2; mergeRegs = 2;
} }
else clearReg(i); else clearReg(i);
@ -282,8 +289,9 @@ public:
counter++; counter++;
if (vfLoadReg >= 0) { // Search For Cached Regs if (vfLoadReg >= 0) { // Search For Cached Regs
for (int i = 0; i < xmmTotal; i++) { for (int i = 0; i < xmmTotal; i++) {
if ((xmmReg[i].reg == vfLoadReg) && (!xmmReg[i].xyzw // Reg Was Not Modified microMapXMM& imap (xmmMap[i]);
|| (xmmReg[i].reg && (xmmReg[i].xyzw==0xf)))) { // Reg Had All Vectors Modified and != VF0 if ((imap.VFreg == vfLoadReg) && (!imap.xyzw // Reg Was Not Modified
|| (imap.VFreg && (imap.xyzw==0xf)))) { // Reg Had All Vectors Modified and != VF0
int z = i; int z = i;
if (vfWriteReg >= 0) { // Reg will be modified if (vfWriteReg >= 0) { // Reg will be modified
if (cloneWrite) { // Clone Reg so as not to use the same Cached Reg if (cloneWrite) { // Clone Reg so as not to use the same Cached Reg
@ -294,7 +302,7 @@ public:
else if (xyzw == 2) SSE2_PSHUFD_XMM_to_XMM(z, i, 2); else if (xyzw == 2) SSE2_PSHUFD_XMM_to_XMM(z, i, 2);
else if (xyzw == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3); else if (xyzw == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3);
else if (z != i) SSE_MOVAPS_XMM_to_XMM (z, i); else if (z != i) SSE_MOVAPS_XMM_to_XMM (z, i);
xmmReg[i].count = counter; // Reg i was used, so update counter imap.count = counter; // Reg i was used, so update counter
} }
else { // Don't clone reg, but shuffle to adjust for SS ops else { // Don't clone reg, but shuffle to adjust for SS ops
if ((vfLoadReg != vfWriteReg) || (xyzw != 0xf)) { writeBackReg(z); } if ((vfLoadReg != vfWriteReg) || (xyzw != 0xf)) { writeBackReg(z); }
@ -302,11 +310,11 @@ public:
else if (xyzw == 2) SSE2_PSHUFD_XMM_to_XMM(z, i, 2); else if (xyzw == 2) SSE2_PSHUFD_XMM_to_XMM(z, i, 2);
else if (xyzw == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3); else if (xyzw == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3);
} }
xmmReg[z].reg = vfWriteReg; xmmMap[z].VFreg = vfWriteReg;
xmmReg[z].xyzw = xyzw; xmmMap[z].xyzw = xyzw;
} }
xmmReg[z].count = counter; xmmMap[z].count = counter;
xmmReg[z].isNeeded = 1; xmmMap[z].isNeeded = 1;
return z; return z;
} }
} }
@ -319,18 +327,18 @@ public:
else if (vfLoadReg == 33) mVUloadIreg(x, xyzw, vuRegs); else if (vfLoadReg == 33) mVUloadIreg(x, xyzw, vuRegs);
else if (vfLoadReg == 32) mVUloadReg (x, (uptr)&vuRegs->ACC.UL[0], xyzw); else if (vfLoadReg == 32) mVUloadReg (x, (uptr)&vuRegs->ACC.UL[0], xyzw);
else if (vfLoadReg >= 0) mVUloadReg (x, (uptr)&vuRegs->VF[vfLoadReg].UL[0], xyzw); else if (vfLoadReg >= 0) mVUloadReg (x, (uptr)&vuRegs->VF[vfLoadReg].UL[0], xyzw);
xmmReg[x].reg = vfWriteReg; xmmMap[x].VFreg = vfWriteReg;
xmmReg[x].xyzw = xyzw; xmmMap[x].xyzw = xyzw;
} }
else { // Reg Will Not Be Modified (always load full reg for caching) else { // Reg Will Not Be Modified (always load full reg for caching)
if (vfLoadReg == 33) mVUloadIreg(x, 0xf, vuRegs); if (vfLoadReg == 33) mVUloadIreg(x, 0xf, vuRegs);
else if (vfLoadReg == 32) SSE_MOVAPS_M128_to_XMM(x, (uptr)&vuRegs->ACC.UL[0]); else if (vfLoadReg == 32) SSE_MOVAPS_M128_to_XMM(x, (uptr)&vuRegs->ACC.UL[0]);
else if (vfLoadReg >= 0) SSE_MOVAPS_M128_to_XMM(x, (uptr)&vuRegs->VF[vfLoadReg].UL[0]); else if (vfLoadReg >= 0) SSE_MOVAPS_M128_to_XMM(x, (uptr)&vuRegs->VF[vfLoadReg].UL[0]);
xmmReg[x].reg = vfLoadReg; xmmMap[x].VFreg = vfLoadReg;
xmmReg[x].xyzw = 0; xmmMap[x].xyzw = 0;
} }
xmmReg[x].count = counter; xmmMap[x].count = counter;
xmmReg[x].isNeeded = 1; xmmMap[x].isNeeded = 1;
return x; return x;
} }
}; };