* 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.
public:
explicit ModSibBase( const xAddressInfo& src )
{
Base = src.Base;
Index = src.Index;
Scale = src.Factor;
Displacement= src.Displacement;
explicit ModSibBase( const xAddressInfo& src );
explicit ModSibBase( s32 disp );
ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 );
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 ); }
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 ); }
@ -690,8 +660,8 @@ template< typename T > void xWrite( T val );
public: \
explicit ModSib##bits( const xAddressInfo& src ) : _parent( src ) {} \
explicit ModSib##bits( s32 disp ) : _parent( disp ) {} \
ModSib##bits( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) : \
_parent( base, index, scale, displacement ) {} \
ModSib##bits( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) \
: _parent( base, index, scale, displacement ) {} \
\
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.
//
template< typename xModSibType >
struct xAddressIndexer
class xAddressIndexer
{
public:
// passthrough instruction, allows ModSib to pass silently through ptr translation
// without doing anything and without compiler error.
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...") )
//, m_Timer(this)
{
SetMinWidth( 300 );
//m_sem = sem;
//m_mutex = mutex;
@ -42,7 +44,7 @@ Threading::WaitForTaskDialog::WaitForTaskDialog( const wxString& title, const wx
Connect( pxEvt_ThreadedTaskComplete, wxCommandEventHandler(WaitForTaskDialog::OnTaskComplete) );
*this += 12;
*this += Heading(m_heading) | StdExpand();
*this += Heading(m_heading).Unwrapped() | StdExpand();
*this += 12;
// 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 (),
&vProcessCPUs, &vSystemCPUs) ) return;
int CPUs = 0;
uint CPUs = 0;
DWORD bit;
for (bit = 1; bit != 0; bit <<= 1)

View File

@ -491,8 +491,36 @@ xAddressInfo& xAddressInfo::Add( const xAddressInfo& src )
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.
// 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

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.
wxDialogWithHelpers dialog( NULL, caption );
dialog += dialog.Heading( content );
dialog.SetMinWidth( (content.Length() > 256) ? 525 : 460 );
dialog += dialog.Heading( content ) | StdExpand();
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 mVUloadIreg(int reg, int xyzw, VURegs* vuRegs);
struct microXMM {
int reg; // VF Reg Number Stored (-1 = Temp; 0 = vf0 and will not be written back; 32 = ACC; 33 = I reg)
struct microMapXMM {
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 count; // Count of when last used
bool isNeeded; // Is needed for current instruction
@ -177,27 +177,27 @@ struct microXMM {
#define xmmTotal 7 // Don't allocate PQ?
class microRegAlloc {
private:
microXMM xmmReg[xmmTotal];
VURegs* vuRegs;
int counter;
microMapXMM xmmMap[xmmTotal];
VURegs* vuRegs;
int counter;
int findFreeRegRec(int startIdx) {
for (int i = startIdx; i < xmmTotal; i++) {
if (!xmmReg[i].isNeeded) {
if (!xmmMap[i].isNeeded) {
int x = findFreeRegRec(i+1);
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;
}
int findFreeReg() {
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
}
}
int x = findFreeRegRec(0);
if (x < 0) { DevCon.Error("microVU Allocation Error!"); return 0; }
pxAssumeDev( x >= 0, "microVU register allocation failure!" );
return x;
}
@ -219,34 +219,38 @@ public:
}
}
void clearReg(int reg) {
xmmReg[reg].reg = -1;
xmmReg[reg].count = 0;
xmmReg[reg].xyzw = 0;
xmmReg[reg].isNeeded = 0;
microMapXMM& clear( xmmMap[reg] );
clear.VFreg = -1;
clear.count = 0;
clear.xyzw = 0;
clear.isNeeded = 0;
}
void clearRegVF(int VFreg) {
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) {
if ((xmmReg[reg].reg > 0) && xmmReg[reg].xyzw) { // Reg was modified and not Temp or vf0
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);
else mVUsaveReg(reg, (uptr)&vuRegs->VF[xmmReg[reg].reg].UL[0], xmmReg[reg].xyzw, 1);
microMapXMM& write( xmmMap[reg] );
if ((write.VFreg > 0) && write.xyzw) { // Reg was modified and not Temp or vf0
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) {
for (int i = 0; i < xmmTotal; i++) {
if ((i == reg) || xmmReg[i].isNeeded) continue;
if (xmmReg[i].reg == xmmReg[reg].reg) {
if (xmmReg[i].xyzw && xmmReg[i].xyzw < 0xf) DevCon.Error("microVU Error: writeBackReg() [%d]", xmmReg[i].reg);
microMapXMM& imap (xmmMap[i]);
if ((i == reg) || imap.isNeeded) continue;
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
}
}
}
if (xmmReg[reg].xyzw == 0xf) { // Make Cached Reg if All Vectors were Modified
xmmReg[reg].count = counter;
xmmReg[reg].xyzw = 0;
xmmReg[reg].isNeeded = 0;
if (write.xyzw == 0xf) { // Make Cached Reg if All Vectors were Modified
write.count = counter;
write.xyzw = 0;
write.isNeeded = 0;
return;
}
}
@ -254,19 +258,22 @@ public:
}
void clearNeeded(int reg) {
if ((reg < 0) || (reg >= xmmTotal)) return;
xmmReg[reg].isNeeded = 0;
if (xmmReg[reg].xyzw) { // Reg was modified
if (xmmReg[reg].reg > 0) {
microMapXMM& clear (xmmMap[reg]);
clear.isNeeded = 0;
if (clear.xyzw) { // Reg was modified
if (clear.VFreg > 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
if (i == reg) continue;
if (xmmReg[i].reg == xmmReg[reg].reg) {
if (xmmReg[i].xyzw && xmmReg[i].xyzw < 0xf) DevCon.Error("microVU Error: clearNeeded() [%d]", xmmReg[i].reg);
microMapXMM& imap (xmmMap[i]);
if (imap.VFreg == clear.VFreg) {
if (imap.xyzw && imap.xyzw < 0xf) DevCon.Error("microVU Error: clearNeeded() [%d]", imap.VFreg);
if (mergeRegs == 1) {
mVUmergeRegs(i, reg, xmmReg[reg].xyzw, 1);
xmmReg[i].xyzw = 0xf;
xmmReg[i].count = counter;
mVUmergeRegs(i, reg, clear.xyzw, 1);
imap.xyzw = 0xf;
imap.count = counter;
mergeRegs = 2;
}
else clearReg(i);
@ -282,8 +289,9 @@ public:
counter++;
if (vfLoadReg >= 0) { // Search For Cached Regs
for (int i = 0; i < xmmTotal; i++) {
if ((xmmReg[i].reg == vfLoadReg) && (!xmmReg[i].xyzw // Reg Was Not Modified
|| (xmmReg[i].reg && (xmmReg[i].xyzw==0xf)))) { // Reg Had All Vectors Modified and != VF0
microMapXMM& imap (xmmMap[i]);
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;
if (vfWriteReg >= 0) { // Reg will be modified
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 == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3);
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
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 == 1) SSE2_PSHUFD_XMM_to_XMM(z, i, 3);
}
xmmReg[z].reg = vfWriteReg;
xmmReg[z].xyzw = xyzw;
xmmMap[z].VFreg = vfWriteReg;
xmmMap[z].xyzw = xyzw;
}
xmmReg[z].count = counter;
xmmReg[z].isNeeded = 1;
xmmMap[z].count = counter;
xmmMap[z].isNeeded = 1;
return z;
}
}
@ -319,18 +327,18 @@ public:
else if (vfLoadReg == 33) mVUloadIreg(x, xyzw, vuRegs);
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);
xmmReg[x].reg = vfWriteReg;
xmmReg[x].xyzw = xyzw;
xmmMap[x].VFreg = vfWriteReg;
xmmMap[x].xyzw = xyzw;
}
else { // Reg Will Not Be Modified (always load full reg for caching)
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 >= 0) SSE_MOVAPS_M128_to_XMM(x, (uptr)&vuRegs->VF[vfLoadReg].UL[0]);
xmmReg[x].reg = vfLoadReg;
xmmReg[x].xyzw = 0;
xmmMap[x].VFreg = vfLoadReg;
xmmMap[x].xyzw = 0;
}
xmmReg[x].count = counter;
xmmReg[x].isNeeded = 1;
xmmMap[x].count = counter;
xmmMap[x].isNeeded = 1;
return x;
}
};