mirror of https://github.com/PCSX2/pcsx2.git
Implemented a new optimized version of recPLZCW, though it probably doesn't make much actual difference to performance (but it was fun! :)
Applied a small patch from Pseudonym that repairs the Debugger (sorta). git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@679 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
parent
6ec4518d35
commit
f8b274ddfe
|
@ -610,18 +610,14 @@ void disR5900Fasm(string& output, u32 code, u32 pc)
|
|||
{
|
||||
string dbuf;
|
||||
char obuf[48];
|
||||
const R5900::OPCODE *op;
|
||||
|
||||
const u32 scode = cpuRegs.code;
|
||||
opcode_addr = pc;
|
||||
cpuRegs.code = code;
|
||||
op = &R5900::OpcodeTables::tbl_Standard[(code) >> 26];
|
||||
while (op->getsubclass)
|
||||
op = &op->getsubclass();
|
||||
|
||||
sprintf(obuf, "%08X:\t", pc );
|
||||
output.assign( obuf );
|
||||
op->disasm( output );
|
||||
GetCurrentInstruction().disasm( output );
|
||||
|
||||
cpuRegs.code = scode;
|
||||
}
|
||||
|
@ -727,8 +723,8 @@ void ANDI( string& output ) { _sap("andi\t%s, %s, 0x%04X") GPR_REG[DECODE_RT
|
|||
void ORI( string& output ) { _sap("ori\t%s, %s, 0x%04X") GPR_REG[DECODE_RT], GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||
void XORI( string& output ) { _sap("xori\t%s, %s, 0x%04X") GPR_REG[DECODE_RT], GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||
void LUI( string& output ) { _sap("lui\t%s, 0x%04X") GPR_REG[DECODE_RT], DECODE_IMMED); }
|
||||
void BEQL( string& output ) { _sap("beql\t%s, %s, %s") GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); offset_decode(output); }
|
||||
void BNEL( string& output ) { _sap("bnel\t%s, %s, %s") GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); offset_decode(output); }
|
||||
void BEQL( string& output ) { _sap("beql\t%s, %s, ") GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); offset_decode(output); }
|
||||
void BNEL( string& output ) { _sap("bnel\t%s, %s, ") GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); offset_decode(output); }
|
||||
void BLEZL( string& output ) { _sap("blezl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
||||
void BGTZL( string& output ) { _sap("bgtzl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
||||
void DADDI( string& output ) { _sap("daddi\t%s, %s, 0x%04X") GPR_REG[DECODE_RT], GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||
|
@ -1193,4 +1189,4 @@ void P_VRINIT( string& output ){_sap("vrinit R, %s%s") COP2_REG_CTL[DECODE_FS],
|
|||
void P_VRXOR( string& output ){_sap("vrxor R, %s%s") COP2_REG_CTL[DECODE_FS], dest_string());}
|
||||
//************************************END OF SPECIAL2 VUO TABLE****************************
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,17 +132,21 @@ namespace MMI {
|
|||
|
||||
__forceinline void _PLZCW(int n)
|
||||
{
|
||||
int i;
|
||||
u32 sign;
|
||||
|
||||
sign = cpuRegs.GPR.r[_Rs_].UL[n] >> 31;
|
||||
|
||||
for (i=30; i>=0; i--) {
|
||||
if (((cpuRegs.GPR.r[_Rs_].UL[n] >> i) & 0x1) != sign)
|
||||
break;
|
||||
}
|
||||
|
||||
cpuRegs.GPR.r[_Rd_].UL[n] = 30 - i;
|
||||
// This function counts the number of "like" bits in the source register, starting
|
||||
// with the MSB and working its way down, and returns the result MINUS ONE.
|
||||
// So 0xff00 would return 7, not 8.
|
||||
|
||||
int c = 0;
|
||||
s32 i = cpuRegs.GPR.r[_Rs_].SL[n];
|
||||
|
||||
// Negate the source based on the sign bit. This allows us to use a simple
|
||||
// unified bit test of the MSB for either condition.
|
||||
if( i >= 0 ) i = ~i;
|
||||
|
||||
// shift first, compare, then increment. This excludes the sign bit from our final count.
|
||||
while( i <<= 1, i < 0 ) c++;
|
||||
|
||||
cpuRegs.GPR.r[_Rd_].UL[n] = c;
|
||||
}
|
||||
|
||||
void PLZCW() {
|
||||
|
|
|
@ -117,7 +117,7 @@ extern void EEDumpRegs(FILE * fp);
|
|||
extern void IOPDumpRegs(FILE * fp);
|
||||
BOOL APIENTRY DumpProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
char start[16], end[16], fname[128], tmp[128], buf[128];
|
||||
char start[16], end[16], fname[128], tmp[128];
|
||||
unsigned long start_pc, end_pc, temp;
|
||||
|
||||
FILE *fp;
|
||||
|
@ -125,14 +125,14 @@ BOOL APIENTRY DumpProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
sprintf(buf, "%08X", cpuRegs.pc);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_START, buf);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_END, buf);
|
||||
sprintf(tmp, "%08X", cpuRegs.pc);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_START, tmp);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_END, tmp);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_FNAME, "EEdisasm.txt");
|
||||
|
||||
sprintf(buf, "%08X", psxRegs.pc);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_STARTIOP, buf);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_ENDIOP, buf);
|
||||
sprintf(tmp, "%08X", psxRegs.pc);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_STARTIOP, tmp);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_ENDIOP, tmp);
|
||||
SetDlgItemText(hDlg, IDC_DUMP_FNAMEIOP, "IOPdisasm.txt");
|
||||
return TRUE;
|
||||
|
||||
|
@ -168,13 +168,9 @@ BOOL APIENTRY DumpProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
MakeDebugOpcode();
|
||||
|
||||
output.assign( HasBreakpoint() ? "*" : "" );
|
||||
sprintf(buf, "%08X %08X: %s", temp, cpuRegs.code, tmp);
|
||||
output.append( buf );
|
||||
R5900::GetCurrentInstruction().disasm( output );
|
||||
|
||||
R5900::OpcodeTables::tbl_Standard[_Opcode_].disasm( output );
|
||||
|
||||
|
||||
fprintf(fp, "%s\n", buf);
|
||||
fprintf(fp, "%08X %08X: %s\n", temp, cpuRegs.code, output.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,8 +209,7 @@ BOOL APIENTRY DumpProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
opcode_addr=temp;
|
||||
MakeIOPDebugOpcode();
|
||||
R3000A::IOP_DEBUG_BSC[(psxRegs.code) >> 26](tmp);
|
||||
sprintf(buf, "%08X %08X: %s", temp, psxRegs.code, tmp);
|
||||
fprintf(fp, "%s\n", buf);
|
||||
fprintf(fp, "%08X %08X: %s\n", temp, psxRegs.code, tmp);
|
||||
}
|
||||
|
||||
fprintf(fp,"\n\n\n----------------------------------\n");
|
||||
|
|
|
@ -110,35 +110,28 @@ void recPLZCW()
|
|||
_deleteEEreg(_Rd_, 0);
|
||||
}
|
||||
|
||||
// first word
|
||||
// Count the number of leading bits (MSB) that match the sign bit, excluding the sign
|
||||
// bit itself.
|
||||
|
||||
TEST32ItoR(EAX, 0x80000000);
|
||||
j8Ptr[0] = JZ8(0);
|
||||
// Strategy: If the sign bit is set, then negate the value. And that way the same
|
||||
// bitcompare can be used for either bit status. but be warned! BSR returns undefined
|
||||
// results if the EAX is zero, so we need to have special checks for zeros before
|
||||
// using it.
|
||||
|
||||
// --- first word ---
|
||||
|
||||
MOV32ItoR(ECX,31);
|
||||
TEST32RtoR(EAX, EAX); // TEST sets the sign flag accordingly.
|
||||
u8* label_notSigned = JNS8(0);
|
||||
NOT32R(EAX);
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
x86SetJ8(label_notSigned);
|
||||
|
||||
|
||||
TEST32RtoR(EAX, EAX);
|
||||
j8Ptr[0] = JNZ8(0);
|
||||
|
||||
// zero, so put 31
|
||||
if( EEINST_ISLIVE1(_Rd_) || regd < 0 ) {
|
||||
MOV32ItoM((uptr)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], 31);
|
||||
}
|
||||
else {
|
||||
SetMMXstate();
|
||||
PCMPEQDRtoR(regd, regd);
|
||||
PSRLQItoR(regd, 59);
|
||||
}
|
||||
|
||||
j8Ptr[1] = JMP8(0);
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
|
||||
// not zero
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
BSRRtoR(EAX, EAX);
|
||||
MOV32ItoR(ECX, 30);
|
||||
u8* label_Zeroed = JZ8(0); // If BSR sets the ZF, eax is "trash"
|
||||
SUB32RtoR(ECX, EAX);
|
||||
DEC32R(ECX); // PS2 doesn't count the first bit
|
||||
|
||||
x86SetJ8(label_Zeroed);
|
||||
if( EEINST_ISLIVE1(_Rd_) || regd < 0 ) {
|
||||
MOV32RtoM((uptr)&cpuRegs.GPR.r[ _Rd_ ].UL[ 0 ], ECX);
|
||||
}
|
||||
|
@ -147,9 +140,8 @@ void recPLZCW()
|
|||
MOVD32RtoMMX(regd, ECX);
|
||||
}
|
||||
|
||||
x86SetJ8(j8Ptr[1]);
|
||||
|
||||
// second word
|
||||
|
||||
if( EEINST_ISLIVE1(_Rd_) ) {
|
||||
if( regs >= 0 && (regs & MEM_XMMTAG) ) {
|
||||
SSE2_PSHUFD_XMM_to_XMM(regs&0xf, regs&0xf, 0x4e);
|
||||
|
@ -164,26 +156,19 @@ void recPLZCW()
|
|||
}
|
||||
else MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[ _Rs_ ].UL[ 1 ]);
|
||||
|
||||
TEST32ItoR(EAX, 0x80000000);
|
||||
j8Ptr[0] = JZ8(0);
|
||||
MOV32ItoR(ECX, 31);
|
||||
TEST32RtoR(EAX, EAX); // TEST sets the sign flag accordingly.
|
||||
label_notSigned = JNS8(0);
|
||||
NOT32R(EAX);
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
x86SetJ8(label_notSigned);
|
||||
|
||||
TEST32RtoR(EAX, EAX);
|
||||
j8Ptr[0] = JNZ8(0);
|
||||
|
||||
// zero, so put 31
|
||||
MOV32ItoM((uptr)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], 31);
|
||||
j8Ptr[1] = JMP8(0);
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
|
||||
// not zero
|
||||
x86SetJ8(j8Ptr[0]);
|
||||
BSRRtoR(EAX, EAX);
|
||||
MOV32ItoR(ECX, 30);
|
||||
u8* label_Zeroed = JZ8(0); // If BSR sets the ZF, eax is "trash"
|
||||
SUB32RtoR(ECX, EAX);
|
||||
MOV32RtoM((uptr)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], ECX);
|
||||
x86SetJ8(j8Ptr[1]);
|
||||
DEC32R(ECX); // PS2 doesn't count the first bit
|
||||
|
||||
x86SetJ8(label_Zeroed);
|
||||
MOV32ItoM((uptr)&cpuRegs.GPR.r[ _Rd_ ].UL[ 1 ], ECX);
|
||||
}
|
||||
else {
|
||||
EEINST_RESETHASLIVE1(_Rd_);
|
||||
|
@ -265,7 +250,7 @@ CPU_SSE2_XMMCACHE_START(XMMINFO_WRITED|XMMINFO_READLO|XMMINFO_READHI)
|
|||
|
||||
CPU_SSE_XMMCACHE_END
|
||||
|
||||
recCall( Interp::PMFHL, _Rd_ );
|
||||
recCall( Interp::PMFHL, _Rd_ );
|
||||
}
|
||||
|
||||
void recPMTHL()
|
||||
|
|
Loading…
Reference in New Issue