mirror of https://github.com/PCSX2/pcsx2.git
* 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:
parent
b7c9aa63cd
commit
df3bda9183
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue