pcsx2-wxgui: maintenence merging of trunk revisions into the brance (always a good idea to update branches after header file renames)

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@764 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-03-13 06:14:08 +00:00
parent b8b36445cb
commit 915fe28c23
84 changed files with 1630 additions and 1883 deletions

View File

@ -14,9 +14,6 @@ export PCSX2OPTIONS="--enable-sse3 --enable-sse4 --enable-devbuild --prefix `pwd
#Debug / Devbuild version #Debug / Devbuild version
#export PCSX2OPTIONS="--enable-debug --enable-devbuild --enable-sse3 --prefix `pwd`" #export PCSX2OPTIONS="--enable-debug --enable-devbuild --enable-sse3 --prefix `pwd`"
#Optimized, but a devbuild - with memcpy_fast_ enabled. - BROKEN!
#export PCSX2OPTIONS="--enable-sse3 --enable-sse4 --enable-devbuild --enable-memcpyfast --prefix `pwd`"
#ZeroGS Normal mode #ZeroGS Normal mode
export ZEROGSOPTIONS="--enable-sse2" export ZEROGSOPTIONS="--enable-sse2"

View File

@ -13,12 +13,10 @@ STRIP = strip
OPTIMIZE = -O2 -fomit-frame-pointer -finline-functions -ffast-math OPTIMIZE = -O2 -fomit-frame-pointer -finline-functions -ffast-math
CFLAGS = -Wall ${OPTIMIZE} -I. CFLAGS = -Wall ${OPTIMIZE} -I.
DIRS = kernel intro loader DIRS = kernel intro loader
FILES = RESET ROMDIR EXTINFO ROMVER IOPBOOT EELOAD \ FILES = RESET ROMDIR ROMVER IOPBOOT EELOAD \
SYSMEM LOADCORE EXCEPMAN INTRMAN SSBUSC DMACMAN \ SYSMEM LOADCORE EXCEPMAN INTRMAN SSBUSC DMACMAN \
TIMRMAN SYSCLIB HEAPLIB THREADMAN VBLANK STDIO \ TIMRMAN SYSCLIB HEAPLIB THREADMAN VBLANK STDIO \
SIFMAN SIFCMD SIO2MAN LOADER INTRO IOPBTCONF FP2BLOGO \ SIFMAN SIFCMD SIO2MAN LOADER INTRO IOPBTCONF FP2BLOGO
IOMAN MODLOAD ROMDRV IGREETING REBOOT LOADFILE CDVDMAN \
CDVDFSV SIFINIT FILEIO SECRMAN EESYNC
ps2romgen_exe: ps2romgen.o ps2romgen_exe: ps2romgen.o
${CC} ${CFLAGS} ps2romgen.o -o build/ps2romgen_exe ${CC} ${CFLAGS} ps2romgen.o -o build/ps2romgen_exe
@ -33,7 +31,6 @@ fps2bios:
for i in $(DIRS); do \ for i in $(DIRS); do \
(cd $$i; make; cd ..) \ (cd $$i; make; cd ..) \
done; done;
cp -f used/* build
cp -f FP2BLOGO build cp -f FP2BLOGO build
cp -f IOPBTCONF build/ cp -f IOPBTCONF build/
(cd build; \ (cd build; \

View File

@ -43,6 +43,7 @@ int main(int argc, char *argv[]) {
} }
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
memset(&rd, 0, sizeof(rd));
if (strcmp(argv[i], "ROMDIR") == 0) { if (strcmp(argv[i], "ROMDIR") == 0) {
strncpy(rd.fileName, argv[i], 9); strncpy(rd.fileName, argv[i], 9);
rd.extInfoSize = 0; rd.extInfoSize = 0;
@ -55,7 +56,7 @@ int main(int argc, char *argv[]) {
continue; continue;
} }
for (j=0; j<9; j++) { for (j=0; j<9; j++) {
if (argv[i][j] == ',') break; if (argv[i][j] == ',' || argv[i][j] == 0) break;
rd.fileName[j] = argv[i][j]; rd.fileName[j] = argv[i][j];
} }
memset(rd.fileName+j, 0, 10-j); memset(rd.fileName+j, 0, 10-j);

View File

@ -20,7 +20,7 @@
#include <ctype.h> #include <ctype.h>
#include "PsxCommon.h" #include "IopCommon.h"
#include "CDVDiso.h" #include "CDVDiso.h"
static cdvdStruct cdvd; static cdvdStruct cdvd;
@ -462,7 +462,7 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
// get main elf name // get main elf name
GetPS2ElfName(str); GetPS2ElfName(str);
sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]); sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]);
DevCon::Notice("exeName = %s", params &str[8]); DevCon::Notice("exeName = %s", params &str[8]);
// convert the number characters to a real 32bit number // convert the number characters to a real 32bit number

View File

@ -19,7 +19,7 @@
#ifndef __CDVD_H__ #ifndef __CDVD_H__
#define __CDVD_H__ #define __CDVD_H__
#include "PsxCommon.h" #include "IopCommon.h"
struct cdvdRTC { struct cdvdRTC {
u8 status; u8 status;

View File

@ -144,79 +144,259 @@ void WriteTLB(int i)
MapTLB(i); MapTLB(i);
} }
//////////////////////////////////////////////////////////////////////////////////////////
// Performance Counters Update Stuff!
//
// Note regarding updates of PERF and TIMR registers: never allow increment to be 0.
// That happens when a game loads the MFC0 twice in the same recompiled block (before the
// cpuRegs.cycles update), and can cause games to lock up since it's an unexpected result.
//
// PERF Overflow exceptions: The exception is raised when the MSB of the Performance
// Counter Register is set. I'm assuming the exception continues to re-raise until the
// app clears the bit manually (needs testing).
//
// PERF Events:
// * Event 0 on PCR 0 is unused (counter disable)
// * Event 16 is usable as a specific counter disable bit (since CTE affects both counters)
// * Events 17-31 are reserved (act as counter disable)
//
// Most event mode aren't supported, and issue a warning and do a standard instruction
// count. But only mode 1 (instruction counter) has been found to be used by games thus far.
//
static __forceinline bool PERF_ShouldCountEvent( uint evt )
{
switch( evt )
{
// This is a rough table of actions for various PCR modes. Some of these
// can be implemented more accurately later. Others (WBBs in particular)
// probably cannot without some severe complications.
// left sides are PCR0 / right sides are PCR1
case 1: // cpu cycle counter.
case 2: // single/dual instruction issued
case 3: // Branch issued / Branch mispredicated
return true;
case 4: // BTAC/TLB miss
case 5: // ITLB/DTLB miss
case 6: // Data/Instruction cache miss
return false;
case 7: // Access to DTLB / WBB single request fail
case 8: // Non-blocking load / WBB burst request fail
case 9:
case 10:
return false;
case 11: // CPU address bus busy / CPU data bus busy
return false;
case 12: // Instruction completed
case 13: // non-delayslot instruction completed
case 14: // COP2/COP1 instruction complete
case 15: // Load/Store completed
return true;
}
return false;
}
// Diagnostics for event modes that we just ignore for now. Using these perf units could
// cause compat issues in some very odd/rare games, so if this msg comes up who knows,
// might save some debugging effort. :)
void COP0_DiagnosticPCCR()
{
if( cpuRegs.PERF.n.pccr.b.Event0 >= 7 && cpuRegs.PERF.n.pccr.b.Event0 <= 10 )
Console::Notice( "PERF/PCR0 Unsupported Update Event Mode = 0x%x", params cpuRegs.PERF.n.pccr.b.Event0 );
if( cpuRegs.PERF.n.pccr.b.Event1 >= 7 && cpuRegs.PERF.n.pccr.b.Event1 <= 10 )
Console::Notice( "PERF/PCR1 Unsupported Update Event Mode = 0x%x", params cpuRegs.PERF.n.pccr.b.Event1 );
}
__forceinline void COP0_UpdatePCCR()
{
if( cpuRegs.CP0.n.Status.b.ERL || !cpuRegs.PERF.n.pccr.b.CTE ) return;
// TODO : Implement memory mode checks here (kernel/super/user)
// For now we just assume user mode.
if( cpuRegs.PERF.n.pccr.b.U0 )
{
// ----------------------------------
// Update Performance Counter 0
// ----------------------------------
if( PERF_ShouldCountEvent( cpuRegs.PERF.n.pccr.b.Event0 ) )
{
u32 incr = cpuRegs.cycle - s_iLastPERFCycle[0];
if( incr == 0 ) incr++;
// use prev/XOR method for one-time exceptions (but likely less correct)
//u32 prev = cpuRegs.PERF.n.pcr0;
cpuRegs.PERF.n.pcr0 += incr;
s_iLastPERFCycle[0] = cpuRegs.cycle;
//prev ^= (1UL<<31); // XOR is fun!
//if( (prev & cpuRegs.PERF.n.pcr0) & (1UL<<31) )
if( cpuRegs.PERF.n.pcr0 & 0x80000000 )
{
// TODO: Vector to the appropriate exception here.
// This code *should* be correct, but is untested (and other parts of the emu are
// not prepared to handle proper Level 2 exception vectors yet)
/*if( delay_slot )
{
cpuRegs.CP0.ErrorEPC = cpuRegs.pc - 4;
cpuRegs.CP0.Cause.BD2 = 1;
}
else
{
cpuRegs.CP0.ErrorEPC = cpuRegs.pc;
cpuRegs.CP0.Cause.BD2 = 0;
}
if( cpuRegs.CP0.Status.DEV )
{
// Bootstrap vector
cpuRegs.pc = 0xbfc00280;
}
else
{
cpuRegs.pc = 0x80000080;
}
cpuRegs.CP0.Status.ERL = 1;
cpuRegs.CP0.Cause.EXC2 = 2;*/
}
}
}
if( cpuRegs.PERF.n.pccr.b.U1 )
{
// ----------------------------------
// Update Performance Counter 1
// ----------------------------------
if( PERF_ShouldCountEvent( cpuRegs.PERF.n.pccr.b.Event1 ) )
{
u32 incr = cpuRegs.cycle - s_iLastPERFCycle[1];
if( incr == 0 ) incr++;
cpuRegs.PERF.n.pcr1 += incr;
s_iLastPERFCycle[1] = cpuRegs.cycle;
if( cpuRegs.PERF.n.pcr1 & 0x80000000 )
{
// See PCR0 comments for notes on exceptions
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
namespace R5900 { namespace R5900 {
namespace Interpreter { namespace Interpreter {
namespace OpcodeImpl { namespace OpcodeImpl {
namespace COP0 { namespace COP0 {
void MFC0() { void MFC0()
if (!_Rt_) return; {
if (_Rd_ != 9) { COP0_LOG("%s\n", disR5900Current.getCString() ); } // Note on _Rd_ Condition 9: CP0.Count should be updated even if _Rt_ is 0.
if( (_Rd_ != 9) && !_Rt_ ) return;
if(_Rd_ != 9) { COP0_LOG("%s\n", disR5900Current.getCString() ); }
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MFC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]); //if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MFC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) { switch (_Rd_)
{
case 12: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)(cpuRegs.CP0.r[_Rd_] & 0xf0c79c1f); break; case 12:
cpuRegs.GPR.r[_Rt_].SD[0] = (s32)(cpuRegs.CP0.r[_Rd_] & 0xf0c79c1f);
break;
case 25: case 25:
switch(_Imm_ & 0x3F){ switch(_Imm_ & 0x3F)
case 0: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pccr; break; {
case 1: case 0: // MFPS [LSB is clear]
if((cpuRegs.PERF.n.pccr & 0x800003E0) == 0x80000020) { cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pccr.val;
cpuRegs.PERF.n.pcr0 += cpuRegs.cycle-s_iLastPERFCycle[0]; break;
s_iLastPERFCycle[0] = cpuRegs.cycle;
} case 1: // MFPC [LSB is set] - read PCR0
COP0_UpdatePCCR();
cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pcr0; cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr0;
break; break;
case 3:
if((cpuRegs.PERF.n.pccr & 0x800F8000) == 0x80008000) { case 3: // MFPC [LSB is set] - read PCR1
cpuRegs.PERF.n.pcr1 += cpuRegs.cycle-s_iLastPERFCycle[1]; COP0_UpdatePCCR();
s_iLastPERFCycle[1] = cpuRegs.cycle; cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr1;
} break;
cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pcr1;
break;
} }
/*SysPrintf("MFC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n", /*SysPrintf("MFC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n",
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/ cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/
break; break;
case 24: case 24:
SysPrintf("MFC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); Console::WriteLn("MFC0 Breakpoint debug Registers code = %x", params cpuRegs.code & 0x3FF);
break; break;
case 9: case 9:
// update {
cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle; u32 incr = cpuRegs.cycle-s_iLastCOP0Cycle;
if( incr == 0 ) incr++;
cpuRegs.CP0.n.Count += incr;
s_iLastCOP0Cycle = cpuRegs.cycle; s_iLastCOP0Cycle = cpuRegs.cycle;
default: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.CP0.r[_Rd_]; if( !_Rt_ ) break;
}
default:
cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.CP0.r[_Rd_];
} }
} }
void MTC0() { void MTC0()
{
COP0_LOG("%s\n", disR5900Current.getCString()); COP0_LOG("%s\n", disR5900Current.getCString());
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]); //if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) { switch (_Rd_)
{
case 25: case 25:
/*if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n", /*if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n",
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/ cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);*/
switch(_Imm_ & 0x3F){ switch(_Imm_ & 0x3F)
case 0: {
if((cpuRegs.PERF.n.pccr & 0x800003E0) == 0x80000020) case 0: // MTPS [LSB is clear]
cpuRegs.PERF.n.pcr0 += cpuRegs.cycle-s_iLastPERFCycle[0]; // Updates PCRs and sets the PCCR.
if((cpuRegs.PERF.n.pccr & 0x800F8000) == 0x80008000) COP0_UpdatePCCR();
cpuRegs.PERF.n.pcr1 += cpuRegs.cycle-s_iLastPERFCycle[1]; cpuRegs.PERF.n.pccr.val = cpuRegs.GPR.r[_Rt_].UL[0];
cpuRegs.PERF.n.pccr = cpuRegs.GPR.r[_Rt_].UL[0]; COP0_DiagnosticPCCR();
break;
case 1: // MTPC [LSB is set] - set PCR0
cpuRegs.PERF.n.pcr0 = cpuRegs.GPR.r[_Rt_].UL[0];
s_iLastPERFCycle[0] = cpuRegs.cycle; s_iLastPERFCycle[0] = cpuRegs.cycle;
break;
case 3: // MTPC [LSB is set] - set PCR0
cpuRegs.PERF.n.pcr1 = cpuRegs.GPR.r[_Rt_].UL[0];
s_iLastPERFCycle[1] = cpuRegs.cycle; s_iLastPERFCycle[1] = cpuRegs.cycle;
break; break;
case 1: cpuRegs.PERF.n.pcr0 = cpuRegs.GPR.r[_Rt_].UL[0]; s_iLastPERFCycle[0] = cpuRegs.cycle; break;
case 3: cpuRegs.PERF.n.pcr1 = cpuRegs.GPR.r[_Rt_].UL[0]; s_iLastPERFCycle[1] = cpuRegs.cycle; break;
} }
break; break;
case 24: case 24:
SysPrintf("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); Console::WriteLn("MTC0 Breakpoint debug Registers code = %x", params cpuRegs.code & 0x3FF);
break; break;
case 12: WriteCP0Status(cpuRegs.GPR.r[_Rt_].UL[0]); break; case 12: WriteCP0Status(cpuRegs.GPR.r[_Rt_].UL[0]); break;
case 9: s_iLastCOP0Cycle = cpuRegs.cycle; cpuRegs.CP0.r[9] = cpuRegs.GPR.r[_Rt_].UL[0]; break; case 9:
default: cpuRegs.CP0.r[_Rd_] = cpuRegs.GPR.r[_Rt_].UL[0]; break; s_iLastCOP0Cycle = cpuRegs.cycle;
cpuRegs.CP0.r[9] = cpuRegs.GPR.r[_Rt_].UL[0];
break;
default:
cpuRegs.CP0.r[_Rd_] = cpuRegs.GPR.r[_Rt_].UL[0];
break;
} }
} }
@ -233,12 +413,10 @@ int CPCOND0() {
void BC0F() { void BC0F() {
BC0(== 0); BC0(== 0);
COP0_LOG( "COP0 > BC0F\n" );
} }
void BC0T() { void BC0T() {
BC0(== 1); BC0(== 1);
COP0_LOG( "COP0 > BC0T\n" );
} }
#define BC0L(cond) \ #define BC0L(cond) \
@ -248,12 +426,10 @@ void BC0T() {
void BC0FL() { void BC0FL() {
BC0L(== 0); BC0L(== 0);
COP0_LOG( "COP0 > BC0FL\n" );
} }
void BC0TL() { void BC0TL() {
BC0L(== 1); BC0L(== 1);
COP0_LOG( "COP0 > BCOTL\n" );
} }
void TLBR() { void TLBR() {
@ -263,7 +439,6 @@ void TLBR() {
int i = cpuRegs.CP0.n.Index&0x1f; int i = cpuRegs.CP0.n.Index&0x1f;
COP0_LOG("COP0 > TLBR\n");
cpuRegs.CP0.n.PageMask = tlb[i].PageMask; cpuRegs.CP0.n.PageMask = tlb[i].PageMask;
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00); cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00);
cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1); cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1);

View File

@ -19,10 +19,14 @@
#ifndef __COP0_H__ #ifndef __COP0_H__
#define __COP0_H__ #define __COP0_H__
void WriteCP0Status(u32 value); extern void WriteCP0Status(u32 value);
void UpdateCP0Status(); extern void UpdateCP0Status();
void WriteTLB(int i); extern void WriteTLB(int i);
void UnmapTLB(int i); extern void UnmapTLB(int i);
void MapTLB(int i); extern void MapTLB(int i);
extern void COP0_UpdatePCCR();
extern void COP0_DiagnosticPCCR();
#endif /* __COP0_H__ */ #endif /* __COP0_H__ */

View File

@ -18,8 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "Common.h"
//THIS ALL IS FOR THE CDROM REGISTERS HANDLING //THIS ALL IS FOR THE CDROM REGISTERS HANDLING
@ -73,7 +72,6 @@ const char *CmdName[0x100]= {
cdrStruct cdr; cdrStruct cdr;
long LoadCdBios; long LoadCdBios;
int cdOpenCase;
u8 Test04[] = { 0 }; u8 Test04[] = { 0 };
u8 Test05[] = { 0 }; u8 Test05[] = { 0 };

View File

@ -19,7 +19,7 @@
#ifndef __CDROM_H__ #ifndef __CDROM_H__
#define __CDROM_H__ #define __CDROM_H__
#include "PsxCommon.h" #include "IopCommon.h"
#include "Decode_XA.h" #include "Decode_XA.h"
#include "PS2Edefs.h" #include "PS2Edefs.h"

View File

@ -27,20 +27,20 @@
//#define PSXCLK 186864000 /* 36.864 Mhz */ //#define PSXCLK 186864000 /* 36.864 Mhz */
#define PS2CLK 294912000 //hz /* 294.912 mhz */ #define PS2CLK 294912000 //hz /* 294.912 mhz */
#define PCSX2_VERSION "(beta)"
#include "Plugins.h" #include "Plugins.h"
#include "Misc.h"
#include "SaveState.h" #include "SaveState.h"
#include "DebugTools/Debug.h" #include "DebugTools/Debug.h"
#include "R5900.h"
#include "Memory.h" #include "Memory.h"
#include "Elfheader.h"
#include "Hw.h" #include "Hw.h"
// Moving this before one of the other includes causes compilation issues.
//#include "Misc.h" #include "R5900.h"
#include "Elfheader.h"
#include "Patch.h" #include "Patch.h"
#define PCSX2_VERSION "(beta)" #include "System.h"
#include "Pcsx2Config.h"
#endif /* __COMMON_H__ */ #endif /* __COMMON_H__ */

View File

@ -20,7 +20,7 @@
#ifndef __DEBUG_H__ #ifndef __DEBUG_H__
#define __DEBUG_H__ #define __DEBUG_H__
#include "Misc.h" #include "Pcsx2Config.h"
extern FILE *emuLog; extern FILE *emuLog;
@ -73,15 +73,47 @@ namespace R3000A
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
extern u32 varLog; struct LogSources
{
bool
R5900:1, // instructions and exception vectors for the R5900 (EE)
R3000A:1, // instructions and exception vectors for the R3000a (IOP)
Memory:1, // memory accesses (loads and stores)
Hardware:1,
DMA:1,
Bios:1,
ELF:1,
VU0:1,
COP0:1, // TLB logs, PERF logs, Debug register logs
VIF:1,
SPR:1, // Scratchpad
GIF:1,
SIF:1,
IPU:1,
VUM:1, // VU memory access logs
RPC:1,
Counters:1, // EE's counters!
IopMemory:1,
IopHardware:1,
IopBios:1,
IopDMA:1,
IopCnt:1,
Memcards:1,
Pad:1,
CDVD:1,
GPU:1, // PS1's GPU (currently unimplemented)
LogToConsole:1;
};
extern LogSources varLog;
void SourceLog( u16 protocol, u8 source, u32 cpuPc, u32 cpuCycle, const char *fmt, ...); void SourceLog( u16 protocol, u8 source, u32 cpuPc, u32 cpuCycle, const char *fmt, ...);
void __Log( const char* fmt, ... ); void __Log( const char* fmt, ... );
extern bool SrcLog_CPU( const char* fmt, ... ); extern bool SrcLog_CPU( const char* fmt, ... );
extern bool SrcLog_COP0( const char* fmt, ... ); extern bool SrcLog_COP0( const char* fmt, ... );
extern bool SrcLog_FPU( const char* fmt, ... );
extern bool SrcLog_MMI( const char* fmt, ... );
extern bool SrcLog_MEM( const char* fmt, ... ); extern bool SrcLog_MEM( const char* fmt, ... );
extern bool SrcLog_HW( const char* fmt, ... ); extern bool SrcLog_HW( const char* fmt, ... );
@ -108,42 +140,38 @@ extern bool SrcLog_PSXCNT( const char* fmt, ... );
extern bool SrcLog_MEMCARDS( const char* fmt, ... ); extern bool SrcLog_MEMCARDS( const char* fmt, ... );
extern bool SrcLog_PAD( const char* fmt, ... ); extern bool SrcLog_PAD( const char* fmt, ... );
extern bool SrcLog_GTE( const char* fmt, ... );
extern bool SrcLog_CDR( const char* fmt, ... ); extern bool SrcLog_CDR( const char* fmt, ... );
extern bool SrcLog_GPU( const char* fmt, ... ); extern bool SrcLog_GPU( const char* fmt, ... );
#define CPU_LOG (varLog & 0x00000001) && SrcLog_CPU #define CPU_LOG (varLog.R5900) && SrcLog_CPU
#define MEM_LOG (varLog & 0x00000002) && SrcLog_MEM #define MEM_LOG (varLog.Memory) && SrcLog_MEM
#define HW_LOG (varLog & 0x00000004) && SrcLog_HW #define HW_LOG (varLog.Hardware) && SrcLog_HW
#define DMA_LOG (varLog & 0x00000008) && SrcLog_DMA #define DMA_LOG (varLog.DMA) && SrcLog_DMA
#define BIOS_LOG (varLog & 0x00000010) && SrcLog_BIOS #define BIOS_LOG (varLog.Bios) && SrcLog_BIOS
#define ELF_LOG (varLog & 0x00000020) && SrcLog_ELF #define ELF_LOG (varLog.ELF) && SrcLog_ELF
#define FPU_LOG (varLog & 0x00000040) && SrcLog_FPU #define VU0_LOG (varLog.VU0) && SrcLog_VU0
#define MMI_LOG (varLog & 0x00000080) && SrcLog_MMI #define COP0_LOG (varLog.COP0) && SrcLog_COP0
#define VU0_LOG (varLog & 0x00000100) && SrcLog_VU0 #define VIF_LOG (varLog.VIF) && SrcLog_VIF
#define COP0_LOG (varLog & 0x00000200) && SrcLog_COP0 #define SPR_LOG (varLog.SPR) && SrcLog_SPR
#define VIF_LOG (varLog & 0x00000400) && SrcLog_VIF #define GIF_LOG (varLog.GIF) && SrcLog_GIF
#define SPR_LOG (varLog & 0x00000800) && SrcLog_SPR #define SIF_LOG (varLog.SIF) && SrcLog_SIF
#define GIF_LOG (varLog & 0x00001000) && SrcLog_GIF #define IPU_LOG (varLog.IPU) && SrcLog_IPU
#define SIF_LOG (varLog & 0x00002000) && SrcLog_SIF #define VUM_LOG (varLog.VUM) && SrcLog_VUM
#define IPU_LOG (varLog & 0x00004000) && SrcLog_IPU #define RPC_LOG (varLog.RPC) && SrcLog_RPC
#define VUM_LOG (varLog & 0x00008000) && SrcLog_VUM #define EECNT_LOG (varLog.Counters) && SrcLog_EECNT
#define RPC_LOG (varLog & 0x00010000) && SrcLog_RPC
#define EECNT_LOG (varLog & 0x40000000) && SrcLog_EECNT
#define PSXCPU_LOG (varLog & 0x00100000) && SrcLog_PSXCPU #define PSXCPU_LOG (varLog.R3000A) && SrcLog_PSXCPU
#define PSXMEM_LOG (varLog & 0x00200000) && SrcLog_PSXMEM #define PSXMEM_LOG (varLog.IopMemory) && SrcLog_PSXMEM
#define PSXHW_LOG (varLog & 0x00400000) && SrcLog_PSXHW #define PSXHW_LOG (varLog.IopHardware) && SrcLog_PSXHW
#define PSXBIOS_LOG (varLog & 0x00800000) && SrcLog_PSXBIOS #define PSXBIOS_LOG (varLog.IopBios) && SrcLog_PSXBIOS
#define PSXDMA_LOG (varLog & 0x01000000) && SrcLog_PSXDMA #define PSXDMA_LOG (varLog.IopDMA) && SrcLog_PSXDMA
#define PSXCNT_LOG (varLog & 0x20000000) && SrcLog_PSXCNT #define PSXCNT_LOG (varLog.IopCnt) && SrcLog_PSXCNT
//memcard has the same number as PAD_LOG for now //memcard has the same number as PAD_LOG for now
#define MEMCARDS_LOG (varLog & 0x02000000) && SrcLog_MEMCARDS #define MEMCARDS_LOG (varLog.Memcards) && SrcLog_MEMCARDS
#define PAD_LOG (varLog & 0x02000000) && SrcLog_PAD #define PAD_LOG (varLog.Pad) && SrcLog_PAD
#define GTE_LOG (varLog & 0x04000000) && SrcLog_GTE #define CDR_LOG (varLog.CDVD) && SrcLog_CDR
#define CDR_LOG (varLog & 0x08000000) && SrcLog_CDR #define GPU_LOG (varLog.GPU) && SrcLog_GPU
#define GPU_LOG (varLog & 0x10000000) && SrcLog_GPU
// fixme - currently we don't log cache // fixme - currently we don't log cache
#define CACHE_LOG 0&& #define CACHE_LOG 0&&

View File

@ -148,7 +148,7 @@ static uint parseCommandLine( const char *filename )
{ // 4 + 4 + 256 { // 4 + 4 + 256
const char * p; const char * p;
int argc; int argc;
int i; int i;
args_ptr -= 256; args_ptr -= 256;
@ -159,59 +159,47 @@ static uint parseCommandLine( const char *filename )
p = strrchr( filename, '\\' ); p = strrchr( filename, '\\' );
#else //linux #else //linux
p = strrchr( filename, '/' ); p = strrchr( filename, '/' );
if( p == NULL ) if( p == NULL ) p = strchr(filename, '\\');
p = strchr(filename, '\\');
#endif #endif
if ( p ) if (p)
{ p++;
p++;
}
else else
{ p = filename;
p = filename;
}
args_ptr -= strlen( p ) + 1; args_ptr -= strlen( p ) + 1;
/* if ( args_ptr < 0 ) // fixme- This is still impossible.
{
return 0;
}*/
strcpy( (char*)&PS2MEM_BASE[ args_ptr ], p ); //fill param 0; i.e. name of the program strcpy( (char*)&PS2MEM_BASE[ args_ptr ], p ); //fill param 0; i.e. name of the program
for ( i = strlen( p ) + 1 + 256, argc = 0; i > 0; i-- ) for ( i = strlen( p ) + 1 + 256, argc = 0; i > 0; i-- )
{ {
while ( i && ( ( PS2MEM_BASE[ args_ptr + i ] == 0 ) || ( PS2MEM_BASE[ args_ptr + i ] == 32 ) ) ) while (i && ((PS2MEM_BASE[ args_ptr + i ] == 0) || (PS2MEM_BASE[ args_ptr + i ] == 32)))
{ { i--; }
i--;
} if ( PS2MEM_BASE[ args_ptr + i + 1 ] == ' ') PS2MEM_BASE[ args_ptr + i + 1 ] = 0;
if ( PS2MEM_BASE[ args_ptr + i + 1 ] == ' ' )
{ while (i && (PS2MEM_BASE[ args_ptr + i ] != 0) && (PS2MEM_BASE[ args_ptr + i] != 32))
PS2MEM_BASE[ args_ptr + i + 1 ] = 0; { i--; }
}
while ( i && ( PS2MEM_BASE[ args_ptr + i ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i] != 32 ) ) if ((PS2MEM_BASE[ args_ptr + i ] != 0) && (PS2MEM_BASE[ args_ptr + i ] != 32))
{
i--;
}
if ( ( PS2MEM_BASE[ args_ptr + i ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i ] != 32 ) )
{ //i==0 { //i==0
argc++; argc++;
if ( args_ptr - 4 - 4 - argc * 4 < 0 ) // fixme - Should this be cast to a signed int? if ( args_ptr - 4 - 4 - argc * 4 < 0 ) // fixme - Should this be cast to a signed int?
{ return 0;
return 0;
}
((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i; ((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i;
} }
else else
{ {
if ( ( PS2MEM_BASE[ args_ptr + i + 1 ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i + 1 ] != 32 ) ) if ( ( PS2MEM_BASE[ args_ptr + i + 1 ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i + 1 ] != 32 ) )
{ {
argc++; argc++;
if ( args_ptr - 4 - 4 - argc * 4 < 0 ) // fixme - Should this be cast to a signed int? if ( args_ptr - 4 - 4 - argc * 4 < 0 ) // fixme - Should this be cast to a signed int?
{
return 0; return 0;
}
((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i + 1; ((u32*)PS2MEM_BASE)[ args_ptr / 4 - argc ] = args_ptr + i + 1;
} }
} }
} }
((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 1 ] = argc; //how many args ((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 1 ] = argc; //how many args
((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 2 ] = ( argc > 0); //have args? //not used, cannot be filled at all ((u32*)PS2MEM_BASE)[ args_ptr /4 - argc - 2 ] = ( argc > 0); //have args? //not used, cannot be filled at all
@ -311,10 +299,10 @@ struct ElfObject
if ((strnicmp( filename.c_str(), "cdrom0:", strlen("cdromN:")) == 0) || if ((strnicmp( filename.c_str(), "cdrom0:", strlen("cdromN:")) == 0) ||
(strnicmp( filename.c_str(), "cdrom1:", strlen("cdromN:")) == 0)) (strnicmp( filename.c_str(), "cdrom1:", strlen("cdromN:")) == 0))
{ {
int fi; int fi = CDVDFS_open(filename.c_str() + strlen("cdromN:"), 1);//RDONLY
fi = CDVDFS_open(filename.c_str() + strlen("cdromN:"), 1);//RDONLY
if (fi < 0) if (fi < 0) throw Exception::FileNotFound( filename );
throw Exception::FileNotFound( filename );
CDVDFS_lseek( fi, 0, SEEK_SET ); CDVDFS_lseek( fi, 0, SEEK_SET );
rsize = CDVDFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() ); rsize = CDVDFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() );
CDVDFS_close( fi ); CDVDFS_close( fi );
@ -324,15 +312,14 @@ struct ElfObject
FILE *f; FILE *f;
f = fopen( filename.c_str(), "rb" ); f = fopen( filename.c_str(), "rb" );
if( f == NULL ) if( f == NULL ) Exception::FileNotFound( filename );
Exception::FileNotFound( filename );
fseek( f, 0, SEEK_SET ); fseek( f, 0, SEEK_SET );
rsize = fread( data.GetPtr(), 1, data.GetSizeInBytes(), f ); rsize = fread( data.GetPtr(), 1, data.GetSizeInBytes(), f );
fclose( f ); fclose( f );
} }
if( rsize < data.GetSizeInBytes() ) if( rsize < data.GetSizeInBytes() ) throw Exception::EndOfStream( filename );
throw Exception::EndOfStream( filename );
} }
u32 GetCRC() const u32 GetCRC() const
@ -426,37 +413,14 @@ struct ElfObject
switch ( secthead[ i ].sh_type ) switch ( secthead[ i ].sh_type )
{ {
default: case 0x0: ELF_LOG("null"); break;
ELF_LOG("unknown %08x",secthead[i].sh_type); case 0x1: ELF_LOG("progbits"); break;
break; case 0x2: ELF_LOG("symtab"); break;
case 0x3: ELF_LOG("strtab"); break;
case 0x0: case 0x4: ELF_LOG("rela"); break;
ELF_LOG("null"); case 0x8: ELF_LOG("no bits"); break;
break; case 0x9: ELF_LOG("rel"); break;
default: ELF_LOG("unknown %08x",secthead[i].sh_type); break;
case 0x1:
ELF_LOG("progbits");
break;
case 0x2:
ELF_LOG("symtab");
break;
case 0x3:
ELF_LOG("strtab");
break;
case 0x4:
ELF_LOG("rela");
break;
case 0x8:
ELF_LOG("no bits");
break;
case 0x9:
ELF_LOG("rel");
break;
} }
ELF_LOG("\n"); ELF_LOG("\n");
@ -619,17 +583,6 @@ void LoadGameSpecificSettings()
g_FFXHack = 0; g_FFXHack = 0;
switch(ElfCRC) { switch(ElfCRC) {
// The code involving VUFIX_SIGNEDZERO & VUFIX_EXTRAFLAGS
// is no longer in pcsx2.
//case 0x0c414549: // spacefisherman, missing gfx
// g_VUGameFixes |= VUFIX_SIGNEDZERO;
// break;
//case 0x4C9EE7DF: // crazy taxi (u)
//case 0xC9C145BF: // crazy taxi, missing gfx
// g_VUGameFixes |= VUFIX_EXTRAFLAGS;
// break;
case 0xb99379b7: // erementar gerad (discolored chars) case 0xb99379b7: // erementar gerad (discolored chars)
g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42 g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42
break; break;

View File

@ -184,11 +184,9 @@ void __fastcall WriteFIFO_page_6(u32 mem, const mem128_t *value)
} }
else else
{ {
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
GSGIFTRANSFER3((u32*)value, 1); GSGIFTRANSFER3((u32*)value, 1);
FreezeMMXRegs(0); FreezeRegs(0);
FreezeXMMRegs(0);
} }
} }

View File

@ -220,14 +220,12 @@ void GIFdma()
// When MTGS is enabled, Gifchain calls WRITERING_DMA, which calls GSRINGBUF_DONECOPY, which freezes // When MTGS is enabled, Gifchain calls WRITERING_DMA, which calls GSRINGBUF_DONECOPY, which freezes
// the registers inside of the FreezeXMMRegs calls here and in the other two below.. // the registers inside of the FreezeXMMRegs calls here and in the other two below..
// I'm not really sure that is intentional. --arcum42 // I'm not really sure that is intentional. --arcum42
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
GIFchain(); GIFchain();
FreezeXMMRegs(0); // Theres a comment below that says not to unfreeze the xmm regs, so not sure about this. FreezeRegs(0); // Theres a comment below that says not to unfreeze the xmm regs, so not sure about this.
FreezeMMXRegs(0);
if((gspath3done == 1 || (gif->chcr & 0xc) == 0) && gif->qwc == 0){ if((gspath3done == 1 || (gif->chcr & 0xc) == 0) && gif->qwc == 0){
if(gif->qwc > 0) SysPrintf("Horray\n"); if(gif->qwc > 0) SysPrintf("Hurray\n");
gspath3done = 0; gspath3done = 0;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
//psHu32(GIF_MODE)&= ~0x4; //psHu32(GIF_MODE)&= ~0x4;
@ -248,11 +246,9 @@ void GIFdma()
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && (gif->chcr & 0xc) == 0) { if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && (gif->chcr & 0xc) == 0) {
SysPrintf("DMA Stall Control on GIF normal\n"); SysPrintf("DMA Stall Control on GIF normal\n");
} }
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
GIFchain(); //Transfers the data set by the switch GIFchain(); //Transfers the data set by the switch
FreezeXMMRegs(0); FreezeRegs(0);
FreezeMMXRegs(0);
if(gif->qwc == 0 && (gif->chcr & 0xc) == 0) gspath3done = 1; if(gif->qwc == 0 && (gif->chcr & 0xc) == 0) gspath3done = 1;
return; return;
} }
@ -298,12 +294,9 @@ void GIFdma()
return; return;
} }
} }
FreezeRegs(1);
FreezeXMMRegs(1);
FreezeMMXRegs(1);
GIFchain(); //Transfers the data set by the switch GIFchain(); //Transfers the data set by the switch
FreezeXMMRegs(0); FreezeRegs(0);
FreezeMMXRegs(0);
if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag
GIF_LOG("dmaIrq Set\n"); GIF_LOG("dmaIrq Set\n");
@ -534,15 +527,13 @@ void mfifoGIFtransfer(int qwc) {
gifmfifoirq = 1; gifmfifoirq = 1;
} }
} }
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
if (mfifoGIFchain() == -1) { if (mfifoGIFchain() == -1) {
SysPrintf("GIF dmaChain error size=%d, madr=%lx, tadr=%lx\n", SysPrintf("GIF dmaChain error size=%d, madr=%lx, tadr=%lx\n",
gif->qwc, gif->madr, gif->tadr); gif->qwc, gif->madr, gif->tadr);
gifstate = GIF_STATE_STALL; gifstate = GIF_STATE_STALL;
} }
FreezeXMMRegs(0); FreezeRegs(0);
FreezeMMXRegs(0);
if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL; if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL;
CPU_INT(11,mfifocycles); CPU_INT(11,mfifocycles);

View File

@ -19,28 +19,34 @@
#pragma once #pragma once
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// TestRun Parameters. // Startup Parameters.
struct TESTRUNARGS enum StartupMode
{ {
u8 enabled; BootMode_Bios,
u8 jpgcapture; BootMode_Quick,
BootMode_Elf
uint frame; // if == 0, frame is unlimited (run until crash).
int numimages;
int curimage;
u32 autopad; // mask for auto buttons
bool efile;
int snapdone;
const char* ptitle;
const char* pimagename;
const char* plogname;
const char* pgsdll, *pcdvddll, *pspudll;
const char* ppad1dll, *ppad2dll, *pdev9dll;
}; };
extern TESTRUNARGS g_TestRun; class StartupParams
{
public:
// Name of the CDVD or ELF image to load.
// if NULL, the CDVD configured settings are used.
const char* ImageName;
bool NoGui;
bool Enabled;
StartupMode BootMode;
// Plugin overrides
const char* gsdll, *cdvddll, *spudll;
const char* pad1dll, *pad2dll, *dev9dll;
StartupParams() { memzero_obj(*this); }
};
extern StartupParams g_Startup;
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Core Gui APIs (shared by all platforms) // Core Gui APIs (shared by all platforms)

View File

@ -58,7 +58,7 @@ enum
BCb_COEFF = 0x40 BCb_COEFF = 0x40
}; };
static PCSX2_ALIGNED16(const SSE2_Tables sse2_tables) = static volatile PCSX2_ALIGNED16(const SSE2_Tables sse2_tables) =
{ {
{0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000}, // c_bias {0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000}, // c_bias
{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, // y_bias {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, // y_bias
@ -223,8 +223,8 @@ ihatemsvc:
// Use ecx and edx as base pointers, to allow for Mod/RM form on memOps. // Use ecx and edx as base pointers, to allow for Mod/RM form on memOps.
// This saves 2-3 bytes per instruction where these are used. :) // This saves 2-3 bytes per instruction where these are used. :)
"mov ecx, offset yuv2rgb_temp\n" "mov ecx, offset %c[yuv2rgb_temp]\n"
"mov edx, offset sse2_tables+64\n" "mov edx, offset %c[sse2_tables]+64\n"
".align 16\n" ".align 16\n"
"tworows:\n" "tworows:\n"
@ -240,15 +240,15 @@ ihatemsvc:
// unfortunately I don't think this will matter despite being // unfortunately I don't think this will matter despite being
// technically potentially a little faster, but this is // technically potentially a little faster, but this is
// equivalent to an add or sub // equivalent to an add or sub
"pxor xmm2, xmmword ptr [edx-0x40]\n" // xmm2 <-- 8 x (Cb - 128) << 8 "pxor xmm2, xmmword ptr [edx+%c[C_BIAS]]\n" // xmm2 <-- 8 x (Cb - 128) << 8
"pxor xmm0, xmmword ptr [edx-0x40]\n" // xmm0 <-- 8 x (Cr - 128) << 8 "pxor xmm0, xmmword ptr [edx+%c[C_BIAS]]\n" // xmm0 <-- 8 x (Cr - 128) << 8
"movaps xmm1, xmm0\n" "movaps xmm1, xmm0\n"
"movaps xmm3, xmm2\n" "movaps xmm3, xmm2\n"
"pmulhw xmm1, xmmword ptr [edx+0x10]\n" "pmulhw xmm1, xmmword ptr [edx+%c[GCr_COEFF]]\n"
"pmulhw xmm3, xmmword ptr [edx+0x20]\n" "pmulhw xmm3, xmmword ptr [edx+%c[GCb_COEFF]]\n"
"pmulhw xmm0, xmmword ptr [edx+0x30]\n" "pmulhw xmm0, xmmword ptr [edx+%c[RCr_COEFF]]\n"
"pmulhw xmm2, xmmword ptr [edx+0x40]\n" "pmulhw xmm2, xmmword ptr [edx+%c[BCb_COEFF]]\n"
"paddsw xmm1, xmm3\n" "paddsw xmm1, xmm3\n"
// store for the next line; looking at the code above // store for the next line; looking at the code above
// compared to the code below, I have to wonder whether // compared to the code below, I have to wonder whether
@ -270,13 +270,13 @@ ihatemsvc:
"movaps xmm5, xmm2\n" "movaps xmm5, xmm2\n"
"movaps xmm6, xmmword ptr [mb8+edi]\n" "movaps xmm6, xmmword ptr [mb8+edi]\n"
"psubusb xmm6, xmmword ptr [edx-0x30]\n" "psubusb xmm6, xmmword ptr [edx+%c[Y_BIAS]]\n"
"movaps xmm7, xmm6\n" "movaps xmm7, xmm6\n"
"psllw xmm6, 8\n" // xmm6 <- Y << 8 for pixels 0,2,4,6,8,10,12,14 "psllw xmm6, 8\n" // xmm6 <- Y << 8 for pixels 0,2,4,6,8,10,12,14
"pand xmm7, xmmword ptr [edx+Y_MASK]\n" // xmm7 <- Y << 8 for pixels 1,3,5,7,9,11,13,15 "pand xmm7, xmmword ptr [edx+%c[Y_MASK]]\n" // xmm7 <- Y << 8 for pixels 1,3,5,7,9,11,13,15
"pmulhuw xmm6, xmmword ptr [edx+0x00]\n" "pmulhuw xmm6, xmmword ptr [edx+%c[Y_COEFF]]\n"
"pmulhuw xmm7, xmmword ptr [edx+0x00]\n" "pmulhuw xmm7, xmmword ptr [edx+%c[Y_COEFF]]\n"
"paddsw xmm0, xmm6\n" "paddsw xmm0, xmm6\n"
"paddsw xmm3, xmm7\n" "paddsw xmm3, xmm7\n"
@ -286,7 +286,7 @@ ihatemsvc:
"paddsw xmm5, xmm7\n" "paddsw xmm5, xmm7\n"
// round // round
"movaps xmm6, xmmword ptr [edx-0x10]\n" "movaps xmm6, xmmword ptr [edx+%c[ROUND_1BIT]]\n"
"paddw xmm0, xmm6\n" "paddw xmm0, xmm6\n"
"paddw xmm1, xmm6\n" "paddw xmm1, xmm6\n"
"paddw xmm2, xmm6\n" "paddw xmm2, xmm6\n"
@ -342,6 +342,12 @@ ihatemsvc:
"cmp esi, 64\n" "cmp esi, 64\n"
"jne tworows\n" "jne tworows\n"
".att_syntax\n" ".att_syntax\n"
:
:[C_BIAS]"i"(C_BIAS), [Y_BIAS]"i"(Y_BIAS), [Y_MASK]"i"(Y_MASK),
[ROUND_1BIT]"i"(ROUND_1BIT), [Y_COEFF]"i"(Y_COEFF), [GCr_COEFF]"i"(GCr_COEFF),
[GCb_COEFF]"i"(GCb_COEFF), [RCr_COEFF]"i"(RCr_COEFF), [BCb_COEFF]"i"(BCb_COEFF),
[yuv2rgb_temp]"i"(yuv2rgb_temp), [sse2_tables]"i"(&sse2_tables)
:
); );
#else #else
#error Unsupported compiler #error Unsupported compiler

View File

@ -19,7 +19,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include <ctype.h> #include <ctype.h>
#include "PsxCommon.h" #include "IopCommon.h"
namespace R3000A { namespace R3000A {

View File

@ -15,37 +15,25 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifndef __PSXCOMMON_H__ #ifndef __IOPCOMMON_H__
#define __PSXCOMMON_H__ #define __IOPCOMMON_H__
#include "PS2Etypes.h"
#include <assert.h>
#include "System.h"
extern long LoadCdBios;
extern int cdOpenCase;
#define PSXCLK (36864000ULL) /* 36.864 Mhz */ #define PSXCLK (36864000ULL) /* 36.864 Mhz */
#include "Plugins.h"
#include "Misc.h"
#include "SaveState.h"
#include "R3000A.h" #include "R3000A.h"
#include "Common.h"
#include "CdRom.h"
#include "CDVD.h"
#include "Sio.h"
#include "Sif.h"
#include "IopMem.h" #include "IopMem.h"
#include "IopHw.h" #include "IopHw.h"
#include "IopBios.h" #include "IopBios.h"
#include "IopDma.h" #include "IopDma.h"
#include "IopCounters.h" #include "IopCounters.h"
#include "CdRom.h"
#include "Sio.h"
#include "DebugTools/Debug.h"
#include "IopSio2.h" #include "IopSio2.h"
#include "CDVD.h"
#include "Memory.h"
#include "Hw.h"
#include "Sif.h"
#endif /* __PSXCOMMON_H__ */ #endif /* __IOPCOMMON_H__ */

View File

@ -23,7 +23,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include <math.h> #include <math.h>
#include "PsxCommon.h" #include "IopCommon.h"
/* Config.PsxType == 1: PAL: /* Config.PsxType == 1: PAL:
VBlank interlaced 50.00 Hz VBlank interlaced 50.00 Hz

View File

@ -18,7 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
using namespace R3000A; using namespace R3000A;

View File

@ -18,8 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "Misc.h"
#include "iR5900.h" #include "iR5900.h"
// NOTE: Any modifications to read/write fns should also go into their const counterparts // NOTE: Any modifications to read/write fns should also go into their const counterparts

View File

@ -18,7 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "VU.h" #include "VU.h"
#include "iCore.h" #include "iCore.h"
#include "Hw.h" #include "Hw.h"

View File

@ -18,7 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
sio2Struct sio2; sio2Struct sio2;

View File

@ -22,6 +22,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Paths.h" #include "Paths.h"
#include "Common.h" #include "Common.h"
#include "HostGui.h"
//For CpuDlg //For CpuDlg
#include "Counters.h" #include "Counters.h"
@ -53,7 +54,6 @@ extern "C"
extern void SaveConfig(); extern void SaveConfig();
extern int LoadConfig(); extern int LoadConfig();
extern void SysRestorableReset(); extern void SysRestorableReset();
extern bool UseGui;
extern int Pcsx2Configure(); extern int Pcsx2Configure();

View File

@ -94,7 +94,7 @@ bool Alert(const char* fmt)
{ {
GtkWidget *dialog; GtkWidget *dialog;
if (!UseGui) if (g_Startup.NoGui)
{ {
Console::Error(fmt); Console::Error(fmt);
return false; return false;
@ -126,7 +126,7 @@ bool Alert(const char* fmt, VARG_PARAM dummy, ...)
if (msg[msg.length()-1] == '\n') if (msg[msg.length()-1] == '\n')
msg[msg.length()-1] = 0; msg[msg.length()-1] = 0;
if (!UseGui) if (g_Startup.NoGui)
{ {
Console::Error(msg.c_str()); Console::Error(msg.c_str());
return false; return false;

View File

@ -59,16 +59,11 @@ int main(int argc, char *argv[])
#endif #endif
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
memset(&g_TestRun, 0, sizeof(g_TestRun)); memset(&g_Startup, 0, sizeof(g_Startup));
#endif #endif
if (!ParseCommandLine(argc, argv, file)) return 0; if (!ParseCommandLine(argc, argv, file)) return 0;
#ifdef PCSX2_DEVBUILD
g_TestRun.efile = efile;
g_TestRun.ptitle = file;
#endif
// make gtk thread safe if using MTGS // make gtk thread safe if using MTGS
if (CHECK_MULTIGS) if (CHECK_MULTIGS)
{ {
@ -76,7 +71,7 @@ int main(int argc, char *argv[])
gdk_threads_init(); gdk_threads_init();
} }
if (UseGui) if (!g_Startup.NoGui)
{ {
gtk_init(NULL, NULL); gtk_init(NULL, NULL);
} }
@ -133,7 +128,7 @@ int main(int argc, char *argv[])
} }
#endif #endif
if (UseGui && (file == NULL)) if (!g_Startup.NoGui && (file == NULL))
{ {
StartGui(); StartGui();
return 0; return 0;
@ -315,7 +310,7 @@ gboolean OnDelete(GtkWidget *widget, GdkEvent *event, gpointer user_data)
int Pcsx2Configure() int Pcsx2Configure()
{ {
if (!UseGui) return 0; if (g_Startup.NoGui) return 0;
MainWindow = NULL; MainWindow = NULL;
OnConf_Conf(NULL, 0); OnConf_Conf(NULL, 0);
@ -397,17 +392,17 @@ void pcsx2_exit()
printf("PCSX2 Quitting\n"); printf("PCSX2 Quitting\n");
if (UseGui) if (g_Startup.NoGui)
{
SysClose();
exit(0);
}
else
{ {
gtk_main_quit(); gtk_main_quit();
SysClose(); SysClose();
gtk_exit(0); gtk_exit(0);
} }
else
{
SysClose();
exit(0);
}
} }
void SignalExit(int sig) void SignalExit(int sig)

View File

@ -20,8 +20,6 @@
#include "LnxSysExec.h" #include "LnxSysExec.h"
#include "HostGui.h" #include "HostGui.h"
bool UseGui = true;
static bool sinit = false; static bool sinit = false;
GtkWidget *FileSel; GtkWidget *FileSel;
@ -68,6 +66,7 @@ void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * )
bool ParseCommandLine(int argc, char *argv[], char *file) bool ParseCommandLine(int argc, char *argv[], char *file)
{ {
int i = 1; int i = 1;
g_Startup.BootMode = BootMode_Bios;
while (i < argc) while (i < argc)
{ {
@ -78,84 +77,50 @@ bool ParseCommandLine(int argc, char *argv[], char *file)
//Msgbox::Alert( phelpmsg ); //Msgbox::Alert( phelpmsg );
return false; return false;
} }
else if (stricmp(token, "-efile") == 0)
{
token = argv[i++];
if (token != NULL)
{
efile = atoi(token);
}
}
else if (stricmp(token, "-nogui") == 0) else if (stricmp(token, "-nogui") == 0)
{ {
UseGui = FALSE; g_Startup.NoGui = FALSE;
} }
else if (stricmp(token, "-loadgs") == 0) else if (stricmp(token, "-loadgs") == 0)
{ {
g_pRunGSState = argv[i++]; g_pRunGSState = argv[i++];
} }
#ifdef PCSX2_DEVBUILD else if( strcmp(token, "-bootmode" ) == 0)
else if (stricmp(token, "-image") == 0)
{
g_TestRun.pimagename = argv[i++];
}
else if (stricmp(token, "-log") == 0)
{
g_TestRun.plogname = argv[i++];
}
else if (stricmp(token, "-logopt") == 0)
{ {
token = argv[i++]; token = argv[i++];
if (token != NULL) g_Startup.BootMode = (StartupMode)atoi( token);
{ g_Startup.Enabled = true;
if (token[0] == '0' && token[1] == 'x') token += 2;
sscanf(token, "%x", &varLog);
}
}
else if (stricmp(token, "-frame") == 0)
{
token = argv[i++];
if (token != NULL)
{
g_TestRun.frame = atoi(token);
}
}
else if (stricmp(token, "-numimages") == 0)
{
token = argv[i++];
if (token != NULL)
{
g_TestRun.numimages = atoi(token);
}
}
else if (stricmp(token, "-jpg") == 0)
{
g_TestRun.jpgcapture = 1;
} }
else if (stricmp(token, "-gs") == 0) else if (stricmp(token, "-gs") == 0)
{ {
token = argv[i++]; token = argv[i++];
g_TestRun.pgsdll = token; g_Startup.gsdll = token;
} }
else if (stricmp(token, "-cdvd") == 0) else if (stricmp(token, "-cdvd") == 0)
{ {
token = argv[i++]; token = argv[i++];
g_TestRun.pcdvddll = token; g_Startup.cdvddll = token;
} }
else if (stricmp(token, "-spu") == 0) else if (stricmp(token, "-spu") == 0)
{ {
token = argv[i++]; token = argv[i++];
g_TestRun.pspudll = token; g_Startup.spudll = token;
} }
else if (stricmp(token, "-test") == 0)
{
g_TestRun.enabled = 1;
}
#endif
else if (stricmp(token, "-pad") == 0) else if (stricmp(token, "-pad") == 0)
{ {
token = argv[i++]; token = argv[i++];
printf("-pad ignored\n"); g_Startup.pad1dll = token;
g_Startup.pad2dll = token;
}
else if (stricmp(token, "-pad1") == 0)
{
token = argv[i++];
g_Startup.pad1dll = token;
}
else if (stricmp(token, "-pad2") == 0)
{
token = argv[i++];
g_Startup.pad2dll = token;
} }
else if (stricmp(token, "-loadgs") == 0) else if (stricmp(token, "-loadgs") == 0)
{ {
@ -183,9 +148,33 @@ void SysPrintf(const char *fmt, ...)
Console::Write(msg); Console::Write(msg);
} }
static std::string str_Default( "default" );
void RunGui() void RunGui()
{ {
PCSX2_MEM_PROTECT_BEGIN();
LoadPatch( str_Default );
if( g_Startup.NoGui || g_Startup.Enabled )
{
// Initially bypass GUI and start PCSX2 directly.
// Manually load plugins using the user's configured image (if non-elf).
if( g_Startup.Enabled && (g_Startup.BootMode != BootMode_Elf) )
{
if (OpenPlugins(g_Startup.ImageName) == -1)
return;
}
SysPrepareExecution(
(g_Startup.BootMode == BootMode_Elf) ? g_Startup.ImageName : NULL,
(g_Startup.BootMode == BootMode_Bios)
);
}
StartGui(); StartGui();
PCSX2_MEM_PROTECT_END();
} }
void OnStates_Load(GtkMenuItem *menuitem, gpointer user_data) void OnStates_Load(GtkMenuItem *menuitem, gpointer user_data)
@ -319,8 +308,6 @@ bool SysInit()
mkdir(LOGS_DIR, 0755); mkdir(LOGS_DIR, 0755);
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if (g_TestRun.plogname != NULL)
emuLog = fopen(g_TestRun.plogname, "w");
if (emuLog == NULL) if (emuLog == NULL)
emuLog = fopen(LOGS_DIR "/emuLog.txt", "wb"); emuLog = fopen(LOGS_DIR "/emuLog.txt", "wb");
#endif #endif
@ -525,7 +512,7 @@ namespace HostGui
#endif #endif
SysEndExecution(); SysEndExecution();
if (!UseGui) exit(0); if (g_Startup.NoGui) exit(0);
// fixme: The GUI is now capable of receiving control back from the // fixme: The GUI is now capable of receiving control back from the
// emulator. Which means that when we call SysEscapeExecute() here, the // emulator. Which means that when we call SysEscapeExecute() here, the

View File

@ -677,16 +677,14 @@ int mtgsThreadObject::Callback()
void mtgsThreadObject::WaitGS() void mtgsThreadObject::WaitGS()
{ {
// Freeze registers because some kernel code likes to destroy them // Freeze registers because some kernel code likes to destroy them
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
SetEvent(); SetEvent();
while( volatize(m_RingPos) != volatize(m_WritePos) ) while( volatize(m_RingPos) != volatize(m_WritePos) )
{ {
Timeslice(); Timeslice();
//SpinWait(); //SpinWait();
} }
FreezeXMMRegs(0); FreezeRegs(0);
FreezeMMXRegs(0);
} }
// Sets the gsEvent flag and releases a timeslice. // Sets the gsEvent flag and releases a timeslice.
@ -701,8 +699,7 @@ void mtgsThreadObject::SetEvent()
void mtgsThreadObject::PrepEventWait() void mtgsThreadObject::PrepEventWait()
{ {
// Freeze registers because some kernel code likes to destroy them // Freeze registers because some kernel code likes to destroy them
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
//Console::Notice( "MTGS Stall! EE waits for nothing! ... except your GPU sometimes." ); //Console::Notice( "MTGS Stall! EE waits for nothing! ... except your GPU sometimes." );
SetEvent(); SetEvent();
Timeslice(); Timeslice();
@ -710,8 +707,7 @@ void mtgsThreadObject::PrepEventWait()
void mtgsThreadObject::PostEventWait() const void mtgsThreadObject::PostEventWait() const
{ {
FreezeMMXRegs(0); FreezeRegs(0);
FreezeXMMRegs(0);
} }
u8* mtgsThreadObject::GetDataPacketPtr() const u8* mtgsThreadObject::GetDataPacketPtr() const
@ -770,12 +766,10 @@ void mtgsThreadObject::SendDataPacket()
m_CopyDataTally += m_packet_size; m_CopyDataTally += m_packet_size;
if( ( m_CopyDataTally > 0x8000 ) || ( ++m_CopyCommandTally > 16 ) ) if( ( m_CopyDataTally > 0x8000 ) || ( ++m_CopyCommandTally > 16 ) )
{ {
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
//Console::Status( "MTGS Kick! DataSize : 0x%5.8x, CommandTally : %d", m_CopyDataTally, m_CopyCommandTally ); //Console::Status( "MTGS Kick! DataSize : 0x%5.8x, CommandTally : %d", m_CopyDataTally, m_CopyCommandTally );
SetEvent(); SetEvent();
FreezeMMXRegs(0); FreezeRegs(0);
FreezeXMMRegs(0);
} }
} }

View File

@ -18,7 +18,7 @@ RecoverySystem.cpp Saveslots.cpp
libpcsx2_a_SOURCES += \ libpcsx2_a_SOURCES += \
CDVD.h CDVDiso.h CDVDisodrv.h CDVDlib.h COP0.h Cache.h CdRom.h Common.h Counters.h Decode_XA.h EEregs.h \ CDVD.h CDVDiso.h CDVDisodrv.h CDVDlib.h COP0.h Cache.h CdRom.h Common.h Counters.h Decode_XA.h EEregs.h \
Elfheader.h Exceptions.h GS.h Hw.h IopBios.h IopBios2.h IopCounters.h IopDma.h IopHw.h IopMem.h IopSio2.h Memcpyfast.h \ Elfheader.h Exceptions.h GS.h Hw.h IopBios.h IopBios2.h IopCounters.h IopDma.h IopHw.h IopMem.h IopSio2.h Memcpyfast.h \
Memory.h MemoryCard.h Misc.h Patch.h Paths.h Plugins.h PrecompiledHeader.h PsxCommon.h R3000A.h R5900.h R5900OpcodeTables.h \ Memory.h MemoryCard.h Misc.h Patch.h Paths.h Plugins.h PrecompiledHeader.h IopCommon.h R3000A.h R5900.h R5900OpcodeTables.h \
SPR.h SamplProf.h SaveState.h Sif.h Sifcmd.h Sio.h SafeArray.h Stats.h StringUtils.h System.h Threading.h \ SPR.h SamplProf.h SaveState.h Sif.h Sifcmd.h Sio.h SafeArray.h Stats.h StringUtils.h System.h Threading.h \
VU.h VUflags.h VUmicro.h VUops.h Vif.h VifDma.h cheatscpp.h vtlb.h NakedAsm.h R5900Exceptions.h HostGui.h Pcsx2Config.h VU.h VUflags.h VUmicro.h VUops.h Vif.h VifDma.h cheatscpp.h vtlb.h NakedAsm.h R5900Exceptions.h HostGui.h Pcsx2Config.h

View File

@ -21,8 +21,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "Misc.h" #include "IopCommon.h"
#include "PsxCommon.h"
#include "Mdec.h" #include "Mdec.h"
int iq_y[DCTSIZE2],iq_uv[DCTSIZE2]; int iq_y[DCTSIZE2],iq_uv[DCTSIZE2];

View File

@ -19,46 +19,30 @@
#ifndef __MEMCPY_FAST_H__ #ifndef __MEMCPY_FAST_H__
#define __MEMCPY_FAST_H__ #define __MEMCPY_FAST_H__
void _memset16_unaligned( void* dest, u16 data, size_t size ); #if defined(_WIN32)
#include "windows/memzero.h"
#else
#include "Linux/memzero.h"
#endif // WIN32
#if defined(_WIN32) && !defined(__x86_64__) // Only used in the Windows version of memzero.h. But it's in Misc.cpp for some reason.
void _memset16_unaligned( void* dest, u16 data, size_t size );
// The new simplified memcpy_amd_ is now faster than memcpy_raz_. // The new simplified memcpy_amd_ is now faster than memcpy_raz_.
// memcpy_amd_ also does mmx register saving, negating the need for freezeregs (code cleanup!) // memcpy_amd_ also does mmx register saving, negating the need for freezeregs (code cleanup!)
// Additionally, using one single memcpy implementation keeps the code cache cleaner. // Additionally, using one single memcpy implementation keeps the code cache cleaner.
//extern void __fastcall memcpy_raz_udst(void *dest, const void *src, size_t bytes); #ifdef __LINUX__
//extern void __fastcall memcpy_raz_usrc(void *dest, const void *src, size_t bytes); extern "C" void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes);
//extern void __fastcall memcpy_raz_(void *dest, const void *src, size_t bytes); extern "C" u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
extern "C" void memxor_mmx(void* dst, const void* src1, int cmpsize);
#else
extern void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes); extern void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes);
extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize); extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
extern void memxor_mmx(void* dst, const void* src1, int cmpsize); extern void memxor_mmx(void* dst, const void* src1, int cmpsize);
#endif
# include "windows/memzero.h" #define memcpy_fast memcpy_amd_
# define memcpy_fast memcpy_amd_ #define memcpy_aligned memcpy_amd_
# define memcpy_aligned memcpy_amd_
#else
// for now linux uses the GCC memcpy/memset implementations.
//#define memcpy_raz_udst memcpy
//#define memcpy_raz_usrc memcpy
//#define memcpy_raz_ memcpy
// fast_routines.S
extern "C" u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
extern "C" void memxor_mmx(void* dst, const void* src1, int cmpsize);
# include "Linux/memzero.h"
#if defined(LINUX_USE_FAST_MEMORY)
# define memcpy_fast memcpy_amd_
# define memcpy_aligned memcpy_amd_
extern "C" void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes);
#else
# define memcpy_fast memcpy
# define memcpy_aligned memcpy
#endif // LINUX_USE_FAST_MEMORY
#endif // WIN32
#endif //Header #endif //Header

View File

@ -43,10 +43,9 @@ BIOS
#include <vector> #include <vector>
#include "Common.h" #include "IopCommon.h"
#include "iR5900.h" #include "iR5900.h"
#include "PsxCommon.h"
#include "VUmicro.h" #include "VUmicro.h"
#include "GS.h" #include "GS.h"
#include "IPU/IPU.h" #include "IPU/IPU.h"

View File

@ -18,7 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Misc.h" #include "System.h"
#include "MemoryCard.h" #include "MemoryCard.h"
#include "Paths.h" #include "Paths.h"

View File

@ -26,8 +26,7 @@
#include <ctype.h> #include <ctype.h>
#include "Common.h" #include "IopCommon.h"
#include "PsxCommon.h"
#include "HostGui.h" #include "HostGui.h"
#include "CDVDisodrv.h" #include "CDVDisodrv.h"
@ -52,6 +51,11 @@ char CdromId[12];
static int g_Pcsx2Recording = 0; // true 1 if recording video and sound static int g_Pcsx2Recording = 0; // true 1 if recording video and sound
bool renderswitch = 0; bool renderswitch = 0;
#define NUM_STATES 10
int StatesC = 0;
extern char strgametitle[256];
const char *LabelAuthors = { const char *LabelAuthors = {
"PCSX2, a PS2 emulator\n\n" "PCSX2, a PS2 emulator\n\n"
"Active Devs: Arcum42, Refraction,\n" "Active Devs: Arcum42, Refraction,\n"
@ -80,73 +84,22 @@ const char *LabelGreets = {
"F|RES, MrBrown, razorblade, Seta-san, Skarmeth" "F|RES, MrBrown, razorblade, Seta-san, Skarmeth"
}; };
static struct { #define DIRENTRY_SIZE 16
const char *name;
u32 size;
} ioprps[]={
{"IOPRP14", 43845},
{"IOPRP142", 48109},
{"IOPRP143", 58317},
{"IOPRP144", 58525},
{"IOPRP15", 82741},
{"IOPRP151", 82917},
{"IOPRP153", 82949},
{"IOPRP16", 91909},
{"IOPRP165", 98901},
{"IOPRP20", 109809},
{"IOPRP202", 110993},
{"IOPRP205", 119797},
{"IOPRP21", 126857},
{"IOPRP211", 129577},
{"IOPRP213", 129577},
{"IOPRP214", 140945},
{"IOPRP22", 199257},
{"IOPRP221", 196937},
{"IOPRP222", 198233},
{"IOPRP224", 201065},
{"IOPRP23", 230329},
{"IOPRP234", 247641},
{"IOPRP24", 251065},
{"IOPRP241", 251049},
{"IOPRP242", 252409},
{"IOPRP243", 253201},
{"IOPRP250", 264897},
{"IOPRP252", 265233},
{"IOPRP253", 267217},
{"IOPRP254", 264449},
{"IOPRP255", 264449},
{"IOPRP260", 248945},
{"IOPRP270", 249121},
{"IOPRP271", 266817},
{"IOPRP280", 269889},
{"IOPRP300", 275345},
{"DNAS280", 272753},
{"DNAS270", 251729},
{"DNAS271", 268977},
{"DNAS300", 278641},
{"DNAS280", 272705},
{"DNAS255", 264945},
{NULL, 0}
};
void GetRPCVersion(char *ioprp, char *rpcver){ #if defined(_MSC_VER)
char *p=ioprp; #pragma pack(1)
int i; #endif
struct TocEntry te;
struct romdir{
if (p && (CDVD_findfile(p+strlen("cdromN:"), &te) != -1)){ char fileName[10];
for (i=0; ioprps[i].size>0; i++) u16 extInfoSize;
if (te.fileSize==ioprps[i].size) u32 fileSize;
break; #if defined(_MSC_VER)
if (ioprps[i].size>0) };
p=(char *)ioprps[i].name; #pragma pack() //+22
} #else
// fixme - Is p really supposed to be set in the middle of an if statement? } __attribute__((packed));
if (p && (p=strstr(p, "IOPRP")+strlen("IOPRP"))){ #endif
for (i=0;(i<4) && p && (*p>='0') && (*p<='9');i++, p++) rpcver[i]=*p;
for ( ; i<4 ;i++ ) rpcver[i]='0';
}
}
u32 GetBiosVersion() { u32 GetBiosVersion() {
unsigned int fileOffset=0; unsigned int fileOffset=0;
@ -267,44 +220,6 @@ int IsBIOS(char *filename, char *description)
return FALSE; //fail quietly return FALSE; //fail quietly
} }
// LOAD STUFF
// fixme - Is there any reason why we shouldn't delete this define, and replace the array lengths
// with the actual numbers?
#define ISODCL(from, to) (to - from + 1)
struct iso_directory_record {
char length [ISODCL (1, 1)]; /* length[1]; 711 */
char ext_attr_length [ISODCL (2, 2)]; /* ext_attr_length[1]; 711 */
char extent [ISODCL (3, 10)]; /* extent[8]; 733 */
char size [ISODCL (11, 18)]; /* size[8]; 733 */
char date [ISODCL (19, 25)]; /* date[7]; 7 by 711 */
char flags [ISODCL (26, 26)]; /* flags[1]; */
char file_unit_size [ISODCL (27, 27)]; /* file_unit_size[1]; 711 */
char interleave [ISODCL (28, 28)]; /* interleave[1]; 711 */
char volume_sequence_number [ISODCL (29, 32)]; /* volume_sequence_number[3]; 723 */
unsigned char name_len [ISODCL (33, 33)]; /* name_len[1]; 711 */
char name [1];
};
int LoadCdrom() {
return 0;
}
int CheckCdrom() {
u8 *buf;
if (CDVDreadTrack(16, CDVD_MODE_2352) == -1)
return -1;
buf = CDVDgetBuffer();
if (buf == NULL)
return -1;
strncpy(CdromId, (char*)buf+52, 10);
return 0;
}
int GetPS2ElfName(char *name){ int GetPS2ElfName(char *name){
int f; int f;
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D char buffer[g_MaxPath];//if a file is longer...it should be shorter :D
@ -351,7 +266,6 @@ int GetPS2ElfName(char *name){
FILE *fp; FILE *fp;
int i; int i;
// inifile_read(CdromId);
fp = fopen("System.map", "r"); fp = fopen("System.map", "r");
if( fp == NULL ) return 2; if( fp == NULL ) return 2;
@ -396,7 +310,6 @@ void SaveGSState(const string& file)
g_fGSSave->Freeze( g_nLeftGSFrames ); g_fGSSave->Freeze( g_nLeftGSFrames );
} }
extern uptr pDsp;
void LoadGSState(const string& file) void LoadGSState(const string& file)
{ {
int ret; int ret;
@ -448,11 +361,6 @@ void LoadGSState(const string& file)
#endif #endif
#define NUM_STATES 10
int StatesC = 0;
extern char strgametitle[256];
char* mystrlwr( char* string ) char* mystrlwr( char* string )
{ {
assert( string != NULL ); assert( string != NULL );
@ -529,10 +437,10 @@ void CycleFrameLimit(int dir)
void ProcessFKeys(int fkey, int shift) void ProcessFKeys(int fkey, int shift)
{ {
assert(fkey >= 1 && fkey <= 12 ); assert(fkey >= 1 && fkey <= 12 );
switch(fkey) { switch(fkey) {
case 1: case 1:
try try
{ {
gzSavingState( SaveState::GetFilename( StatesC ) ).FreezeAll(); gzSavingState( SaveState::GetFilename( StatesC ) ).FreezeAll();
@ -653,93 +561,26 @@ void ProcessFKeys(int fkey, int shift)
#endif #endif
case 12: case 12:
if( shift ) { if( shift ) {
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
iDumpRegisters(cpuRegs.pc, 0); iDumpRegisters(cpuRegs.pc, 0);
Console::Notice("hardware registers dumped EE:%x, IOP:%x\n", params cpuRegs.pc, psxRegs.pc); Console::Notice("hardware registers dumped EE:%x, IOP:%x\n", params cpuRegs.pc, psxRegs.pc);
#endif #endif
} }
else { else {
g_Pcsx2Recording ^= 1; g_Pcsx2Recording ^= 1;
if( mtgsThread != NULL ) { if( mtgsThread != NULL ) {
mtgsThread->SendSimplePacket(GS_RINGTYPE_RECORD, g_Pcsx2Recording, 0, 0); mtgsThread->SendSimplePacket(GS_RINGTYPE_RECORD, g_Pcsx2Recording, 0, 0);
} }
else { else {
if( GSsetupRecording != NULL ) GSsetupRecording(g_Pcsx2Recording, NULL); if( GSsetupRecording != NULL ) GSsetupRecording(g_Pcsx2Recording, NULL);
} }
if( SPU2setupRecording != NULL ) SPU2setupRecording(g_Pcsx2Recording, NULL); if( SPU2setupRecording != NULL ) SPU2setupRecording(g_Pcsx2Recording, NULL);
} }
break; break;
}
}
void injectIRX(const char *filename)
{
char name[260], *p, *q;
struct romdir *rd;
int iROMDIR=-1, iIOPBTCONF=-1, iBLANK=-1, i, filesize;
FILE *fp;
strcpy(name, filename);
for (i=0; name[i] && name[i]!='.' && i<10; i++) name[i]=toupper(name[i]);name[i]=0;
//phase 1: find ROMDIR in bios
for (p=(char*)PS2MEM_ROM; p<(char*)PS2MEM_ROM+0x80000; p++)
if (strncmp(p, "RESET", 5)==0)
break;
rd=(struct romdir*)p;
for (i=0; rd[i].fileName[0]; i++)if (strncmp(rd[i].fileName, name, strlen(name))==0)break;
if (rd[i].fileName[0])return;//already in;)
//phase 2: make room in IOPBTCONF & ROMDIR
for (i=0; rd[i].fileName[0]; i++)if (strncmp(rd[i].fileName, "ROMDIR", 6)==0)iROMDIR=i;
for (i=0; rd[i].fileName[0]; i++)if (strncmp(rd[i].fileName, "IOPBTCONF", 9)==0)iIOPBTCONF=i;
for (i=0; rd[i].fileName[0]; i++)if (rd[i].fileName[0]=='-')break; iBLANK=i;
rd[iBLANK].fileSize-=DIRENTRY_SIZE+DIRENTRY_SIZE;
p=(char*)PS2MEM_ROM;for (i=0; i<iBLANK; i++)p+=(rd[i].fileSize+0xF)&(~0xF);p+=DIRENTRY_SIZE;
// fixme - brevity, yes, but at the expense of readability?
q=(char*)PS2MEM_ROM;for (i=0; i<=iIOPBTCONF; i++) q+=(rd[i].fileSize+0xF)&(~0xF);
while (p-16>q){*((u64*)p)=*((u64*)p-4);*((u64*)p+1)=*((u64*)p-3);p-=DIRENTRY_SIZE;}
*((u64*)p)=*((u64*)p+1)=0;p-=DIRENTRY_SIZE;rd[iIOPBTCONF].fileSize+=DIRENTRY_SIZE;
q=(char*)PS2MEM_ROM;for (i=0; i<=iROMDIR; i++) q+=(rd[i].fileSize+0xF)&(~0xF);
while (p >q){*((u64*)p)=*((u64*)p-2);*((u64*)p+1)=*((u64*)p-1);p-=DIRENTRY_SIZE;}
*((u64*)p)=*((u64*)p+1)=0;p-=DIRENTRY_SIZE;rd[iROMDIR].fileSize+=DIRENTRY_SIZE;
//phase 3: add the name to the end of IOPBTCONF
p=(char*)PS2MEM_ROM;for (i=0; i<iIOPBTCONF; i++) p+=(rd[i].fileSize+0xF)&(~0xF);while(*p) p++;//go to end of file
strcpy(p, name);p[strlen(name)]=0xA;
//phase 4: find file
string path( Path::Combine( Config.BiosDir, filename ) );
if( !Path::isFile( path ) )
{
Msgbox::Alert("Unable to hack in %s%s\n", params Config.BiosDir, filename);
return;
} }
//phase 5: add the file to the end of the bios
p=(char*)PS2MEM_ROM;for (i=0; rd[i].fileName[0]; i++)p+=(rd[i].fileSize+0xF)&(~0xF);
fp=fopen(path.c_str(), "rb");
fseek(fp, 0, SEEK_END);
filesize=ftell(fp);
fseek(fp, 0, SEEK_SET);
fread(p, 1, filesize, fp);
fclose(fp);
//phase 6: register it in ROMDIR
memset(rd[i].fileName, 0, 10);
memcpy(rd[i].fileName, name, strlen(name));
rd[i].fileSize=filesize;
rd[i].extInfoSize=0;
} }
void _memset16_unaligned( void* dest, u16 data, size_t size ) void _memset16_unaligned( void* dest, u16 data, size_t size )
{ {
jASSUME( (size & 0x1) == 0 ); jASSUME( (size & 0x1) == 0 );

View File

@ -56,18 +56,17 @@ extern bool g_EEFreezeRegs;
#ifndef __INTEL_COMPILER #ifndef __INTEL_COMPILER
extern "C" void FreezeXMMRegs_(int save); extern "C" void FreezeXMMRegs_(int save);
extern "C" void FreezeMMXRegs_(int save); extern "C" void FreezeMMXRegs_(int save);
extern "C" void FreezeRegs(int save);
#else #else
extern void FreezeXMMRegs_(int save); extern void FreezeXMMRegs_(int save);
extern void FreezeMMXRegs_(int save); extern void FreezeMMXRegs_(int save);
extern void FreezeRegs(int save);
#endif #endif
// these macros check to see if needs freezing // these macros check to see if needs freezing
#define FreezeXMMRegs(save) if( g_EEFreezeRegs ) { FreezeXMMRegs_(save); } #define FreezeXMMRegs(save) if( g_EEFreezeRegs ) { FreezeXMMRegs_(save); }
#define FreezeMMXRegs(save) if( g_EEFreezeRegs ) { FreezeMMXRegs_(save); } #define FreezeMMXRegs(save) if( g_EEFreezeRegs ) { FreezeMMXRegs_(save); }
// Not used.
//void injectIRX(const char *filename);
// If we move the rest of this stuff, we can probably move these, too. // If we move the rest of this stuff, we can probably move these, too.
extern void InitCPUTicks(); extern void InitCPUTicks();
extern u64 GetCPUTicks(); extern u64 GetCPUTicks();
@ -80,30 +79,8 @@ extern const char *LabelAuthors;
extern const char *LabelGreets; extern const char *LabelGreets;
void CycleFrameLimit(int dir); void CycleFrameLimit(int dir);
// Only used in Misc.cpp
void SaveGSState(const string& file); void SaveGSState(const string& file);
void LoadGSState(const string& file); void LoadGSState(const string& file);
extern char CdromId[12];
int LoadCdrom();
int CheckCdrom();
#define DIRENTRY_SIZE 16
#if defined(_MSC_VER)
#pragma pack(1)
#endif
struct romdir{
char fileName[10];
u16 extInfoSize;
u32 fileSize;
#if defined(_MSC_VER)
};
#pragma pack() //+22
#else
} __attribute__((packed));
#endif
#endif /* __MISC_H__ */ #endif /* __MISC_H__ */

View File

@ -23,7 +23,7 @@
#define _PC_ // disables MIPS opcode macros. #define _PC_ // disables MIPS opcode macros.
#include "PsxCommon.h" #include "IopCommon.h"
#include "Paths.h" #include "Paths.h"
#include "Patch.h" #include "Patch.h"
#include "VU.h" #include "VU.h"

View File

@ -19,8 +19,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "RedtapeWindows.h" #include "RedtapeWindows.h"
#include "Common.h" #include "IopCommon.h"
#include "PsxCommon.h"
#include "GS.h" #include "GS.h"
_GSinit GSinit; _GSinit GSinit;

View File

@ -18,9 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "Misc.h"
#include "R5900.h" #include "R5900.h"
using namespace R3000A; using namespace R3000A;

View File

@ -19,8 +19,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "Common.h"
using namespace R3000A; using namespace R3000A;
@ -380,8 +379,9 @@ void psxJALR() { if (_Rd_) { _SetLink(_Rd_); } doBranch(_u32(_rRs_)); }
static __forceinline void execI() static __forceinline void execI()
{ {
psxRegs.code = iopMemRead32(psxRegs.pc); psxRegs.code = iopMemRead32(psxRegs.pc);
PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc)); //if( (psxRegs.pc >= 0x1200 && psxRegs.pc <= 0x1400) || (psxRegs.pc >= 0x0b40 && psxRegs.pc <= 0x1000))
PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc));
psxRegs.pc+= 4; psxRegs.pc+= 4;
psxRegs.cycle++; psxRegs.cycle++;
@ -395,6 +395,7 @@ static void doBranch(s32 tar) {
branch2 = iopIsDelaySlot = true; branch2 = iopIsDelaySlot = true;
branchPC = tar; branchPC = tar;
execI(); execI();
PSXCPU_LOG( "\n" );
iopIsDelaySlot = false; iopIsDelaySlot = false;
psxRegs.pc = branchPC; psxRegs.pc = branchPC;

View File

@ -18,8 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "Common.h"
extern void zeroEx(); extern void zeroEx();
@ -58,7 +57,7 @@ void psxANDI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) & _ImmU_; } // Rt = Rs
void psxORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; } // Rt = Rs Or Im void psxORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; } // Rt = Rs Or Im
void psxXORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; } // Rt = Rs Xor Im void psxXORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; } // Rt = Rs Xor Im
void psxSLTI() { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; } // Rt = Rs < Im (Signed) void psxSLTI() { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; } // Rt = Rs < Im (Signed)
void psxSLTIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < _ImmU_; } // Rt = Rs < Im (Unsigned) void psxSLTIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < (u32)_Imm_; } // Rt = Rs < Im (Unsigned)
/********************************************************* /*********************************************************
* Register arithmetic * * Register arithmetic *

View File

@ -387,19 +387,12 @@ static __forceinline void _cpuTestTIMR()
static __forceinline void _cpuTestPERF() static __forceinline void _cpuTestPERF()
{ {
// fixme - The interpreter and recompiler both re-calculate these values // Perfs are updated when read by games (COP0's MFC0/MTC0 instructions), so we need
// whenever they are read, so updating them at regular intervals *should be* // only update them at semi-regular intervals to keep cpuRegs.cycle from wrapping
// merely a common courtesy. But when I set them up to be called less // around twice on us btween updates. Hence this function is called from the cpu's
// frequently some games would crash. I'd like to figure out why someday. [Air] // Counters update.
if((cpuRegs.PERF.n.pccr & 0x800003E0) == 0x80000020) { COP0_UpdatePCCR();
cpuRegs.PERF.n.pcr0 += cpuRegs.cycle-s_iLastPERFCycle[0];
s_iLastPERFCycle[0] = cpuRegs.cycle;
}
if((cpuRegs.PERF.n.pccr & 0x800F8000) == 0x80008000) {
cpuRegs.PERF.n.pcr1 += cpuRegs.cycle-s_iLastPERFCycle[1];
s_iLastPERFCycle[1] = cpuRegs.cycle;
}
} }
// Checks the COP0.Status for exception enablings. // Checks the COP0.Status for exception enablings.

View File

@ -52,8 +52,35 @@ union GPRregs {
}; };
union PERFregs { union PERFregs {
struct { struct
u32 pccr, pcr0, pcr1, pad; {
union
{
struct
{
u32 pad0:1; // LSB should always be zero (or undefined)
u32 EXL0:1; // enable PCR0 during Level 1 exception handling
u32 K0:1; // enable PCR0 during Kernel Mode execution
u32 S0:1; // enable PCR0 during Supervisor mode execution
u32 U0:1; // enable PCR0 during User-mode execution
u32 Event0:5; // PCR0 event counter (all values except 1 ignored at this time)
u32 pad1:1; // more zero/undefined padding [bit 10]
u32 EXL1:1; // enable PCR1 during Level 1 exception handling
u32 K1:1; // enable PCR1 during Kernel Mode execution
u32 S1:1; // enable PCR1 during Supervisor mode execution
u32 U1:1; // enable PCR1 during User-mode execution
u32 Event1:5; // PCR1 event counter (all values except 1 ignored at this time)
u32 Reserved:11;
u32 CTE:1; // Counter enable bit, no counting if set to zero.
} b;
u32 val;
} pccr;
u32 pcr0, pcr1, pad;
} n; } n;
u32 r[4]; u32 r[4];
}; };

View File

@ -18,8 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Common.h" #include "IopCommon.h"
#include "PsxCommon.h"
#include "VUmicro.h" #include "VUmicro.h"
#include "deci2.h" #include "deci2.h"

View File

@ -18,8 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Common.h" #include "IopCommon.h"
#include "PsxCommon.h"
#include "IopBios2.h" #include "IopBios2.h"
#include "deci2.h" #include "deci2.h"

View File

@ -18,8 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Common.h" #include "IopCommon.h"
#include "PsxCommon.h"
#include "SaveState.h" #include "SaveState.h"
#include "CDVDisodrv.h" #include "CDVDisodrv.h"

View File

@ -23,7 +23,7 @@
#ifdef __LINUX__ #ifdef __LINUX__
#include "PS2Edefs.h" #include "PS2Edefs.h"
#endif #endif
#include "System.h"
// Savestate Versioning! // Savestate Versioning!
// If you make changes to the savestate version, please increment the value below. // If you make changes to the savestate version, please increment the value below.

View File

@ -22,8 +22,7 @@
#include "GS.h" #include "GS.h"
TESTRUNARGS g_TestRun; StartupParams g_Startup;
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Save Slot Detection System // Save Slot Detection System
@ -63,11 +62,11 @@ void States_Load( const string& file )
try try
{ {
_loadStateOrExcept( file ); _loadStateOrExcept( file );
HostGui::Notice( fmt_string( "*PCSX2*: Loaded State %s", file) ); HostGui::Notice( fmt_string( "*PCSX2*: Loaded State %hs", &file) );
} }
catch( Exception::StateLoadError_Recoverable& ex) catch( Exception::StateLoadError_Recoverable& ex)
{ {
Console::Notice( "Could not load savestate file: %s.\n\n%s", params file, ex.cMessage() ); Console::Notice( "Could not load savestate file: %hs.\n\n%s", params &file, ex.cMessage() );
// At this point the cpu hasn't been reset, so we can return // At this point the cpu hasn't been reset, so we can return
// control to the user safely... (that's why we use a console notice instead of a popup) // control to the user safely... (that's why we use a console notice instead of a popup)
@ -79,7 +78,7 @@ void States_Load( const string& file )
// The emulation state is ruined. Might as well give them a popup and start the gui. // The emulation state is ruined. Might as well give them a popup and start the gui.
string message( fmt_string( string message( fmt_string(
"Encountered an error while loading savestate from file: %s.\n", file ) ); "Encountered an error while loading savestate from file: %hs.\n", &file ) );
if( g_EmulationInProgress ) if( g_EmulationInProgress )
message += "Since the savestate load was incomplete, the emulator must reset.\n"; message += "Since the savestate load was incomplete, the emulator must reset.\n";
@ -145,12 +144,12 @@ void States_Save( const string& file )
try try
{ {
StateRecovery::SaveToFile( file ); StateRecovery::SaveToFile( file );
HostGui::Notice( fmt_string( "State saved to file: %s", file ) ); HostGui::Notice( fmt_string( "State saved to file: %hs", &file ) );
} }
catch( Exception::BaseException& ex ) catch( Exception::BaseException& ex )
{ {
Console::Error( (fmt_string( Console::Error( (fmt_string(
"An error occurred while trying to save to file %s\n", file ) + "An error occurred while trying to save to file %hs\n", &file ) +
"Your emulation state has not been saved!\n\nError: " + ex.Message()).c_str() "Your emulation state has not been saved!\n\nError: " + ex.Message()).c_str()
); );
} }
@ -180,7 +179,7 @@ void States_Save(int num)
// //
void vSyncDebugStuff( uint frame ) void vSyncDebugStuff( uint frame )
{ {
#ifdef PCSX2_DEVBUILD #ifdef OLD_TESTBUILD_STUFF
if( g_TestRun.enabled && g_TestRun.frame > 0 ) { if( g_TestRun.enabled && g_TestRun.frame > 0 ) {
if( frame > g_TestRun.frame ) { if( frame > g_TestRun.frame ) {
// take a snapshot // take a snapshot

View File

@ -20,8 +20,7 @@
#define _PC_ // disables MIPS opcode macros. #define _PC_ // disables MIPS opcode macros.
#include "PsxCommon.h" #include "IopCommon.h"
#include "Common.h"
#include "Sifcmd.h" #include "Sifcmd.h"
using namespace std; using namespace std;

View File

@ -18,7 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "MemoryCard.h" #include "MemoryCard.h"
_sio sio; _sio sio;

View File

@ -37,7 +37,8 @@ using namespace R5900;
FILE *emuLog; FILE *emuLog;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
u32 varLog;
LogSources varLog;
// these used by the depreciated _old_Log only // these used by the depreciated _old_Log only
u16 logProtocol; u16 logProtocol;
@ -67,7 +68,7 @@ void __Log( const char* fmt, ... )
// fixme: should throw an exception here once we have proper exception handling implemented. // fixme: should throw an exception here once we have proper exception handling implemented.
} }
if (varLog & 0x80000000) // log to console enabled? if (varLog.LogToConsole) // log to console enabled?
{ {
Console::Write(tmp); Console::Write(tmp);
@ -105,7 +106,7 @@ static __forceinline void _vSourceLog( u16 protocol, u8 source, u32 cpuPc, u32 c
#endif #endif
#endif #endif
if (varLog & 0x80000000) // log to console enabled? if (varLog.LogToConsole) // log to console enabled?
{ {
Console::WriteLn(tmp); Console::WriteLn(tmp);
@ -145,7 +146,6 @@ IMPLEMENT_SOURCE_LOG( BIOS, 'E', 0 )
IMPLEMENT_SOURCE_LOG( CPU, 'E', 1 ) IMPLEMENT_SOURCE_LOG( CPU, 'E', 1 )
IMPLEMENT_SOURCE_LOG( FPU, 'E', 1 ) IMPLEMENT_SOURCE_LOG( FPU, 'E', 1 )
IMPLEMENT_SOURCE_LOG( MMI, 'E', 1 )
IMPLEMENT_SOURCE_LOG( COP0, 'E', 1 ) IMPLEMENT_SOURCE_LOG( COP0, 'E', 1 )
IMPLEMENT_SOURCE_LOG( MEM, 'E', 6 ) IMPLEMENT_SOURCE_LOG( MEM, 'E', 6 )

View File

@ -20,8 +20,7 @@
#include <time.h> #include <time.h>
#include "Common.h" #include "IopCommon.h"
#include "PsxCommon.h"
#include "Stats.h" #include "Stats.h"
#include "Paths.h" #include "Paths.h"

View File

@ -391,7 +391,7 @@ void SysPrepareExecution( const char* elf_file, bool use_bios )
return; return;
} }
if (OpenPlugins(g_TestRun.ptitle) == -1) if (OpenPlugins(NULL) == -1)
return; return;
if( elf_file == NULL ) if( elf_file == NULL )
@ -401,9 +401,6 @@ void SysPrepareExecution( const char* elf_file, bool use_bios )
// Not recovering a state, so need to execute the bios and load the ELF information. // Not recovering a state, so need to execute the bios and load the ELF information.
// (note: gsRecoveries are done from ExecuteCpu) // (note: gsRecoveries are done from ExecuteCpu)
// if the elf_file is null we use the CDVD elf file.
// But if the elf_file is an empty string then we boot the bios instead.
char ename[g_MaxPath]; char ename[g_MaxPath];
ename[0] = 0; ename[0] = 0;
if( !use_bios ) if( !use_bios )

View File

@ -20,10 +20,12 @@
#define __SYSTEM_H__ #define __SYSTEM_H__
#include "PS2Etypes.h" #include "PS2Etypes.h"
#include "Pcsx2Config.h"
#include "Exceptions.h" #include "Exceptions.h"
#include "Paths.h" #include "Paths.h"
#include "MemcpyFast.h" #include "MemcpyFast.h"
#include "SafeArray.h" #include "SafeArray.h"
#include "Misc.h"
enum PageProtectionMode enum PageProtectionMode

View File

@ -1534,11 +1534,9 @@ static int __fastcall Vif1TransDirectHL(u32 *data){
} }
else else
{ {
FreezeXMMRegs(1); FreezeRegs(1);
FreezeMMXRegs(1);
GSGIFTRANSFER2((u32*)splittransfer[0], 1); GSGIFTRANSFER2((u32*)splittransfer[0], 1);
FreezeMMXRegs(0); FreezeRegs(0);
FreezeXMMRegs(0);
} }
if(vif1.tag.size == 0) vif1.cmd = 0; if(vif1.tag.size == 0) vif1.cmd = 0;
@ -1576,12 +1574,9 @@ static int __fastcall Vif1TransDirectHL(u32 *data){
mtgsThread->SendDataPacket(); mtgsThread->SendDataPacket();
} }
else { else {
FreezeRegs(1);
FreezeXMMRegs(1);
FreezeMMXRegs(1);
GSGIFTRANSFER2(data, (ret >> 2)); GSGIFTRANSFER2(data, (ret >> 2));
FreezeMMXRegs(0); FreezeRegs(0);
FreezeXMMRegs(0);
} }
return ret; return ret;
@ -2128,9 +2123,7 @@ void dmaVIF1()
vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes vif1ch->madr += vif1ch->qwc * 16; // mgs3 scene changes
vif1ch->qwc = 0; vif1ch->qwc = 0;
CPU_INT(1, g_vifCycles); CPU_INT(1, g_vifCycles);
} }
vif1.done = 1; vif1.done = 1;
return; return;
} }

View File

@ -35,12 +35,13 @@ else
DEBUG_FLAGS=" -O0 -g " DEBUG_FLAGS=" -O0 -g "
fi fi
WARNING_FLAGS="-Wall -Wno-format -Wno-unused-value" WARNING_FLAGS="-Wno-format -Wno-unused-value"
NORMAL_FLAGS=" -pipe -msse -msse2 -O2 " EXTRA_WARNING_FLAGS="-Wall -Wextra"
NORMAL_FLAGS=" -pipe -msse -msse2 -O2 ${WARNING_FLAGS}"
# These optimizations seem to cause issues with GCC 4.3.3, so we'll turn them off. # These optimizations seem to cause issues with GCC 4.3.3, so we'll turn them off.
NORMAL_FLAGS+=" -fno-guess-branch-probability -fno-dse -fno-tree-dse " NORMAL_FLAGS+=" -fno-guess-branch-probability -fno-dse -fno-tree-dse "
DEBUG_FLAGS+=" -g -msse -msse2 ${WARNING_FLAGS} " DEBUG_FLAGS+=" -g -msse -msse2 ${EXTRA_WARNING_FLAGS} ${WARNING_FLAGS} "
dnl Check for debug build dnl Check for debug build
AC_MSG_CHECKING(debug build) AC_MSG_CHECKING(debug build)
@ -63,14 +64,14 @@ AC_MSG_RESULT($debug)
AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC)) AC_CHECK_FUNCS([ _aligned_malloc _aligned_free ], AC_DEFINE(HAVE_ALIGNED_MALLOC))
AC_MSG_CHECKING(turn on memcpy_fast_) #AC_MSG_CHECKING(turn on memcpy_fast_)
AC_ARG_ENABLE(memcpyfast, AC_HELP_STRING([--enable-memcpyfast], [Turns on memcpy_fast - EXPERIMENTAL]), #AC_ARG_ENABLE(memcpyfast, AC_HELP_STRING([--enable-memcpyfast], [Turns on memcpy_fast - EXPERIMENTAL]),
memcpyfast=$enableval,memcpyfast=no) #memcpyfast=$enableval,memcpyfast=no)
if test "x$memcpyfast" == xyes #if test "x$memcpyfast" == xyes
then #then
AC_DEFINE(LINUX_USE_FAST_MEMORY,1,[LINUX_USE_FAST_MEMORY]) # AC_DEFINE(LINUX_USE_FAST_MEMORY,1,[LINUX_USE_FAST_MEMORY])
fi #fi
AC_MSG_RESULT($memcpyfast) #AC_MSG_RESULT($memcpyfast)
#AC_MSG_CHECKING(turn on microVU) #AC_MSG_CHECKING(turn on microVU)
#AC_ARG_ENABLE(microVU, AC_HELP_STRING([--enable-microVU], [Turns on the currently incomplete microVU files - Not a good idea]), #AC_ARG_ENABLE(microVU, AC_HELP_STRING([--enable-microVU], [Turns on the currently incomplete microVU files - Not a good idea]),

View File

@ -552,10 +552,7 @@ BOOL APIENTRY DebuggerProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case IDC_DEBUG_LOG: case IDC_DEBUG_LOG:
if( varLog ) varLog.LogToConsole = !varLog.LogToConsole;
varLog &= ~0x80000000;
else
varLog |= 0x80000000;
return TRUE; return TRUE;
#endif #endif

View File

@ -2925,6 +2925,10 @@
RelativePath="..\..\Common.h" RelativePath="..\..\Common.h"
> >
</File> </File>
<File
RelativePath="..\..\IopCommon.h"
>
</File>
<File <File
RelativePath="..\..\Stats.cpp" RelativePath="..\..\Stats.cpp"
> >

View File

@ -27,7 +27,7 @@
#include <windowsx.h> #include <windowsx.h>
#include <tchar.h> #include <tchar.h>
#include "Misc.h" #include "System.h"
#include "HostGui.h" #include "HostGui.h"
#include "resource.h" #include "resource.h"
#include "WinDebugResource.h" #include "WinDebugResource.h"
@ -149,7 +149,6 @@ extern AppData gApp;
extern HWND hStatusWnd; extern HWND hStatusWnd;
extern PcsxConfig winConfig; // local storage of the configuration options. extern PcsxConfig winConfig; // local storage of the configuration options.
extern bool UseGui;
extern bool nDisableSC; // screensaver extern bool nDisableSC; // screensaver
extern unsigned int langsMax; extern unsigned int langsMax;

View File

@ -55,36 +55,26 @@ void strcatz(char *dst, char *src)
strcpy(dst + len, src); strcpy(dst + len, src);
} }
//2002-09-20 (Florin) //2002-09-20 (Florin)
BOOL APIENTRY CmdlineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);//forward def BOOL APIENTRY CmdlineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);//forward def
//------------------- //-------------------
static const char* phelpmsg = static const char* phelpmsg =
"pcsx2 [options] [file]\n\n" "pcsx2 [options] [cdimage/elf file]\n\n"
"-cfg [file] {configuration file}\n" "\t-cfg [file] {configuration file}\n"
"-efile [efile] {0 - reset, 1 - runcd (default), 2 - loadelf}\n" "\t-bootmode [mode] {0 - quick (default), 1 - bios, 2 - load elf}\n"
"-help {display this help file}\n" "\t-nogui {disables display of the gui - skips right to opening the GS window}"
"-nogui {Don't use gui when launching}\n" "\t-help {display this help file}\n"
"-loadgs [file] {Loads a gsstate}\n" "\t-loadgs [file] {Loads a gsstate}\n\n"
"Run without GUI Options:\n"
"\n" "\n"
#ifdef PCSX2_DEVBUILD
"Testing Options: \n"
"\t-frame [frame] {game will run up to this frame before exiting}\n"
"\t-image [name] {path and base name of image (do not include the .ext)}\n"
"\t-jpg {save images to jpg format}\n"
"\t-log [name] {log path to save log file in}\n"
"\t-logopt [hex] {log options in hex (see debug.h) }\n"
"\t-numimages [num] {after hitting frame, this many images will be captures every 20 frames}\n"
"\t-test {Triggers testing mode (only for dev builds)}\n"
"\n"
#endif
"Plugin Overrides (specified dlls will be used in place of configured dlls):\n" "Plugin Overrides (specified dlls will be used in place of configured dlls):\n"
"\t-cdvd [dllpath] {specifies an override for the CDVD plugin}\n" "\t-cdvd [dllpath] {specifies an override for the CDVD plugin}\n"
"\t-gs [dllpath] {specifies an override for the GS plugin}\n" "\t-gs [dllpath] {specifies an override for the GS plugin}\n"
"\t-spu [dllpath] {specifies an override for the SPU2 plugin}\n" "\t-spu [dllpath] {specifies an override for the SPU2 plugin}\n"
"\t-pads [dllpath] {specifies an override for *both* pad plugins}\n" "\t-pad [dllpath] {specifies an override for *both* pad plugins}\n"
"\t-pad1 [dllpath] {specifies an override for the PAD1 plugin only}\n" "\t-pad1 [dllpath] {specifies an override for the PAD1 plugin only}\n"
"\t-pad2 [dllpath] {specifies an override for the PAD2 plugin only}\n" "\t-pad2 [dllpath] {specifies an override for the PAD2 plugin only}\n"
"\t-dev9 [dllpath] {specifies an override for the DEV9 plugin}\n" "\t-dev9 [dllpath] {specifies an override for the DEV9 plugin}\n"
@ -189,21 +179,6 @@ void WinClose()
BOOL SysLoggedSetLockPagesPrivilege ( HANDLE hProcess, BOOL bEnable); BOOL SysLoggedSetLockPagesPrivilege ( HANDLE hProcess, BOOL bEnable);
// Returns TRUE if the test run mode was activated (game was run and has been exited)
static bool TestRunMode()
{
if( IsDevBuild && (g_TestRun.enabled || g_TestRun.ptitle != NULL) )
{
// run without ui
UseGui = false;
PCSX2_MEM_PROTECT_BEGIN();
SysPrepareExecution( g_TestRun.efile ? g_TestRun.ptitle : NULL );
PCSX2_MEM_PROTECT_END();
return true;
}
return false;
}
static void _doPluginOverride( const char* name, const char* src, char (&dest)[g_MaxPath] ) static void _doPluginOverride( const char* name, const char* src, char (&dest)[g_MaxPath] )
{ {
if( src == NULL || src[0] == 0 ) return; if( src == NULL || src[0] == 0 ) return;
@ -219,12 +194,12 @@ void WinRun()
memcpy( &winConfig, &Config, sizeof( PcsxConfig ) ); memcpy( &winConfig, &Config, sizeof( PcsxConfig ) );
_doPluginOverride( "GS", g_TestRun.pgsdll, Config.GS ); _doPluginOverride( "GS", g_Startup.gsdll, Config.GS );
_doPluginOverride( "CDVD", g_TestRun.pcdvddll, Config.CDVD ); _doPluginOverride( "CDVD", g_Startup.cdvddll, Config.CDVD );
_doPluginOverride( "SPU2", g_TestRun.pspudll, Config.SPU2 ); _doPluginOverride( "SPU2", g_Startup.spudll, Config.SPU2 );
_doPluginOverride( "PAD1", g_TestRun.ppad1dll, Config.PAD1 ); _doPluginOverride( "PAD1", g_Startup.pad1dll, Config.PAD1 );
_doPluginOverride( "PAD2", g_TestRun.ppad2dll, Config.PAD2 ); _doPluginOverride( "PAD2", g_Startup.pad2dll, Config.PAD2 );
_doPluginOverride( "DEV9", g_TestRun.pdev9dll, Config.DEV9 ); _doPluginOverride( "DEV9", g_Startup.dev9dll, Config.DEV9 );
#ifndef _DEBUG #ifndef _DEBUG
@ -239,8 +214,6 @@ void WinRun()
if (Pcsx2Configure(NULL) == FALSE) return; if (Pcsx2Configure(NULL) == FALSE) return;
} }
if( TestRunMode() ) return;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if( g_pRunGSState ) { if( g_pRunGSState ) {
LoadGSState(g_pRunGSState); LoadGSState(g_pRunGSState);
@ -294,8 +267,6 @@ void WinRun()
textdomain(PACKAGE); textdomain(PACKAGE);
#endif #endif
memzero_obj(g_TestRun);
_getcwd( g_WorkingFolder, g_MaxPath ); _getcwd( g_WorkingFolder, g_MaxPath );
int argc; int argc;
@ -303,7 +274,7 @@ void WinRun()
if( argv == NULL ) if( argv == NULL )
{ {
Msgbox::Alert( "A fatal error occured while attempting to parse the command line.\n" ); Msgbox::Alert( "A fatal error occurred while attempting to parse the command line.\n" );
return 2; return 2;
} }
@ -396,6 +367,23 @@ void RunGui()
LoadPatch( str_Default ); LoadPatch( str_Default );
if( g_Startup.NoGui || g_Startup.Enabled )
{
// Initially bypass GUI and start PCSX2 directly.
// Manually load plugins using the user's configured image (if non-elf).
if( g_Startup.Enabled && (g_Startup.BootMode != BootMode_Elf) )
{
if (OpenPlugins(g_Startup.ImageName) == -1)
return;
}
SysPrepareExecution(
(g_Startup.BootMode == BootMode_Elf) ? g_Startup.ImageName : NULL,
(g_Startup.BootMode == BootMode_Bios)
);
}
do do
{ {
CreateMainWindow(); CreateMainWindow();
@ -501,22 +489,26 @@ BOOL APIENTRY CmdlineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
BOOL APIENTRY LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { BOOL APIENTRY LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
int i; int i;
// Note: varLog layout has been changed, so this code won't be applicable to the new wx version
// of this dialog box.
switch (message) { switch (message) {
case WM_INITDIALOG: case WM_INITDIALOG:
for (i=0; i<32; i++) //for (i=0; i<32; i++)
if (varLog & (1<<i)) // if (varLog & (1<<i))
CheckDlgButton(hDlg, IDC_CPULOG+i, TRUE); // CheckDlgButton(hDlg, IDC_CPULOG+i, TRUE);
return TRUE; return TRUE;
case WM_COMMAND: case WM_COMMAND:
if (LOWORD(wParam) == IDOK) { if (LOWORD(wParam) == IDOK) {
for (i=0; i<32; i++) { //for (i=0; i<32; i++) {
int ret = Button_GetCheck(GetDlgItem(hDlg, IDC_CPULOG+i)); // int ret = Button_GetCheck(GetDlgItem(hDlg, IDC_CPULOG+i));
if (ret) varLog|= 1<<i; // if (ret) varLog|= 1<<i;
else varLog&=~(1<<i); // else varLog&=~(1<<i);
} //}
SaveConfig(); SaveConfig();

View File

@ -25,7 +25,6 @@
#include "iR5900.h" #include "iR5900.h"
static bool sinit = false; static bool sinit = false;
bool UseGui = true;
bool nDisableSC = false; // screensaver bool nDisableSC = false; // screensaver
// This instance is not modified by command line overrides so // This instance is not modified by command line overrides so
@ -67,7 +66,7 @@ int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
int ParseCommandLine( int tokenCount, TCHAR *const *const tokens ) int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
{ {
int tidx = 0; int tidx = 0;
g_TestRun.efile = 0; g_Startup.BootMode = BootMode_Bios;
while( tidx < tokenCount ) while( tidx < tokenCount )
{ {
@ -75,8 +74,8 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
if( command[0] != '-' ) if( command[0] != '-' )
{ {
g_TestRun.ptitle = command; g_Startup.ImageName = command;
printf("opening file %s\n", command); g_Startup.Enabled = true;
continue; continue;
} }
@ -89,16 +88,11 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
return -1; return -1;
} }
else if( CmdSwitchIs( "nogui" ) ) { else if( CmdSwitchIs( "nogui" ) ) {
UseGui = false; g_Startup.NoGui = true;
} }
else if( CmdSwitchIs( "highpriority" ) ) { else if( CmdSwitchIs( "highpriority" ) ) {
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
} }
#ifdef PCSX2_DEVBUILD
else if( CmdSwitchIs( "jpg" ) ) {
g_TestRun.jpgcapture = 1;
}
#endif
else else
{ {
const TCHAR* param; const TCHAR* param;
@ -112,9 +106,9 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
if( CmdSwitchIs( "cfg" ) ) { if( CmdSwitchIs( "cfg" ) ) {
g_CustomConfigFile = param; g_CustomConfigFile = param;
} }
else if( CmdSwitchIs( "bootmode" ) ) {
else if( CmdSwitchIs( "efile" ) ) { g_Startup.BootMode = (StartupMode)atoi( param );
g_TestRun.efile = !!atoi( param ); g_Startup.Enabled = true;
} }
else if( CmdSwitchIs( "loadgs" ) ) { else if( CmdSwitchIs( "loadgs" ) ) {
g_pRunGSState = param; g_pRunGSState = param;
@ -123,46 +117,28 @@ int ParseCommandLine( int tokenCount, TCHAR *const *const tokens )
// Options to configure plugins: // Options to configure plugins:
else if( CmdSwitchIs( "gs" ) ) { else if( CmdSwitchIs( "gs" ) ) {
g_TestRun.pgsdll = param; g_Startup.gsdll = param;
} }
else if( CmdSwitchIs( "cdvd" ) ) { else if( CmdSwitchIs( "cdvd" ) ) {
g_TestRun.pcdvddll = param; g_Startup.cdvddll = param;
} }
else if( CmdSwitchIs( "spu" ) ) { else if( CmdSwitchIs( "spu" ) ) {
g_TestRun.pspudll = param; g_Startup.spudll = param;
} }
else if( CmdSwitchIs( "pads" ) ) { else if( CmdSwitchIs( "pad" ) ) {
g_TestRun.ppad1dll = param; g_Startup.pad1dll = param;
g_TestRun.ppad2dll = param; g_Startup.pad2dll = param;
} }
else if( CmdSwitchIs( "pad1" ) ) { else if( CmdSwitchIs( "pad1" ) ) {
g_TestRun.ppad1dll = param; g_Startup.pad1dll = param;
} }
else if( CmdSwitchIs( "pad2" ) ) { else if( CmdSwitchIs( "pad2" ) ) {
g_TestRun.ppad2dll = param; g_Startup.pad2dll = param;
} }
else if( CmdSwitchIs( "dev9" ) ) { else if( CmdSwitchIs( "dev9" ) ) {
g_TestRun.pdev9dll = param; g_Startup.dev9dll = param;
} }
#ifdef PCSX2_DEVBUILD
else if( CmdSwitchIs( "image" ) ) {
g_TestRun.pimagename = param;
}
else if( CmdSwitchIs( "log" ) ) {
g_TestRun.plogname = param;
}
else if( CmdSwitchIs( "logopt" ) ) {
if( param[0] == '0' && param[1] == 'x' ) param += 2;
sscanf(param, "%x", &varLog);
}
else if( CmdSwitchIs( "frame" ) ) {
g_TestRun.frame = atoi( param );
}
else if( CmdSwitchIs( "numimages" ) ) {
g_TestRun.numimages = atoi( param );
}
#endif
} }
} }
return 0; return 0;
@ -259,9 +235,10 @@ bool HostGuiInit()
NTFS_CompressFile( MEMCARDS_DIR, Config.McdEnableNTFS ); NTFS_CompressFile( MEMCARDS_DIR, Config.McdEnableNTFS );
#ifdef OLD_TESTBUILD_STUFF
if( IsDevBuild && emuLog == NULL && g_TestRun.plogname != NULL ) if( IsDevBuild && emuLog == NULL && g_TestRun.plogname != NULL )
emuLog = fopen(g_TestRun.plogname, "w"); emuLog = fopen(g_TestRun.plogname, "w");
#endif
if( emuLog == NULL ) if( emuLog == NULL )
emuLog = fopen(LOGS_DIR "\\emuLog.txt","w"); emuLog = fopen(LOGS_DIR "\\emuLog.txt","w");
@ -464,11 +441,6 @@ namespace HostGui
} }
else else
{ {
if( !UseGui ) {
// not using GUI and user just quit, so exit
WinClose();
}
nDisableSC = 0; nDisableSC = 0;
} }

View File

@ -177,8 +177,9 @@ void IniFile::DoConfig( PcsxConfig& Conf )
Entry( "Patching", Conf.Patch, false ); Entry( "Patching", Conf.Patch, false );
Entry( "GameFixes", Conf.GameFixes); Entry( "GameFixes", Conf.GameFixes);
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
Entry( "DevLogFlags", varLog ); Entry( "DevLogFlags", (uint&)varLog );
#endif #endif
//interface //interface

View File

@ -44,11 +44,11 @@
memcmp_mmx: memcmp_mmx:
// make sure mmx regs are stored // make sure mmx regs are stored
// FreezeMMXRegs(1); // FreezeMMXRegs(1);
cmp dword ptr [g_EEFreezeRegs], 0 //cmp dword ptr [g_EEFreezeRegs], 0
je memcmp_mmx_begin //je memcmp_mmx_begin
push 1 //push 1
call FreezeMMXRegs_ //call FreezeMMXRegs_
add esp, 4 //add esp, 4
memcmp_mmx_begin: memcmp_mmx_begin:
push esi push esi
@ -381,7 +381,7 @@ $memcpy_align_done: // destination is dword aligned
shr eax, 6 // get 64-byte block count shr eax, 6 // get 64-byte block count
jz $memcpy_ic_2 // finish the last few bytes jz $memcpy_ic_2 // finish the last few bytes
mov edx, offset _mmx_backup ; will probably need this to save/restore mmx mov edx, offset _mmx_backup // will probably need this to save/restore mmx
cmp eax, IN_CACHE_COPY/64 // too big 4 cache? use uncached copy cmp eax, IN_CACHE_COPY/64 // too big 4 cache? use uncached copy
jae $memcpy_uc_test jae $memcpy_uc_test

View File

@ -128,16 +128,21 @@ void recMFC0( void )
{ {
int mmreg; int mmreg;
if ( ! _Rt_ ) return; if( _Rd_ == 9 )
{
if( _Rd_ == 9 ) { // This case needs to be handled even if the write-back is ignored (_Rt_ == 0 )
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle); MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
MOV32RtoR(EAX,ECX); MOV32RtoR(EAX, ECX);
SUB32MtoR(EAX, (uptr)&s_iLastCOP0Cycle); SUB32MtoR(EAX, (uptr)&s_iLastCOP0Cycle);
u8* skipInc = JNZ8( 0 );
INC32R(EAX);
x86SetJ8( skipInc );
ADD32RtoM((uptr)&cpuRegs.CP0.n.Count, EAX); ADD32RtoM((uptr)&cpuRegs.CP0.n.Count, EAX);
MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX); MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX);
MOV32MtoR( EAX, (uptr)&cpuRegs.CP0.r[ _Rd_ ] ); MOV32MtoR( EAX, (uptr)&cpuRegs.CP0.r[ _Rd_ ] );
if( !_Rt_ ) return;
_deleteEEreg(_Rt_, 0); _deleteEEreg(_Rt_, 0);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX); MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
@ -148,52 +153,24 @@ void recMFC0( void )
else EEINST_RESETHASLIVE1(_Rt_); else EEINST_RESETHASLIVE1(_Rt_);
return; return;
} }
if( _Rd_ == 25 ) {
if ( !_Rt_ ) return;
_deleteEEreg(_Rt_, 0);
switch(_Imm_ & 0x3F){ if( _Rd_ == 25 )
{
switch(_Imm_ & 0x3F)
{
case 0: case 0:
MOV32MtoR(EAX, (uptr)&cpuRegs.PERF.n.pccr); MOV32MtoR(EAX, (uptr)&cpuRegs.PERF.n.pccr);
break;
break;
case 1: case 1:
// check if needs to be incremented
MOV32MtoR(ECX, (uptr)&cpuRegs.PERF.n.pccr);
MOV32MtoR(EAX, (uptr)&cpuRegs.PERF.n.pcr0);
AND32ItoR(ECX, 0x800003E0);
CMP32ItoR(ECX, 0x80000020);
j8Ptr[0] = JNE8(0);
MOV32MtoR(EDX, (uptr)&cpuRegs.cycle);
SUB32MtoR(EAX, (uptr)&s_iLastPERFCycle[0]);
ADD32RtoR(EAX, EDX);
MOV32RtoM((uptr)&s_iLastPERFCycle[0], EDX);
MOV32RtoM((uptr)&cpuRegs.PERF.n.pcr0, EAX);
x86SetJ8(j8Ptr[0]);
break;
case 3: case 3:
// check if needs to be incremented CALLFunc( (uptr)COP0_UpdatePCCR );
MOV32MtoR(ECX, (uptr)&cpuRegs.PERF.n.pccr); break;
MOV32MtoR(EAX, (uptr)&cpuRegs.PERF.n.pcr1);
AND32ItoR(ECX, 0x800F8000);
CMP32ItoR(ECX, 0x80008000);
j8Ptr[0] = JNE8(0);
MOV32MtoR(EDX, (uptr)&cpuRegs.cycle);
SUB32MtoR(EAX, (uptr)&s_iLastPERFCycle[1]);
ADD32RtoR(EAX, EDX);
MOV32RtoM((uptr)&s_iLastPERFCycle[1], EDX);
MOV32RtoM((uptr)&cpuRegs.PERF.n.pcr1, EAX);
x86SetJ8(j8Ptr[0]);
break;
} }
_deleteEEreg(_Rt_, 0);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX); MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
if(EEINST_ISLIVE1(_Rt_)) { if(EEINST_ISLIVE1(_Rt_)) {
CDQ(); CDQ();
@ -201,10 +178,6 @@ void recMFC0( void )
} }
else EEINST_RESETHASLIVE1(_Rt_); else EEINST_RESETHASLIVE1(_Rt_);
#ifdef PCSX2_DEVBUILD
COP0_LOG("MFC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n",
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);
#endif
return; return;
} }
else if( _Rd_ == 24){ else if( _Rd_ == 24){
@ -257,119 +230,102 @@ void recMFC0( void )
} }
} }
void updatePCCR()
{
// read the old pccr and update pcr0/1
MOV32MtoR(EAX, (uptr)&cpuRegs.PERF.n.pccr);
MOV32RtoR(EDX, EAX);
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
AND32ItoR(EAX, 0x800003E0);
CMP32ItoR(EAX, 0x80000020);
j8Ptr[0] = JNE8(0);
MOV32MtoR(EAX, (uptr)&s_iLastPERFCycle[0]);
ADD32RtoM((uptr)&cpuRegs.PERF.n.pcr0, ECX);
SUB32RtoM((uptr)&cpuRegs.PERF.n.pcr0, EAX);
x86SetJ8(j8Ptr[0]);
AND32ItoR(EDX, 0x800F8000);
CMP32ItoR(EDX, 0x80008000);
j8Ptr[0] = JNE8(0);
MOV32MtoR(EAX, (uptr)&s_iLastPERFCycle[1]);
ADD32RtoM((uptr)&cpuRegs.PERF.n.pcr1, ECX);
SUB32RtoM((uptr)&cpuRegs.PERF.n.pcr1, EAX);
x86SetJ8(j8Ptr[0]);
}
void recMTC0() void recMTC0()
{ {
if( GPR_IS_CONST1(_Rt_) ) { if( GPR_IS_CONST1(_Rt_) )
switch (_Rd_) { {
switch (_Rd_)
{
case 12: case 12:
iFlushCall(FLUSH_NODESTROY); iFlushCall(FLUSH_NODESTROY);
//_flushCachedRegs(); //NOTE: necessary? //_flushCachedRegs(); //NOTE: necessary?
_callFunctionArg1((uptr)WriteCP0Status, MEM_CONSTTAG, g_cpuConstRegs[_Rt_].UL[0]); _callFunctionArg1((uptr)WriteCP0Status, MEM_CONSTTAG, g_cpuConstRegs[_Rt_].UL[0]);
break; break;
case 9: case 9:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle); MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX); MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX);
MOV32ItoM((uptr)&cpuRegs.CP0.r[9], g_cpuConstRegs[_Rt_].UL[0]); MOV32ItoM((uptr)&cpuRegs.CP0.r[9], g_cpuConstRegs[_Rt_].UL[0]);
break; break;
case 25:
COP0_LOG("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n", case 25:
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F); switch(_Imm_ & 0x3F)
switch(_Imm_ & 0x3F){ {
case 0: case 0:
CALLFunc( (uptr)COP0_UpdatePCCR );
updatePCCR(); MOV32ItoM((uptr)&cpuRegs.PERF.n.pccr, g_cpuConstRegs[_Rt_].UL[0]);
MOV32ItoM((uptr)&cpuRegs.PERF.n.pccr, g_cpuConstRegs[_Rt_].UL[0]); CALLFunc( (uptr)COP0_DiagnosticPCCR );
break;
// update the cycles
MOV32RtoM((uptr)&s_iLastPERFCycle[0], ECX);
MOV32RtoM((uptr)&s_iLastPERFCycle[1], ECX);
break;
case 1: case 1:
MOV32MtoR(EAX, (uptr)&cpuRegs.cycle); MOV32MtoR(EAX, (uptr)&cpuRegs.cycle);
MOV32ItoM((uptr)&cpuRegs.PERF.n.pcr0, g_cpuConstRegs[_Rt_].UL[0]); MOV32ItoM((uptr)&cpuRegs.PERF.n.pcr0, g_cpuConstRegs[_Rt_].UL[0]);
MOV32RtoM((uptr)&s_iLastPERFCycle[0], EAX); MOV32RtoM((uptr)&s_iLastPERFCycle[0], EAX);
break; break;
case 3: case 3:
MOV32MtoR(EAX, (uptr)&cpuRegs.cycle); MOV32MtoR(EAX, (uptr)&cpuRegs.cycle);
MOV32ItoM((uptr)&cpuRegs.PERF.n.pcr1, g_cpuConstRegs[_Rt_].UL[0]); MOV32ItoM((uptr)&cpuRegs.PERF.n.pcr1, g_cpuConstRegs[_Rt_].UL[0]);
MOV32RtoM((uptr)&s_iLastPERFCycle[1], EAX); MOV32RtoM((uptr)&s_iLastPERFCycle[1], EAX);
break; break;
} }
break; break;
case 24: case 24:
COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF);
break; break;
default: default:
MOV32ItoM((uptr)&cpuRegs.CP0.r[_Rd_], g_cpuConstRegs[_Rt_].UL[0]); MOV32ItoM((uptr)&cpuRegs.CP0.r[_Rd_], g_cpuConstRegs[_Rt_].UL[0]);
break; break;
} }
} }
else { else
switch (_Rd_) { {
switch (_Rd_)
{
case 12: case 12:
iFlushCall(FLUSH_NODESTROY); iFlushCall(FLUSH_NODESTROY);
//_flushCachedRegs(); //NOTE: necessary? //_flushCachedRegs(); //NOTE: necessary?
_callFunctionArg1((uptr)WriteCP0Status, MEM_GPRTAG|_Rt_, 0); _callFunctionArg1((uptr)WriteCP0Status, MEM_GPRTAG|_Rt_, 0);
break; break;
case 9: case 9:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle); MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
_eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[9], _Rt_); _eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[9], _Rt_);
MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX); MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX);
break; break;
case 25:
COP0_LOG("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n", case 25:
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F); switch(_Imm_ & 0x3F)
switch(_Imm_ & 0x3F){ {
case 0: case 0:
updatePCCR(); CALLFunc( (uptr)COP0_UpdatePCCR );
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_); _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_);
CALLFunc( (uptr)COP0_DiagnosticPCCR );
break;
// update the cycles
MOV32RtoM((uptr)&s_iLastPERFCycle[0], ECX);
MOV32RtoM((uptr)&s_iLastPERFCycle[1], ECX);
break;
case 1: case 1:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle); MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr0, _Rt_); _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr0, _Rt_);
MOV32RtoM((uptr)&s_iLastPERFCycle[0], ECX); MOV32RtoM((uptr)&s_iLastPERFCycle[0], ECX);
break; break;
case 3: case 3:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle); MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr1, _Rt_); _eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr1, _Rt_);
MOV32RtoM((uptr)&s_iLastPERFCycle[1], ECX); MOV32RtoM((uptr)&s_iLastPERFCycle[1], ECX);
break; break;
} }
break; break;
case 24: case 24:
COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF);
break; break;
default: default:
_eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[_Rd_], _Rt_); _eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[_Rd_], _Rt_);
break; break;
} }
} }
} }

View File

@ -324,6 +324,7 @@ void SetFPUstate();
#define MMX_TEMP 0x7f #define MMX_TEMP 0x7f
#define MMX_IS32BITS(x) (((x)>=MMX_FPU&&(x)<MMX_COP0+32)||(x)==MMX_FPUACC) #define MMX_IS32BITS(x) (((x)>=MMX_FPU&&(x)<MMX_COP0+32)||(x)==MMX_FPUACC)
// If x is unsigned, the first part of this is always true, and it usually is.
#define MMX_ISGPR(x) ((x) >= MMX_GPR && (x) < MMX_GPR+34) #define MMX_ISGPR(x) ((x) >= MMX_GPR && (x) < MMX_GPR+34)
struct _mmxregs { struct _mmxregs {

View File

@ -25,17 +25,19 @@
#include "iFPU.h" #include "iFPU.h"
/* Version of the FPU that emulates an exponent of 0xff and overflow/underflow flags */ /* Version of the FPU that emulates an exponent of 0xff and overflow/underflow flags */
/* Can be made faster by not converting stuff back and forth between instructions. */
//set overflow flag (set only if FPU_RESULT is 1) //set overflow flag (set only if FPU_RESULT is 1)
#define FPU_FLAGS_OVERFLOW 1 #define FPU_FLAGS_OVERFLOW 1
//set underflow flag (set only if FPU_RESULT is 1) //set underflow flag (set only if FPU_RESULT is 1)
#define FPU_FLAGS_UNDERFLOW 1 #define FPU_FLAGS_UNDERFLOW 1
//if 1, result is not clamped (MORE correct, //if 1, result is not clamped (Gives correct results as in PS2,
//but can cause problems due to insuffecient clamping levels in the VUs) //but can cause problems due to insuffecient clamping levels in the VUs)
#define FPU_RESULT 1 #define FPU_RESULT 1
//also impacts other aspects of DIV/R/SQRT correctness //set I&D flags. also impacts other aspects of DIV/R/SQRT correctness
#define FPU_FLAGS_ID 1 #define FPU_FLAGS_ID 1
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -126,270 +128,8 @@ static u32 PCSX2_ALIGNED16(s_pos[4]) = { 0x7fffffff, 0xffffffff, 0xffffffff, 0xf
//------------------------------------------------------------------ //------------------------------------------------------------------
// *FPU Opcodes!* // *FPU Opcodes!*
//------------------------------------------------------------------ //------------------------------------------------------------------
//------------------------------------------------------------------
// CFC1 / CTC1
//------------------------------------------------------------------
void recCFC1(void)
{
if ( !_Rt_ || ( (_Fs_ != 0) && (_Fs_ != 31) ) ) return;
_eeOnWriteReg(_Rt_, 1);
MOV32MtoR( EAX, (uptr)&fpuRegs.fprc[ _Fs_ ] );
_deleteEEreg(_Rt_, 0);
if (_Fs_ == 31)
{
AND32ItoR(EAX, 0x0083c078); //remove always-zero bits
OR32ItoR(EAX, 0x01000001); //set always-one bits
}
if(EEINST_ISLIVE1(_Rt_))
{
CDQ( );
MOV32RtoM( (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
MOV32RtoM( (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
}
else
{
EEINST_RESETHASLIVE1(_Rt_);
MOV32RtoM( (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
}
}
void recCTC1( void )
{
if ( _Fs_ != 31 ) return;
if ( GPR_IS_CONST1(_Rt_) )
{
MOV32ItoM((uptr)&fpuRegs.fprc[ _Fs_ ], g_cpuConstRegs[_Rt_].UL[0]);
}
else
{
int mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
if( mmreg >= 0 )
{
SSEX_MOVD_XMM_to_M32((uptr)&fpuRegs.fprc[ _Fs_ ], mmreg);
}
else
{
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_READ);
if ( mmreg >= 0 )
{
MOVDMMXtoM((uptr)&fpuRegs.fprc[ _Fs_ ], mmreg);
SetMMXstate();
}
else
{
_deleteGPRtoXMMreg(_Rt_, 1);
_deleteMMXreg(MMX_GPR+_Rt_, 1);
MOV32MtoR( EAX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
MOV32RtoM( (uptr)&fpuRegs.fprc[ _Fs_ ], EAX );
}
}
}
}
//------------------------------------------------------------------
//------------------------------------------------------------------
// MFC1
//------------------------------------------------------------------
void recMFC1(void)
{
int regt, regs;
if ( ! _Rt_ ) return;
_eeOnWriteReg(_Rt_, 1);
regs = _checkXMMreg(XMMTYPE_FPREG, _Fs_, MODE_READ);
if( regs >= 0 )
{
_deleteGPRtoXMMreg(_Rt_, 2);
regt = _allocCheckGPRtoMMX(g_pCurInstInfo, _Rt_, MODE_WRITE);
if( regt >= 0 )
{
SSE2_MOVDQ2Q_XMM_to_MM(regt, regs);
if(EEINST_ISLIVE1(_Rt_))
_signExtendGPRtoMMX(regt, _Rt_, 0);
else
EEINST_RESETHASLIVE1(_Rt_);
}
else
{
if(EEINST_ISLIVE1(_Rt_))
{
_signExtendXMMtoM((uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], regs, 0);
}
else
{
EEINST_RESETHASLIVE1(_Rt_);
SSE_MOVSS_XMM_to_M32((uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], regs);
}
}
}
else
{
regs = _checkMMXreg(MMX_FPU+_Fs_, MODE_READ);
if( regs >= 0 )
{
// convert to mmx reg
mmxregs[regs].reg = MMX_GPR+_Rt_;
mmxregs[regs].mode |= MODE_READ|MODE_WRITE;
_signExtendGPRtoMMX(regs, _Rt_, 0);
}
else
{
regt = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
if( regt >= 0 )
{
if( xmmregs[regt].mode & MODE_WRITE )
{
SSE_MOVHPS_XMM_to_M64((uptr)&cpuRegs.GPR.r[_Rt_].UL[2], regt);
}
xmmregs[regt].inuse = 0;
}
_deleteEEreg(_Rt_, 0);
MOV32MtoR( EAX, (uptr)&fpuRegs.fpr[ _Fs_ ].UL );
if(EEINST_ISLIVE1(_Rt_))
{
CDQ( );
MOV32RtoM( (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
MOV32RtoM( (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
}
else
{
EEINST_RESETHASLIVE1(_Rt_);
MOV32RtoM( (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
}
}
}
}
//------------------------------------------------------------------
//------------------------------------------------------------------
// MTC1
//------------------------------------------------------------------
void recMTC1(void)
{
if( GPR_IS_CONST1(_Rt_) )
{
_deleteFPtoXMMreg(_Fs_, 0);
MOV32ItoM((uptr)&fpuRegs.fpr[ _Fs_ ].UL, g_cpuConstRegs[_Rt_].UL[0]);
}
else
{
int mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rt_, MODE_READ);
if( mmreg >= 0 )
{
if( g_pCurInstInfo->regs[_Rt_] & EEINST_LASTUSE )
{
// transfer the reg directly
_deleteGPRtoXMMreg(_Rt_, 2);
_deleteFPtoXMMreg(_Fs_, 2);
_allocFPtoXMMreg(mmreg, _Fs_, MODE_WRITE);
}
else
{
int mmreg2 = _allocCheckFPUtoXMM(g_pCurInstInfo, _Fs_, MODE_WRITE);
if( mmreg2 >= 0 )
SSE_MOVSS_XMM_to_XMM(mmreg2, mmreg);
else
SSE_MOVSS_XMM_to_M32((uptr)&fpuRegs.fpr[ _Fs_ ].UL, mmreg);
}
}
else
{
int mmreg2;
mmreg = _checkMMXreg(MMX_GPR+_Rt_, MODE_READ);
mmreg2 = _allocCheckFPUtoXMM(g_pCurInstInfo, _Fs_, MODE_WRITE);
if( mmreg >= 0 )
{
if( mmreg2 >= 0 )
{
SetMMXstate();
SSE2_MOVQ2DQ_MM_to_XMM(mmreg2, mmreg);
}
else
{
SetMMXstate();
MOVDMMXtoM((uptr)&fpuRegs.fpr[ _Fs_ ].UL, mmreg);
}
}
else
{
if( mmreg2 >= 0 )
{
SSE_MOVSS_M32_to_XMM(mmreg2, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
}
else
{
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
MOV32RtoM((uptr)&fpuRegs.fpr[ _Fs_ ].UL, EAX);
}
}
}
}
}
//------------------------------------------------------------------
/*#ifndef FPU_RECOMPILE // If FPU_RECOMPILE is not defined, then use the interpreter opcodes. (CFC1, CTC1, MFC1, and MTC1 are special because they work specifically with the EE rec so they're defined above)
REC_FPUFUNC(ABS_S);
REC_FPUFUNC(ADD_S);
REC_FPUFUNC(ADDA_S);
REC_FPUBRANCH(BC1F);
REC_FPUBRANCH(BC1T);
REC_FPUBRANCH(BC1FL);
REC_FPUBRANCH(BC1TL);
REC_FPUFUNC(C_EQ);
REC_FPUFUNC(C_F);
REC_FPUFUNC(C_LE);
REC_FPUFUNC(C_LT);
REC_FPUFUNC(CVT_S);
REC_FPUFUNC(CVT_W);
REC_FPUFUNC(DIV_S);
REC_FPUFUNC(MAX_S);
REC_FPUFUNC(MIN_S);
REC_FPUFUNC(MADD_S);
REC_FPUFUNC(MADDA_S);
REC_FPUFUNC(MOV_S);
REC_FPUFUNC(MSUB_S);
REC_FPUFUNC(MSUBA_S);
REC_FPUFUNC(MUL_S);
REC_FPUFUNC(MULA_S);
REC_FPUFUNC(NEG_S);
REC_FPUFUNC(SUB_S);
REC_FPUFUNC(SUBA_S);
REC_FPUFUNC(SQRT_S);
REC_FPUFUNC(RSQRT_S);
#else // FPU_RECOMPILE*/
//------------------------------------------------------------------ //------------------------------------------------------------------
// PS2 -> DOUBLE // PS2 -> DOUBLE
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -678,7 +418,7 @@ void FPU_MUL(int info, int regd, int sreg, int treg, bool acc)
// CommutativeOp XMM (used for ADD, MUL, MAX, MIN and SUB opcodes) // CommutativeOp XMM (used for ADD, MUL, MAX, MIN and SUB opcodes)
//------------------------------------------------------------------ //------------------------------------------------------------------
static void (*recFPUOpXMM_to_XMM[] )(x86SSERegType, x86SSERegType) = { static void (*recFPUOpXMM_to_XMM[] )(x86SSERegType, x86SSERegType) = {
SSE2_ADDSD_XMM_to_XMM, NULL, SSE2_MAXSD_XMM_to_XMM, SSE2_MINSD_XMM_to_XMM, SSE2_SUBSD_XMM_to_XMM }; SSE2_ADDSD_XMM_to_XMM, NULL, NULL, NULL, SSE2_SUBSD_XMM_to_XMM };
void recFPUOp(int info, int regd, int op, bool acc) void recFPUOp(int info, int regd, int op, bool acc)
{ {
@ -718,48 +458,6 @@ void recADDA_S_xmm(int info)
FPURECOMPILE_CONSTCODE(ADDA_S, XMMINFO_WRITEACC|XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(ADDA_S, XMMINFO_WRITEACC|XMMINFO_READS|XMMINFO_READT);
//------------------------------------------------------------------ //------------------------------------------------------------------
//------------------------------------------------------------------
// BC1x XMM
//------------------------------------------------------------------
/*
static void _setupBranchTest()
{
_eeFlushAllUnused();
// COP1 branch conditionals are based on the following equation:
// (fpuRegs.fprc[31] & 0x00800000)
// BC2F checks if the statement is false, BC2T checks if the statement is true.
MOV32MtoR(EAX, (uptr)&fpuRegs.fprc[31]);
TEST32ItoR(EAX, FPUflagC);
}
void recBC1F( void )
{
_setupBranchTest();
recDoBranchImm(JNZ32(0));
}
void recBC1T( void )
{
_setupBranchTest();
recDoBranchImm(JZ32(0));
}
void recBC1FL( void )
{
_setupBranchTest();
recDoBranchImm_Likely(JNZ32(0));
}
void recBC1TL( void )
{
_setupBranchTest();
recDoBranchImm_Likely(JZ32(0));
}*/
//------------------------------------------------------------------
//TOKNOW : how does C.??.S behave with denormals?
void recCMP(int info) void recCMP(int info)
{ {
int sreg, treg; int sreg, treg;
@ -787,12 +485,7 @@ void recC_EQ_xmm(int info)
} }
FPURECOMPILE_CONSTCODE(C_EQ, XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(C_EQ, XMMINFO_READS|XMMINFO_READT);
/*void recC_F()
{
AND32ItoM( (uptr)&fpuRegs.fprc[31], ~FPUflagC );
}*/
void recC_LE_xmm(int info ) void recC_LE_xmm(int info )
{ {
recCMP(info); recCMP(info);
@ -806,7 +499,6 @@ void recC_LE_xmm(int info )
} }
FPURECOMPILE_CONSTCODE(C_LE, XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(C_LE, XMMINFO_READS|XMMINFO_READT);
//REC_FPUFUNC(C_LE);
void recC_LT_xmm(int info) void recC_LT_xmm(int info)
{ {
@ -821,7 +513,6 @@ void recC_LT_xmm(int info)
} }
FPURECOMPILE_CONSTCODE(C_LT, XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(C_LT, XMMINFO_READS|XMMINFO_READT);
//REC_FPUFUNC(C_LT);
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -840,7 +531,7 @@ void recCVT_S_xmm(int info)
FPURECOMPILE_CONSTCODE(CVT_S, XMMINFO_WRITED|XMMINFO_READS); FPURECOMPILE_CONSTCODE(CVT_S, XMMINFO_WRITED|XMMINFO_READS);
void recCVT_W() void recCVT_W() //called from iFPU.cpp's recCVT_W
{ {
int regs = _checkXMMreg(XMMTYPE_FPREG, _Fs_, MODE_READ); int regs = _checkXMMreg(XMMTYPE_FPREG, _Fs_, MODE_READ);
@ -1052,17 +743,42 @@ FPURECOMPILE_CONSTCODE(MADDA_S, XMMINFO_WRITEACC|XMMINFO_READACC|XMMINFO_READS|X
// MAX / MIN XMM // MAX / MIN XMM
//------------------------------------------------------------------ //------------------------------------------------------------------
//TOKNOW : handles denormals like VU, maybe? static const u32 PCSX2_ALIGNED16(minmax_mask[4]) = {0xffffffff, 0x80000000, 0, 0};
static const u32 PCSX2_ALIGNED16(minmax_mask2[4]) = {0, 0x40000000, 0, 0};
// FPU's MAX/MIN work with all numbers (including "denormals"). Check VU's logical min max for more info.
void recMINMAX(int info, bool ismin)
{
int sreg, treg;
ALLOC_S(sreg); ALLOC_T(treg);
CLEAR_OU_FLAGS;
SSE2_PSHUFD_XMM_to_XMM(sreg, sreg, 0x00);
SSE2_PAND_M128_to_XMM(sreg, (uptr)minmax_mask);
SSE2_POR_M128_to_XMM(sreg, (uptr)minmax_mask2);
SSE2_PSHUFD_XMM_to_XMM(treg, treg, 0x00);
SSE2_PAND_M128_to_XMM(treg, (uptr)minmax_mask);
SSE2_POR_M128_to_XMM(treg, (uptr)minmax_mask2);
if (ismin)
SSE2_MINSD_XMM_to_XMM(sreg, treg);
else
SSE2_MAXSD_XMM_to_XMM(sreg, treg);
SSE_MOVSS_XMM_to_XMM(EEREC_D, sreg);
_freeXMMreg(sreg); _freeXMMreg(treg);
}
void recMAX_S_xmm(int info) void recMAX_S_xmm(int info)
{ {
recFPUOp(info, EEREC_D, 2, false); recMINMAX(info, false);
} }
FPURECOMPILE_CONSTCODE(MAX_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(MAX_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
void recMIN_S_xmm(int info) void recMIN_S_xmm(int info)
{ {
recFPUOp(info, EEREC_D, 3, false); recMINMAX(info, true);
} }
FPURECOMPILE_CONSTCODE(MIN_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(MIN_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
@ -1322,6 +1038,5 @@ void recRSQRT_S_xmm(int info)
FPURECOMPILE_CONSTCODE(RSQRT_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT); FPURECOMPILE_CONSTCODE(RSQRT_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
//#endif // FPU_RECOMPILE
} } } } } } } } } }

View File

@ -1023,99 +1023,46 @@ CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
int t1reg = _allocTempXMMreg(XMMT_INT, -1); int t1reg = _allocTempXMMreg(XMMT_INT, -1);
int t2reg = _allocTempXMMreg(XMMT_INT, -1); int t2reg = _allocTempXMMreg(XMMT_INT, -1);
int t3reg = _allocTempXMMreg(XMMT_INT, -1);
if ( cpucaps.hasStreamingSIMD4Extensions ) { // The idea is:
SSE4_PMOVSXDQ_XMM_to_XMM(t0reg, EEREC_S); // s = x + y; (wrap-arounded)
SSE4_PMOVSXDQ_XMM_to_XMM(t1reg, EEREC_T); // if Sign(x) == Sign(y) && Sign(s) != Sign(x) && Sign(x) == 0 then positive overflow (clamp with 0x7fffffff)
SSE2_PADDQ_XMM_to_XMM(t0reg, t1reg); // if Sign(x) == Sign(y) && Sign(s) != Sign(x) && Sign(x) == 1 then negative overflow (clamp with 0x80000000)
SSE2_PSHUFD_XMM_to_XMM(t1reg, EEREC_S, 0x0e);
SSE2_PSHUFD_XMM_to_XMM(t2reg, EEREC_T, 0x0e);
SSE4_PMOVSXDQ_XMM_to_XMM(t1reg, t1reg);
SSE4_PMOVSXDQ_XMM_to_XMM(t2reg, t2reg);
}
else {
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
SSE2_PXOR_XMM_to_XMM(t2reg, t2reg);
SSE2_PXOR_XMM_to_XMM(t3reg, t3reg);
SSE2_PCMPGTD_XMM_to_XMM(t2reg, t0reg);
SSE2_PCMPGTD_XMM_to_XMM(t3reg, t1reg);
SSE2_PUNPCKLDQ_XMM_to_XMM(t0reg, t2reg);
SSE2_PUNPCKLDQ_XMM_to_XMM(t1reg, t3reg);
SSE2_PADDQ_XMM_to_XMM(t0reg, t1reg);
SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_S);
SSE2_PUNPCKHDQ_XMM_to_XMM(t1reg, t2reg);
SSEX_MOVDQA_XMM_to_XMM(t2reg, EEREC_T);
SSE2_PUNPCKHDQ_XMM_to_XMM(t2reg, t3reg);
}
SSE2_PADDQ_XMM_to_XMM(t1reg, t2reg);
/*
t0reg = { Rs[0]+Rt[0], Rs[1]+Rt[1] }
t1reg = { Rs[2]+Rt[2], Rs[3]+Rt[3] }
*/
SSEX_MOVDQA_XMM_to_XMM(t2reg, t0reg); // get sign bit
SSE_SHUFPS_XMM_to_XMM(t2reg, t1reg, 0xdd); SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSRAD_I8_to_XMM(t2reg, 31); SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
/* SSE2_PSRLD_I8_to_XMM(t0reg, 31);
t2reg = { (Rs[0]+Rt[0]) < 0 ? 0xFFFFFFFF : 0, SSE2_PSRLD_I8_to_XMM(t1reg, 31);
(Rs[1]+Rt[1]) < 0 ? 0xFFFFFFFF : 0,
(Rs[2]+Rt[2]) < 0 ? 0xFFFFFFFF : 0,
(Rs[3]+Rt[3]) < 0 ? 0xFFFFFFFF : 0 }
*/
SSE2_PSHUFD_XMM_to_XMM(t3reg, t2reg, 0x50); // normal addition
SSE2_PXOR_XMM_to_XMM(t0reg, t3reg);
SSE2_PSRLQ_I8_to_XMM(t3reg, 63);
SSE2_PADDQ_XMM_to_XMM(t0reg, t3reg);
/*
t0reg = { abs(Rs[0]+Rt[0]), abs(Rs[1]+Rt[1]) }
*/
SSE2_PSHUFD_XMM_to_XMM(t3reg, t2reg, 0xfa);
SSE2_PXOR_XMM_to_XMM(t1reg, t3reg);
SSE2_PSRLQ_I8_to_XMM(t3reg, 63);
SSE2_PADDQ_XMM_to_XMM(t1reg, t3reg);
/*
t1reg = { abs(Rs[2]+Rt[2]), abs(Rs[3]+Rt[3]) }
*/
SSE2_PSLLQ_I8_to_XMM(t0reg, 1);
SSE2_PSLLQ_I8_to_XMM(t1reg, 1);
SSE2_PCMPEQB_XMM_to_XMM(t3reg, t3reg);
SSE2_PSRLD_I8_to_XMM(t3reg, 1);
SSE2_PXOR_XMM_to_XMM(t2reg, t3reg);
SSE_SHUFPS_XMM_to_XMM(t0reg, t1reg, 0xdd);
SSE2_PXOR_XMM_to_XMM(t1reg, t1reg);
SSE2_PCMPEQD_XMM_to_XMM(t1reg, t0reg);
/*
t1reg = { abs(Rs[0]+Rt[0]) > 0x7FFFFFFF ? 0 : 0xFFFFFFFF,
abs(Rs[1]+Rt[1]) > 0x7FFFFFFF ? 0 : 0xFFFFFFFF,
abs(Rs[2]+Rt[2]) > 0x7FFFFFFF ? 0 : 0xFFFFFFFF,
abs(Rs[3]+Rt[3]) > 0x7FFFFFFF ? 0 : 0xFFFFFFFF }
t2reg = { (Rs[0]+Rt[0]) < 0 ? 0x80000000 : 0x7FFFFFFF,
(Rs[1]+Rt[1]) < 0 ? 0x80000000 : 0x7FFFFFFF,
(Rs[2]+Rt[2]) < 0 ? 0x80000000 : 0x7FFFFFFF,
(Rs[3]+Rt[3]) < 0 ? 0x80000000 : 0x7FFFFFFF }
*/
if( EEREC_D == EEREC_S ) SSE2_PADDD_XMM_to_XMM(EEREC_D, EEREC_T); if( EEREC_D == EEREC_S ) SSE2_PADDD_XMM_to_XMM(EEREC_D, EEREC_T);
else if( EEREC_D == EEREC_T ) SSE2_PADDD_XMM_to_XMM(EEREC_D, EEREC_S); else if( EEREC_D == EEREC_T ) SSE2_PADDD_XMM_to_XMM(EEREC_D, EEREC_S);
else { else {
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S); SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S);
SSE2_PADDD_XMM_to_XMM(EEREC_D, EEREC_T); SSE2_PADDD_XMM_to_XMM(EEREC_D, EEREC_T);
} }
SSE2_PAND_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PANDN_XMM_to_XMM(t1reg, t2reg); // overflow check
SSE2_POR_XMM_to_XMM(EEREC_D, t1reg); // t2reg = 0xffffffff if overflow, else 0
/* SSEX_MOVDQA_XMM_to_XMM(t2reg, EEREC_D);
Rd = { t1reg[0] ? Rs[0]+Rt[0] : t2reg[0], SSE2_PSRLD_I8_to_XMM(t2reg, 31);
t1reg[1] ? Rs[1]+Rt[1] : t2reg[1], SSE2_PCMPEQD_XMM_to_XMM(t1reg, t0reg); // Sign(Rs) == Sign(Rt)
t1reg[2] ? Rs[2]+Rt[2] : t2reg[2], SSE2_PCMPEQD_XMM_to_XMM(t2reg, t0reg); // Sign(Rs) == Sign(Rd)
t1reg[3] ? Rs[3]+Rt[3] : t2reg[3] } SSE2_PANDN_XMM_to_XMM(t2reg, t1reg); // (Sign(Rs) == Sign(Rt)) & ~(Sign(Rs) == Sign(Rd))
*/ SSE2_PCMPEQD_XMM_to_XMM(t1reg, t1reg);
SSE2_PSRLD_I8_to_XMM(t1reg, 1); // 0x7fffffff
SSE2_PADDD_XMM_to_XMM(t1reg, t0reg); // t1reg = (Rs < 0) ? 0x80000000 : 0x7fffffff
// saturation
SSE2_PAND_XMM_to_XMM(t1reg, t2reg);
SSE2_PANDN_XMM_to_XMM(t2reg, EEREC_D);
SSE2_POR_XMM_to_XMM(t1reg, t2reg);
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, t1reg);
_freeXMMreg(t0reg); _freeXMMreg(t0reg);
_freeXMMreg(t1reg); _freeXMMreg(t1reg);
_freeXMMreg(t2reg); _freeXMMreg(t2reg);
_freeXMMreg(t3reg);
CPU_SSE_XMMCACHE_END CPU_SSE_XMMCACHE_END
if( _Rd_ ) _deleteEEreg(_Rd_, 0); if( _Rd_ ) _deleteEEreg(_Rd_, 0);
@ -1210,71 +1157,49 @@ CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
int t1reg = _allocTempXMMreg(XMMT_INT, -1); int t1reg = _allocTempXMMreg(XMMT_INT, -1);
int t2reg = _allocTempXMMreg(XMMT_INT, -1); int t2reg = _allocTempXMMreg(XMMT_INT, -1);
int t3reg = _allocTempXMMreg(XMMT_INT, -1);
if ( cpucaps.hasStreamingSIMD4Extensions ) { // The idea is:
SSE4_PMOVSXDQ_XMM_to_XMM(t0reg, EEREC_S); // s = x - y; (wrap-arounded)
SSE4_PMOVSXDQ_XMM_to_XMM(t1reg, EEREC_T); // if Sign(x) != Sign(y) && Sign(s) != Sign(x) && Sign(x) == 0 then positive overflow (clamp with 0x7fffffff)
SSE2_PSUBQ_XMM_to_XMM(t0reg, t1reg); // if Sign(x) != Sign(y) && Sign(s) != Sign(x) && Sign(x) == 1 then negative overflow (clamp with 0x80000000)
SSE2_PSHUFD_XMM_to_XMM(t1reg, EEREC_S, 0x0e);
SSE2_PSHUFD_XMM_to_XMM(t2reg, EEREC_T, 0x0e);
SSE4_PMOVSXDQ_XMM_to_XMM(t1reg, t1reg);
SSE4_PMOVSXDQ_XMM_to_XMM(t2reg, t2reg);
}
else {
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
SSE2_PXOR_XMM_to_XMM(t2reg, t2reg);
SSE2_PXOR_XMM_to_XMM(t3reg, t3reg);
SSE2_PCMPGTD_XMM_to_XMM(t2reg, t0reg);
SSE2_PCMPGTD_XMM_to_XMM(t3reg, t1reg);
SSE2_PUNPCKLDQ_XMM_to_XMM(t0reg, t2reg);
SSE2_PUNPCKLDQ_XMM_to_XMM(t1reg, t3reg);
SSE2_PSUBQ_XMM_to_XMM(t0reg, t1reg);
SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_S);
SSE2_PUNPCKHDQ_XMM_to_XMM(t1reg, t2reg);
SSEX_MOVDQA_XMM_to_XMM(t2reg, EEREC_T);
SSE2_PUNPCKHDQ_XMM_to_XMM(t2reg, t3reg);
}
SSE2_PSUBQ_XMM_to_XMM(t1reg, t2reg);
SSEX_MOVDQA_XMM_to_XMM(t2reg, t0reg); // get sign bit
SSE_SHUFPS_XMM_to_XMM(t2reg, t1reg, 0xdd); SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
SSE2_PSRAD_I8_to_XMM(t2reg, 31); SSEX_MOVDQA_XMM_to_XMM(t1reg, EEREC_T);
SSE2_PSRLD_I8_to_XMM(t0reg, 31);
SSE2_PSRLD_I8_to_XMM(t1reg, 31);
SSE2_PSHUFD_XMM_to_XMM(t3reg, t2reg, 0x50); // normal subtraction
SSE2_PXOR_XMM_to_XMM(t0reg, t3reg);
SSE2_PSRLQ_I8_to_XMM(t3reg, 63);
SSE2_PADDQ_XMM_to_XMM(t0reg, t3reg);
SSE2_PSHUFD_XMM_to_XMM(t3reg, t2reg, 0xfa);
SSE2_PXOR_XMM_to_XMM(t1reg, t3reg);
SSE2_PSRLQ_I8_to_XMM(t3reg, 63);
SSE2_PADDQ_XMM_to_XMM(t1reg, t3reg);
SSE2_PSLLQ_I8_to_XMM(t0reg, 1);
SSE2_PSLLQ_I8_to_XMM(t1reg, 1);
SSE2_PCMPEQB_XMM_to_XMM(t3reg, t3reg);
SSE2_PSRLD_I8_to_XMM(t3reg, 1);
SSE2_PXOR_XMM_to_XMM(t2reg, t3reg);
SSE_SHUFPS_XMM_to_XMM(t0reg, t1reg, 0xdd);
SSE2_PXOR_XMM_to_XMM(t1reg, t1reg);
SSE2_PCMPEQD_XMM_to_XMM(t1reg, t0reg);
if( EEREC_D == EEREC_S ) SSE2_PSUBD_XMM_to_XMM(EEREC_D, EEREC_T); if( EEREC_D == EEREC_S ) SSE2_PSUBD_XMM_to_XMM(EEREC_D, EEREC_T);
else if( EEREC_D == EEREC_T ) { else if( EEREC_D == EEREC_T ) {
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_T); SSEX_MOVDQA_XMM_to_XMM(t2reg, EEREC_T);
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S); SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, t0reg); SSE2_PSUBD_XMM_to_XMM(EEREC_D, t2reg);
} }
else { else {
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S); SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, EEREC_T); SSE2_PSUBD_XMM_to_XMM(EEREC_D, EEREC_T);
} }
SSE2_PAND_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PANDN_XMM_to_XMM(t1reg, t2reg); // overflow check
SSE2_POR_XMM_to_XMM(EEREC_D, t1reg); // t2reg = 0xffffffff if NOT overflow, else 0
SSEX_MOVDQA_XMM_to_XMM(t2reg, EEREC_D);
SSE2_PSRLD_I8_to_XMM(t2reg, 31);
SSE2_PCMPEQD_XMM_to_XMM(t1reg, t0reg); // Sign(Rs) == Sign(Rt)
SSE2_PCMPEQD_XMM_to_XMM(t2reg, t0reg); // Sign(Rs) == Sign(Rd)
SSE2_POR_XMM_to_XMM(t2reg, t1reg); // (Sign(Rs) == Sign(Rt)) | (Sign(Rs) == Sign(Rd))
SSE2_PCMPEQD_XMM_to_XMM(t1reg, t1reg);
SSE2_PSRLD_I8_to_XMM(t1reg, 1); // 0x7fffffff
SSE2_PADDD_XMM_to_XMM(t1reg, t0reg); // t1reg = (Rs < 0) ? 0x80000000 : 0x7fffffff
// saturation
SSE2_PAND_XMM_to_XMM(EEREC_D, t2reg);
SSE2_PANDN_XMM_to_XMM(t2reg, t1reg);
SSE2_POR_XMM_to_XMM(EEREC_D, t2reg);
_freeXMMreg(t0reg); _freeXMMreg(t0reg);
_freeXMMreg(t1reg); _freeXMMreg(t1reg);
_freeXMMreg(t2reg); _freeXMMreg(t2reg);
_freeXMMreg(t3reg);
CPU_SSE_XMMCACHE_END CPU_SSE_XMMCACHE_END
if( _Rd_ ) _deleteEEreg(_Rd_, 0); if( _Rd_ ) _deleteEEreg(_Rd_, 0);

View File

@ -18,7 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "PsxCommon.h" #include "IopCommon.h"
#include "iR3000A.h" #include "iR3000A.h"
#include "VU.h" #include "VU.h"

View File

@ -30,7 +30,7 @@
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#include "PsxCommon.h" #include "IopCommon.h"
#include "VU.h" #include "VU.h"
#include "iCore.h" #include "iCore.h"

View File

@ -19,7 +19,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include <time.h> #include <time.h>
#include "PsxCommon.h" #include "IopCommon.h"
#include "iR3000A.h" #include "iR3000A.h"
#include "IopMem.h" #include "IopMem.h"
#include "IopDma.h" #include "IopDma.h"
@ -97,7 +97,7 @@ PSXRECOMPILE_CONSTCODE1(SLTI);
//// SLTIU //// SLTIU
void rpsxSLTIU_const() void rpsxSLTIU_const()
{ {
g_psxConstRegs[_Rt_] = g_psxConstRegs[_Rs_] < _ImmU_; g_psxConstRegs[_Rt_] = g_psxConstRegs[_Rs_] < (u32)_Imm_;
} }
void rpsxSLTUconst(int info, int dreg, int sreg, int imm) void rpsxSLTUconst(int info, int dreg, int sreg, int imm)

View File

@ -698,19 +698,10 @@ void* SuperVUGetProgram(u32 startpc, int vuindex)
bool VuFunctionHeader::IsSame(void* pmem) bool VuFunctionHeader::IsSame(void* pmem)
{ {
#ifdef SUPERVU_CACHING #ifdef SUPERVU_CACHING
//u32 checksum[2];
vector<RANGE>::iterator it; vector<RANGE>::iterator it;
FORIT(it, ranges) { FORIT(it, ranges)
//memxor_mmx(checksum, (u8*)pmem+it->start, it->size); {
//if( checksum[0] != it->checksum[0] || checksum[1] != it->checksum[1] ) if( memcmp_mmx((u8*)pmem+it->start, it->pmem, it->size) )
// return false;
// memcmp_mmx doesn't work on x86-64 machines
// and neither does pcsx2.
//#if defined(_MSC_VER)
if( memcmp_mmx((u8*)pmem+it->start, it->pmem, it->size) )
//#else
// if( memcmp((u8*)pmem+it->start, it->pmem, it->size) )
//#endif
return false; return false;
} }
#endif #endif
@ -3022,7 +3013,6 @@ void VuInstruction::Recompile(list<VuInstruction>::iterator& itinst, u32 vuxyz)
CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution); CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution);
u8* jptr = JNE8(0); u8* jptr = JNE8(0);
MOV32MtoR(EAX, pparentinst->pClipWrite); MOV32MtoR(EAX, pparentinst->pClipWrite);
MOV32ItoM(pparentinst->pClipWrite, 0);
MOV32RtoM(s_ClipRead, EAX); MOV32RtoM(s_ClipRead, EAX);
x86SetJ8(jptr); x86SetJ8(jptr);
} }

View File

@ -29,11 +29,6 @@
extern u32 g_vif1Masks[48], g_vif0Masks[48]; extern u32 g_vif1Masks[48], g_vif0Masks[48];
extern u32 g_vif1HasMask3[4], g_vif0HasMask3[4]; extern u32 g_vif1HasMask3[4], g_vif0HasMask3[4];
//static const u32 writearr[4] = { 0xffffffff, 0, 0, 0 };
//static const u32 rowarr[4] = { 0, 0xffffffff, 0, 0 };
//static const u32 colarr[4] = { 0, 0, 0xffffffff, 0 };
//static const u32 updatearr[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0 };
// arranged in writearr, rowarr, colarr, updatearr // arranged in writearr, rowarr, colarr, updatearr
static PCSX2_ALIGNED16(u32 s_maskarr[16][4]) = { static PCSX2_ALIGNED16(u32 s_maskarr[16][4]) = {
0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff,
@ -58,8 +53,6 @@ extern u8 s_maskwrite[256];
extern "C" PCSX2_ALIGNED16(u32 s_TempDecompress[4]) = {0}; extern "C" PCSX2_ALIGNED16(u32 s_TempDecompress[4]) = {0};
//#if defined(_MSC_VER)
void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask) void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
{ {
u32 i; u32 i;
@ -67,7 +60,7 @@ void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
FreezeXMMRegs(1); FreezeXMMRegs(1);
for(i = 0; i < 4; ++i, mask >>= 8, oldmask >>= 8, vif1masks += 16) { for(i = 0; i < 4; ++i, mask >>= 8, oldmask >>= 8, vif1masks += 16) {
prev |= s_maskwrite[mask&0xff];//((mask&3)==3)||((mask&0xc)==0xc)||((mask&0x30)==0x30)||((mask&0xc0)==0xc0); prev |= s_maskwrite[mask&0xff];
hasmask[i] = prev; hasmask[i] = prev;
if( (mask&0xff) != (oldmask&0xff) ) { if( (mask&0xff) != (oldmask&0xff) ) {
@ -93,46 +86,3 @@ void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
} }
FreezeXMMRegs(0); FreezeXMMRegs(0);
} }
/*#else // gcc
// Is this really supposed to be assembly for gcc and C for Windows?
void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
{
u32 i;
u32 prev = 0;
FreezeXMMRegs(1);
for(i = 0; i < 4; ++i, mask >>= 8, oldmask >>= 8, vif1masks += 16) {
prev |= s_maskwrite[mask&0xff];//((mask&3)==3)||((mask&0xc)==0xc)||((mask&0x30)==0x30)||((mask&0xc0)==0xc0);
hasmask[i] = prev;
if( (mask&0xff) != (oldmask&0xff) ) {
u8* p0 = (u8*)&s_maskarr[mask&15][0];
u8* p1 = (u8*)&s_maskarr[(mask>>4)&15][0];
__asm__(".intel_syntax noprefix\n"
"movaps xmm0, [%0]\n"
"movaps xmm1, [%1]\n"
"movaps xmm2, xmm0\n"
"punpcklwd xmm0, xmm0\n"
"punpckhwd xmm2, xmm2\n"
"movaps xmm3, xmm1\n"
"punpcklwd xmm1, xmm1\n"
"punpckhwd xmm3, xmm3\n"
"movq [%2], xmm0\n"
"movq [%2+8], xmm1\n"
"movhps [%2+16], xmm0\n"
"movhps [%2+24], xmm1\n"
"movq [%2+32], xmm2\n"
"movq [%2+40], xmm3\n"
"movhps [%2+48], xmm2\n"
"movhps [%2+56], xmm3\n"
".att_syntax\n" : : "r"(p0), "r"(p1), "r"(vif1masks) );
}
}
FreezeXMMRegs(0);
}
#endif*/

View File

@ -444,7 +444,7 @@ int _getFreeMMXreg()
// check for dead regs // check for dead regs
for (i=0; i<MMXREGS; i++) { for (i=0; i<MMXREGS; i++) {
if (mmxregs[i].needed) continue; if (mmxregs[i].needed) continue;
if (mmxregs[i].reg >= MMX_GPR && mmxregs[i].reg < MMX_GPR+34 ) { if (mmxregs[i].reg >= MMX_GPR && mmxregs[i].reg < MMX_GPR+34 ) { // mmxregs[i] is unsigned, and MMX_GPR == 0, so the first part is always true.
if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR] & (EEINST_LIVE0|EEINST_LIVE1)) ) { if( !(g_pCurInstInfo->regs[mmxregs[i].reg-MMX_GPR] & (EEINST_LIVE0|EEINST_LIVE1)) ) {
_freeMMXreg(i); _freeMMXreg(i);
return i; return i;

View File

@ -613,9 +613,12 @@ void recStep( void ) {
static __forceinline bool recEventTest() static __forceinline bool recEventTest()
{ {
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
// dont' remove this check unless doing an official release // dont' remove this check unless doing an official release
if( g_globalXMMSaved || g_globalMMXSaved) if( g_globalXMMSaved || g_globalMMXSaved)
{
DevCon::Error("Pcsx2 Foopah! Frozen regs have not been restored!!!"); DevCon::Error("Pcsx2 Foopah! Frozen regs have not been restored!!!");
DevCon::Error("g_globalXMMSaved = %d,g_globalMMXSaved = %d",params g_globalXMMSaved, g_globalMMXSaved);
}
assert( !g_globalXMMSaved && !g_globalMMXSaved); assert( !g_globalXMMSaved && !g_globalMMXSaved);
#endif #endif
@ -1198,11 +1201,12 @@ u32 eeScaleBlockCycles()
jNO_DEFAULT jNO_DEFAULT
} }
s_nBlockCycles *= const u32 temp = s_nBlockCycles * (
(s_nBlockCycles <= (10<<3)) ? scalarLow : (s_nBlockCycles <= (10<<3)) ? scalarLow :
((s_nBlockCycles > (21<<3)) ? scalarHigh : scalarMid ); ((s_nBlockCycles > (21<<3)) ? scalarHigh : scalarMid )
);
return s_nBlockCycles >> (3+2); return temp >> (3+2);
} }
// Generates dynarec code for Event tests followed by a block dispatch (branch). // Generates dynarec code for Event tests followed by a block dispatch (branch).

View File

@ -486,19 +486,6 @@ void recADDIU( void )
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recDADDI( void ) void recDADDI( void )
{ {
#ifdef __x86_64_
if ( ! _Rt_ )
{
return;
}
MOV64MtoR( RAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 )
{
ADD64ItoR( EAX, _Imm_ );
}
MOV64RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], RAX );
#else
if ( ! _Rt_ ) if ( ! _Rt_ )
{ {
return; return;
@ -520,7 +507,6 @@ void recDADDI( void )
} }
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX ); MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX ); MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
#endif
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////

View File

@ -950,6 +950,9 @@
#define SSSE3_PABSW_XMM_to_XMM eSSSE3_PABSW_XMM_to_XMM<_EmitterId_> #define SSSE3_PABSW_XMM_to_XMM eSSSE3_PABSW_XMM_to_XMM<_EmitterId_>
#define SSSE3_PABSD_XMM_to_XMM eSSSE3_PABSD_XMM_to_XMM<_EmitterId_> #define SSSE3_PABSD_XMM_to_XMM eSSSE3_PABSD_XMM_to_XMM<_EmitterId_>
#define SSSE3_PALIGNR_XMM_to_XMM eSSSE3_PALIGNR_XMM_to_XMM<_EmitterId_> #define SSSE3_PALIGNR_XMM_to_XMM eSSSE3_PALIGNR_XMM_to_XMM<_EmitterId_>
#define SSSE3_PSIGNB_XMM_to_XMM eSSSE3_PSIGNB_XMM_to_XMM<_EmitterId_>
#define SSSE3_PSIGNW_XMM_to_XMM eSSSE3_PSIGNW_XMM_to_XMM<_EmitterId_>
#define SSSE3_PSIGND_XMM_to_XMM eSSSE3_PSIGND_XMM_to_XMM<_EmitterId_>
//------------------------------------------------------------------ //------------------------------------------------------------------
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -963,6 +966,7 @@
#define SSE4_BLENDVPS_XMM_to_XMM eSSE4_BLENDVPS_XMM_to_XMM<_EmitterId_> #define SSE4_BLENDVPS_XMM_to_XMM eSSE4_BLENDVPS_XMM_to_XMM<_EmitterId_>
#define SSE4_BLENDVPS_M128_to_XMM eSSE4_BLENDVPS_M128_to_XMM<_EmitterId_> #define SSE4_BLENDVPS_M128_to_XMM eSSE4_BLENDVPS_M128_to_XMM<_EmitterId_>
#define SSE4_PMOVSXDQ_XMM_to_XMM eSSE4_PMOVSXDQ_XMM_to_XMM<_EmitterId_> #define SSE4_PMOVSXDQ_XMM_to_XMM eSSE4_PMOVSXDQ_XMM_to_XMM<_EmitterId_>
#define SSE4_PMOVZXDQ_XMM_to_XMM eSSE4_PMOVZXDQ_XMM_to_XMM<_EmitterId_>
#define SSE4_PINSRD_R32_to_XMM eSSE4_PINSRD_R32_to_XMM<_EmitterId_> #define SSE4_PINSRD_R32_to_XMM eSSE4_PINSRD_R32_to_XMM<_EmitterId_>
#define SSE4_PMAXSD_XMM_to_XMM eSSE4_PMAXSD_XMM_to_XMM<_EmitterId_> #define SSE4_PMAXSD_XMM_to_XMM eSSE4_PMAXSD_XMM_to_XMM<_EmitterId_>
#define SSE4_PMINSD_XMM_to_XMM eSSE4_PMINSD_XMM_to_XMM<_EmitterId_> #define SSE4_PMINSD_XMM_to_XMM eSSE4_PMINSD_XMM_to_XMM<_EmitterId_>

View File

@ -1224,6 +1224,30 @@ emitterT void eSSSE3_PALIGNR_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8
write8<I>(imm8); write8<I>(imm8);
} }
emitterT void eSSSE3_PSIGNB_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
{
write8<I>(0x66);
RexRB(0, to, from);
write24<I>(0x08380F);
ModRM<I>(3, to, from);
}
emitterT void eSSSE3_PSIGNW_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
{
write8<I>(0x66);
RexRB(0, to, from);
write24<I>(0x09380F);
ModRM<I>(3, to, from);
}
emitterT void eSSSE3_PSIGND_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
{
write8<I>(0x66);
RexRB(0, to, from);
write24<I>(0x0A380F);
ModRM<I>(3, to, from);
}
// SSE4.1 // SSE4.1
emitterT void eSSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8) emitterT void eSSE4_DPPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from, u8 imm8)
@ -1295,6 +1319,14 @@ emitterT void eSSE4_PMOVSXDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
ModRM<I>(3, to, from); ModRM<I>(3, to, from);
} }
emitterT void eSSE4_PMOVZXDQ_XMM_to_XMM(x86SSERegType to, x86SSERegType from)
{
write8<I>(0x66);
RexRB(0, to, from);
write24<I>(0x35380F);
ModRM<I>(3, to, from);
}
emitterT void eSSE4_PINSRD_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8) emitterT void eSSE4_PINSRD_R32_to_XMM(x86SSERegType to, x86IntRegType from, u8 imm8)
{ {
write8<I>(0x66); write8<I>(0x66);

View File

@ -72,15 +72,23 @@ void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR)
extern "C" extern "C"
{ {
#endif #endif
__forceinline void FreezeRegs(int save)
{
FreezeXMMRegs(save);
FreezeMMXRegs(save);
}
__forceinline void FreezeMMXRegs_(int save) __forceinline void FreezeMMXRegs_(int save)
{ {
//DevCon::Notice("FreezeMMXRegs_(%d); [%d]\n", save, g_globalMMXSaved);
assert( g_EEFreezeRegs ); assert( g_EEFreezeRegs );
if( save ) { if( save ) {
g_globalMMXSaved++; g_globalMMXSaved++;
if( g_globalMMXSaved>1 ) if( g_globalMMXSaved>1 )
{ {
//SysPrintf("MMX Already Saved!\n"); //DevCon::Notice("MMX Already Saved!\n");
return; return;
} }
@ -117,7 +125,7 @@ __forceinline void FreezeMMXRegs_(int save)
else { else {
if( g_globalMMXSaved==0 ) if( g_globalMMXSaved==0 )
{ {
//SysPrintf("MMX Not Saved!\n"); //DevCon::Notice("MMX Not Saved!\n");
return; return;
} }
g_globalMMXSaved--; g_globalMMXSaved--;
@ -159,14 +167,14 @@ __forceinline void FreezeMMXRegs_(int save)
// XMM Register Freezing // XMM Register Freezing
__forceinline void FreezeXMMRegs_(int save) __forceinline void FreezeXMMRegs_(int save)
{ {
//SysPrintf("FreezeXMMRegs_(%d); [%d]\n", save, g_globalXMMSaved); //DevCon::Notice("FreezeXMMRegs_(%d); [%d]\n", save, g_globalXMMSaved);
assert( g_EEFreezeRegs ); assert( g_EEFreezeRegs );
if( save ) if( save )
{ {
g_globalXMMSaved++; g_globalXMMSaved++;
if( g_globalXMMSaved > 1 ){ if( g_globalXMMSaved > 1 ){
//SysPrintf("XMM Already saved\n"); //DevCon::Notice("XMM Already saved\n");
return; return;
} }
@ -204,7 +212,7 @@ __forceinline void FreezeXMMRegs_(int save)
{ {
if( g_globalXMMSaved==0 ) if( g_globalXMMSaved==0 )
{ {
//SysPrintf("XMM Regs not saved!\n"); //DevCon::Notice("XMM Regs not saved!\n");
return; return;
} }

View File

@ -43,6 +43,16 @@ PCSX2_ALIGNED16(const u32 mVU_T6[4]) = {0xbd6501c4, 0xbd6501c4, 0xbd6501c4, 0xb
PCSX2_ALIGNED16(const u32 mVU_T7[4]) = {0x3cb31652, 0x3cb31652, 0x3cb31652, 0x3cb31652}; PCSX2_ALIGNED16(const u32 mVU_T7[4]) = {0x3cb31652, 0x3cb31652, 0x3cb31652, 0x3cb31652};
PCSX2_ALIGNED16(const u32 mVU_T8[4]) = {0xbb84d7e7, 0xbb84d7e7, 0xbb84d7e7, 0xbb84d7e7}; PCSX2_ALIGNED16(const u32 mVU_T8[4]) = {0xbb84d7e7, 0xbb84d7e7, 0xbb84d7e7, 0xbb84d7e7};
PCSX2_ALIGNED16(const u32 mVU_Pi4[4]) = {0x3f490fdb, 0x3f490fdb, 0x3f490fdb, 0x3f490fdb}; PCSX2_ALIGNED16(const u32 mVU_Pi4[4]) = {0x3f490fdb, 0x3f490fdb, 0x3f490fdb, 0x3f490fdb};
PCSX2_ALIGNED16(const u32 mVU_S2[4]) = {0xbe2aaaa4, 0xbe2aaaa4, 0xbe2aaaa4, 0xbe2aaaa4};
PCSX2_ALIGNED16(const u32 mVU_S3[4]) = {0x3c08873e, 0x3c08873e, 0x3c08873e, 0x3c08873e};
PCSX2_ALIGNED16(const u32 mVU_S4[4]) = {0xb94fb21f, 0xb94fb21f, 0xb94fb21f, 0xb94fb21f};
PCSX2_ALIGNED16(const u32 mVU_S5[4]) = {0x362e9c14, 0x362e9c14, 0x362e9c14, 0x362e9c14};
PCSX2_ALIGNED16(const u32 mVU_E1[4]) = {0x3e7fffa8, 0x3e7fffa8, 0x3e7fffa8, 0x3e7fffa8};
PCSX2_ALIGNED16(const u32 mVU_E2[4]) = {0x3d0007f4, 0x3d0007f4, 0x3d0007f4, 0x3d0007f4};
PCSX2_ALIGNED16(const u32 mVU_E3[4]) = {0x3b29d3ff, 0x3b29d3ff, 0x3b29d3ff, 0x3b29d3ff};
PCSX2_ALIGNED16(const u32 mVU_E4[4]) = {0x3933e553, 0x3933e553, 0x3933e553, 0x3933e553};
PCSX2_ALIGNED16(const u32 mVU_E5[4]) = {0x36b63510, 0x36b63510, 0x36b63510, 0x36b63510};
PCSX2_ALIGNED16(const u32 mVU_E6[4]) = {0x353961ac, 0x353961ac, 0x353961ac, 0x353961ac};
PCSX2_ALIGNED16(const float mVU_FTOI_4[4]) = {16.0, 16.0, 16.0, 16.0}; PCSX2_ALIGNED16(const float mVU_FTOI_4[4]) = {16.0, 16.0, 16.0, 16.0};
PCSX2_ALIGNED16(const float mVU_FTOI_12[4]) = {4096.0, 4096.0, 4096.0, 4096.0}; PCSX2_ALIGNED16(const float mVU_FTOI_12[4]) = {4096.0, 4096.0, 4096.0, 4096.0};
PCSX2_ALIGNED16(const float mVU_FTOI_15[4]) = {32768.0, 32768.0, 32768.0, 32768.0}; PCSX2_ALIGNED16(const float mVU_FTOI_15[4]) = {32768.0, 32768.0, 32768.0, 32768.0};

View File

@ -100,11 +100,13 @@ struct microProgManager {
}; };
struct microVU { struct microVU {
int index; // VU Index (VU0 or VU1) u32 index; // VU Index (VU0 or VU1)
u32 microSize; // VU Micro Memory Size u32 microSize; // VU Micro Memory Size
u32 progSize; // VU Micro Program Size (microSize/8) u32 progSize; // VU Micro Program Size (microSize/8)
u32 cacheAddr; // VU Cache Start Address u32 cacheAddr; // VU Cache Start Address
static const u32 cacheSize = 0x400000; // VU Cache Size static const u32 cacheSize = 0x400000; // VU Cache Size
microProgManager<0x800> prog; // Micro Program Data
VURegs* regs; // VU Regs Struct VURegs* regs; // VU Regs Struct
u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to) u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to)
@ -122,7 +124,6 @@ struct microVU {
uptr x86esi; // Source register. Used as a pointer to a source in stream operations. uptr x86esi; // Source register. Used as a pointer to a source in stream operations.
uptr x86edi; // Destination register. Used as a pointer to a destination in stream operations. uptr x86edi; // Destination register. Used as a pointer to a destination in stream operations.
*/ */
microProgManager<0x800> prog; // Micro Program Data
}; };
// microVU rec structs // microVU rec structs

View File

@ -36,14 +36,14 @@
if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2<vuIndex>(reg, xmmT1, _X_Y_Z_W); \ if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2<vuIndex>(reg, xmmT1, _X_Y_Z_W); \
} }
#define getZeroSS(reg) { \ #define getZero(reg) { \
if (_W) { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \ if (_W) { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \
else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ else { SSE_XORPS_XMM_to_XMM(reg, reg); } \
} }
#define getZero(reg) { \ #define getReg6(reg, _reg_) { \
if (_W) { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \ if (!_reg_) { getZero(reg); } \
else { SSE_XORPS_XMM_to_XMM(reg, reg); } \ else { getReg(reg, _reg_); } \
} }
microVUt(void) mVUallocFMAC1a(int& Fd, int& Fs, int& Ft) { microVUt(void) mVUallocFMAC1a(int& Fd, int& Fs, int& Ft) {
@ -51,26 +51,9 @@ microVUt(void) mVUallocFMAC1a(int& Fd, int& Fs, int& Ft) {
Fs = xmmFs; Fs = xmmFs;
Ft = xmmFt; Ft = xmmFt;
Fd = xmmFs; Fd = xmmFs;
if (_XYZW_SS) { getReg6(Fs, _Fs_);
if (!_Fs_) { getZeroSS(Fs); } if (_Ft_ == _Fs_) { Ft = Fs; }
else { getReg(Fs, _Fs_); } else { getReg6(Ft, _Ft_); }
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZero(Ft); }
else { getReg(Ft, _Ft_); }
}
}
} }
microVUt(void) mVUallocFMAC1b(int& Fd) { microVUt(void) mVUallocFMAC1b(int& Fd) {
@ -88,14 +71,7 @@ microVUt(void) mVUallocFMAC2a(int& Fs, int& Ft) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
Fs = xmmFs; Fs = xmmFs;
Ft = xmmFs; Ft = xmmFs;
if (_XYZW_SS) { getReg6(Fs, _Fs_);
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC2b(int& Ft) { microVUt(void) mVUallocFMAC2b(int& Ft) {
@ -139,21 +115,15 @@ microVUt(void) mVUallocFMAC3a(int& Fd, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
Fd = xmmFs; Fd = xmmFs;
if (_XYZW_SS) { if (_XYZW_SS) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); }
if ( (_Ft_ == _Fs_) && ((_X && _bc_x) || (_Y && _bc_y) || (_Z && _bc_w) || (_W && _bc_w)) ) { if ( (_Ft_ == _Fs_) && ((_X && _bc_x) || (_Y && _bc_y) || (_Z && _bc_w) || (_W && _bc_w)) ) {
Ft = Fs; Ft = Fs;
} }
else { else if (!_Ft_) { getZero3SS(Ft); }
if (!_Ft_) { getZero3SS(Ft); } else { getReg3SS(Ft, _Ft_); }
else { getReg3SS(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); }
if (!_Ft_) { getZero3(Ft); } if (!_Ft_) { getZero3(Ft); }
else { getReg3(Ft, _Ft_); } else { getReg3(Ft, _Ft_); }
} }
@ -188,24 +158,17 @@ microVUt(void) mVUallocFMAC4a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
getACC(ACC); getACC(ACC);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else { getReg6(Ft, _Ft_); }
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else if (!_Ft_) { getZero4(Ft); }
if (!_Ft_) { getZero4(Ft); } else { getReg4(Ft, _Ft_); }
else { getReg4(Ft, _Ft_); }
}
} }
} }
@ -225,16 +188,10 @@ microVUt(void) mVUallocFMAC5a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
getACC(ACC); getACC(ACC);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); } if ((_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
if ( (_Ft_ == _Fs_) && _bc_x) { else { getReg3SS(Ft, _Ft_); }
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
@ -266,14 +223,7 @@ microVUt(void) mVUallocFMAC6a(int& Fd, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
Fd = xmmFs; Fd = xmmFs;
getIreg(Ft); getIreg(Ft);
if (_XYZW_SS) { getReg6(Fs, _Fs_);
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC6b(int& Fd) { microVUt(void) mVUallocFMAC6b(int& Fd) {
@ -290,14 +240,9 @@ microVUt(void) mVUallocFMAC7a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
getACC(ACC); getACC(ACC);
getIreg(Ft); getIreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC7b(int& ACC, int& Fs) { microVUt(void) mVUallocFMAC7b(int& ACC, int& Fs) {
@ -315,24 +260,17 @@ microVUt(void) mVUallocFMAC8a(int& Fd, int&ACC, int& Fs, int& Ft) {
Fd = xmmFs; Fd = xmmFs;
ACC = xmmACC0 + readACC; ACC = xmmACC0 + readACC;
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else { getReg6(Ft, _Ft_); }
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else if (!_Ft_) { getZero4(Ft); }
if (!_Ft_) { getZero4(Ft); } else { getReg4(Ft, _Ft_); }
else { getReg4(Ft, _Ft_); }
}
} }
} }
@ -355,24 +293,17 @@ microVUt(void) mVUallocFMAC9a(int& Fd, int&ACC, int& Fs, int& Ft) {
ACC = xmmT1; ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC); SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else { getReg6(Ft, _Ft_); }
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else if (!_Ft_) { getZero4(Ft); }
if (!_Ft_) { getZero4(Ft); } else { getReg4(Ft, _Ft_); }
else { getReg4(Ft, _Ft_); }
}
} }
} }
@ -394,16 +325,10 @@ microVUt(void) mVUallocFMAC10a(int& Fd, int& ACC, int& Fs, int& Ft) {
Fd = xmmFs; Fd = xmmFs;
ACC = xmmACC0 + readACC; ACC = xmmACC0 + readACC;
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); } if ( (_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
if ( (_Ft_ == _Fs_) && _bc_x) { else { getReg3SS(Ft, _Ft_); }
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
@ -430,16 +355,10 @@ microVUt(void) mVUallocFMAC11a(int& Fd, int& ACC, int& Fs, int& Ft) {
ACC = xmmT1; ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC); SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); } if ( (_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
if ( (_Ft_ == _Fs_) && _bc_x) { else { getReg3SS(Ft, _Ft_); }
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
@ -465,14 +384,9 @@ microVUt(void) mVUallocFMAC12a(int& Fd, int&ACC, int& Fs, int& Ft) {
Fd = xmmFs; Fd = xmmFs;
ACC = xmmACC0 + readACC; ACC = xmmACC0 + readACC;
getIreg(Ft); getIreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC12b(int& Fd) { microVUt(void) mVUallocFMAC12b(int& Fd) {
@ -491,14 +405,9 @@ microVUt(void) mVUallocFMAC13a(int& Fd, int&ACC, int& Fs, int& Ft) {
ACC = xmmT1; ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC); SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
getIreg(Ft); getIreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC13b(int& Fd) { microVUt(void) mVUallocFMAC13b(int& Fd) {
@ -516,24 +425,17 @@ microVUt(void) mVUallocFMAC14a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
ACCr = xmmACC0 + readACC; ACCr = xmmACC0 + readACC;
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else { getReg6(Ft, _Ft_); }
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; } if (_Ft_ == _Fs_) { Ft = Fs; }
else { else if (!_Ft_) { getZero4(Ft); }
if (!_Ft_) { getZero4(Ft); } else { getReg4(Ft, _Ft_); }
else { getReg4(Ft, _Ft_); }
}
} }
} }
@ -570,16 +472,10 @@ microVUt(void) mVUallocFMAC16a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
ACCr = xmmACC0 + readACC; ACCr = xmmACC0 + readACC;
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); } getReg6(Fs, _Fs_);
else { getReg(Fs, _Fs_); } if ((_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
if ( (_Ft_ == _Fs_) && _bc_x) { else { getReg3SS(Ft, _Ft_); }
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
} }
else { else {
if (!_Fs_) { getZero4(Fs); } if (!_Fs_) { getZero4(Fs); }
@ -624,8 +520,8 @@ microVUt(void) mVUallocFMAC18a(int& ACC, int& Fs, int& Ft) {
if (!_Ft_) { getZero4(Ft); } if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); } else { getReg4(Ft, _Ft_); }
SSE_SHUFPS_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY
SSE_SHUFPS_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ
} }
microVUt(void) mVUallocFMAC18b(int& ACC, int& Fs) { microVUt(void) mVUallocFMAC18b(int& ACC, int& Fs) {
@ -650,8 +546,8 @@ microVUt(void) mVUallocFMAC19a(int& Fd, int&ACC, int& Fs, int& Ft) {
if (!_Ft_) { getZero4(Ft); } if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); } else { getReg4(Ft, _Ft_); }
SSE_SHUFPS_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY
SSE_SHUFPS_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ
} }
microVUt(void) mVUallocFMAC19b(int& Fd) { microVUt(void) mVUallocFMAC19b(int& Fd) {
@ -669,14 +565,9 @@ microVUt(void) mVUallocFMAC20a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
ACCr = xmmACC0 + readACC; ACCr = xmmACC0 + readACC;
getIreg(Ft); getIreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC20b(int& ACCw, int& Fs) { microVUt(void) mVUallocFMAC20b(int& ACCw, int& Fs) {
@ -712,14 +603,7 @@ microVUt(void) mVUallocFMAC22a(int& Fd, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
Fd = xmmFs; Fd = xmmFs;
getQreg(Ft); getQreg(Ft);
if (_XYZW_SS) { getReg6(Fs, _Fs_);
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC22b(int& Fd) { microVUt(void) mVUallocFMAC22b(int& Fd) {
@ -736,21 +620,15 @@ microVUt(void) mVUallocFMAC23a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
getACC(ACC); getACC(ACC);
getQreg(Ft); getQreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC23b(int& ACC, int& Fs) { microVUt(void) mVUallocFMAC23b(int& ACC, int& Fs) {
mVUallocFMAC4b<vuIndex>(ACC, Fs); mVUallocFMAC4b<vuIndex>(ACC, Fs);
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
// FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg) // FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg)
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -762,14 +640,9 @@ microVUt(void) mVUallocFMAC24a(int& Fd, int&ACC, int& Fs, int& Ft) {
Fd = xmmFs; Fd = xmmFs;
ACC = xmmACC0 + readACC; ACC = xmmACC0 + readACC;
getQreg(Ft); getQreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC24b(int& Fd) { microVUt(void) mVUallocFMAC24b(int& Fd) {
@ -788,14 +661,9 @@ microVUt(void) mVUallocFMAC25a(int& Fd, int&ACC, int& Fs, int& Ft) {
ACC = xmmT1; ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC); SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
getQreg(Ft); getQreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC25b(int& Fd) { microVUt(void) mVUallocFMAC25b(int& Fd) {
@ -813,14 +681,9 @@ microVUt(void) mVUallocFMAC26a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt; Ft = xmmFt;
ACCr = xmmACC0 + readACC; ACCr = xmmACC0 + readACC;
getQreg(Ft); getQreg(Ft);
if (_XYZW_SS && _X) { if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
if (!_Fs_) { getZeroSS(Fs); } else if (!_Fs_) { getZero4(Fs); }
else { getReg(Fs, _Fs_); } else { getReg4(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
} }
microVUt(void) mVUallocFMAC26b(int& ACCw, int& Fs) { microVUt(void) mVUallocFMAC26b(int& ACCw, int& Fs) {
@ -885,14 +748,14 @@ microVUt(void) mVUallocMFLAGb(int reg, int fInstance) {
microVUt(void) mVUallocVIa(int GPRreg, int _reg_) { microVUt(void) mVUallocVIa(int GPRreg, int _reg_) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (_reg_ == 0) { XOR32RtoR(GPRreg, GPRreg); } if (_reg_ == 0) { XOR32RtoR(GPRreg, GPRreg); }
else if (_reg_ < 9) { MOVD32MMXtoR(GPRreg, mmxVI1 + (_reg_ - 1)); } else if (_reg_ < 9) { MOVD32MMXtoR(GPRreg, mmVI(_reg_)); }
else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); } else { MOVZX32M16toR(GPRreg, (uptr)&mVU->regs->VI[_reg_].UL); }
} }
microVUt(void) mVUallocVIb(int GPRreg, int _reg_) { microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (_reg_ == 0) { return; } if (_reg_ == 0) { return; }
else if (_reg_ < 9) { MOVD32RtoMMX(mmxVI1 + (_reg_ - 1), GPRreg); } else if (_reg_ < 9) { MOVD32RtoMMX(mmVI(_reg_), GPRreg); }
else { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); } else { MOV16RtoM((uptr)&mVU->regs->VI[_reg_].UL, GPRreg); }
} }
@ -906,12 +769,23 @@ microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
// Div/Sqrt/Rsqrt Allocator Helpers // Lower Instruction Allocator Helpers
//------------------------------------------------------------------ //------------------------------------------------------------------
#define getReg5(reg, _reg_, _fxf_) { \ #define getReg5(reg, _reg_, _fxf_) { \
mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _fxf_))); \ if (!_reg_) { \
if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2<vuIndex>(reg, xmmT1, (1 << (3 - _fxf_))); \ if (_fxf_ < 3) { SSE_XORPS_XMM_to_XMM(reg, reg); } \
else { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], 3); } \
} \
else { \
mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], (1 << (3 - _fxf_))); \
if (CHECK_VU_EXTRA_OVERFLOW) mVUclamp2<vuIndex>(reg, xmmT1, (1 << (3 - _fxf_))); \
} \
} }
// Doesn't Clamp
#define getReg7(reg, _reg_) { \
if (!_reg_) { getZero(reg); } \
else { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); } \
}
#endif //PCSX2_MICROVU #endif //PCSX2_MICROVU

View File

@ -137,7 +137,7 @@ microVUf(void) mVU_RSQRT() {
#define EATANhelper(addr) { \ #define EATANhelper(addr) { \
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \ SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \ SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \
SSE_MOVSS_XMM_to_XMM(xmmFt, xmmT1); \ SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmT1); \
SSE_MULSS_M32_to_XMM(xmmFt, (uptr)addr); \ SSE_MULSS_M32_to_XMM(xmmFt, (uptr)addr); \
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \ SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \
} }
@ -147,7 +147,7 @@ microVUt(void) mVU_EATAN_() {
// ToDo: Can Be Optimized Further? (takes approximately (~115 cycles + mem access time) on a c2d) // ToDo: Can Be Optimized Further? (takes approximately (~115 cycles + mem access time) on a c2d)
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE_MULSS_M32_to_XMM(xmmPQ, (uptr)mVU_T1); SSE_MULSS_M32_to_XMM(xmmPQ, (uptr)mVU_T1);
SSE_MOVSS_XMM_to_XMM(xmmT1, xmmFs); SSE_MOVAPS_XMM_to_XMM(xmmT1, xmmFs);
EATANhelper(mVU_T2); EATANhelper(mVU_T2);
EATANhelper(mVU_T3); EATANhelper(mVU_T3);
@ -158,16 +158,15 @@ microVUt(void) mVU_EATAN_() {
EATANhelper(mVU_T8); EATANhelper(mVU_T8);
SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_Pi4); SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_Pi4);
SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6);
} }
microVUf(void) mVU_EATAN() { microVUf(void) mVU_EATAN() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) {}
else { else {
getReg5(xmmFs, _Fs_, _Fsf_); getReg5(xmmFs, _Fs_, _Fsf_);
SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
// ToDo: Can Be Optimized Further? (takes approximately (~125 cycles + mem access time) on a c2d)
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE_SUBSS_M32_to_XMM(xmmFs, (uptr)mVU_one); SSE_SUBSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_one); SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_one);
@ -180,9 +179,9 @@ microVUf(void) mVU_EATANxy() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) {}
else { else {
getReg5(xmmFs, _Fs_, 1); getReg6(xmmFt, _Fs_);
getReg5(xmmFt, _Fs_, 0); SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFt, 0x01);
SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE_SUBSS_M32_to_XMM(xmmFs, (uptr)mVU_one); SSE_SUBSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
@ -196,9 +195,9 @@ microVUf(void) mVU_EATANxz() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) {}
else { else {
getReg5(xmmFs, _Fs_, 2); getReg6(xmmFt, _Fs_);
getReg5(xmmFt, _Fs_, 0); SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFt, 0x02);
SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs); SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE_SUBSS_XMM_to_XMM(xmmFs, xmmFt); SSE_SUBSS_XMM_to_XMM(xmmFs, xmmFt);
@ -208,16 +207,188 @@ microVUf(void) mVU_EATANxz() {
mVU_EATAN_<vuIndex>(); mVU_EATAN_<vuIndex>();
} }
} }
microVUf(void) mVU_EEXP() {} #define eexpHelper(addr) { \
microVUf(void) mVU_ELENG() {} SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \
microVUf(void) mVU_ERCPR() {} SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmT1); \
microVUf(void) mVU_ERLENG() {} SSE_MULSS_M32_to_XMM(xmmFt, (uptr)addr); \
microVUf(void) mVU_ERSADD() {} SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \
microVUf(void) mVU_ERSQRT() {} }
microVUf(void) mVU_ESADD() {} microVUf(void) mVU_EEXP() {
microVUf(void) mVU_ESIN() {} microVU* mVU = mVUx;
microVUf(void) mVU_ESQRT() {} if (recPass == 0) {}
microVUf(void) mVU_ESUM() {} else {
getReg5(xmmFs, _Fs_, _Fsf_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE_MULSS_M32_to_XMM(xmmPQ, (uptr)mVU_E1);
SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_one);
SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmFs);
SSE_MULSS_XMM_to_XMM(xmmFt, xmmFs);
SSE_MOVAPS_XMM_to_XMM(xmmT1, xmmFt);
SSE_MULSS_M32_to_XMM(xmmFt, (uptr)mVU_E2);
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt);
eexpHelper(mVU_E3);
eexpHelper(mVU_E4);
eexpHelper(mVU_E5);
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs);
SSE_MULSS_M32_to_XMM(xmmT1, (uptr)mVU_E6);
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmT1);
SSE_MULSS_XMM_to_XMM(xmmPQ, xmmPQ);
SSE_MULSS_XMM_to_XMM(xmmPQ, xmmPQ);
SSE_MOVSS_M32_to_XMM(xmmT1, (uptr)mVU_one);
SSE_DIVSS_XMM_to_XMM(xmmT1, xmmPQ);
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmT1);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUt(void) mVU_sumXYZ() {
// regd.x = x ^ 2 + y ^ 2 + z ^ 2
if( cpucaps.hasStreamingSIMD4Extensions ) {
SSE4_DPPS_XMM_to_XMM(xmmFs, xmmFs, 0x71);
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
}
else {
SSE_MULPS_XMM_to_XMM(xmmFs, xmmFs); // wzyx ^ 2
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFs, 0xe1); // wzyx -> wzxy
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs); // x ^ 2 + y ^ 2
SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFs, 0xD2); // wzxy -> wxyz
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs); // x ^ 2 + y ^ 2 + z ^ 2
}
}
microVUf(void) mVU_ELENG() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg6(xmmFs, _Fs_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
mVU_sumXYZ<vuIndex>();
SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmPQ);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_ERCPR() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg5(xmmFs, _Fs_, _Fsf_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ);
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_ERLENG() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg6(xmmFs, _Fs_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
mVU_sumXYZ<vuIndex>();
SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmPQ);
SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ);
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_ERSADD() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg6(xmmFs, _Fs_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
mVU_sumXYZ<vuIndex>();
//SSE_RCPSS_XMM_to_XMM(xmmPQ, xmmPQ); // Lower Precision is bad?
SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ);
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_ERSQRT() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg5(xmmFs, _Fs_, _Fsf_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE_MOVSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
SSE_DIVSS_XMM_to_XMM(xmmFs, xmmPQ);
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_ESADD() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg6(xmmFs, _Fs_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
mVU_sumXYZ<vuIndex>();
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
#define esinHelper(addr) { \
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFt); \
SSE_MOVAPS_XMM_to_XMM(xmmFs, xmmT1); \
SSE_MULSS_M32_to_XMM(xmmFs, (uptr)addr); \
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs); \
}
microVUf(void) mVU_ESIN() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg5(xmmFs, _Fs_, _Fsf_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
//SSE_MULSS_M32_to_XMM(xmmPQ, (uptr)mVU_one); // Multiplying by 1 is redundant?
SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmFs);
SSE_MULSS_XMM_to_XMM(xmmFs, xmmFt);
SSE_MOVAPS_XMM_to_XMM(xmmT1, xmmFs);
SSE_MULSS_XMM_to_XMM(xmmFs, xmmFt);
SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmFs);
SSE_MULSS_M32_to_XMM(xmmFs, (uptr)mVU_S2);
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs);
esinHelper(mVU_S3);
esinHelper(mVU_S4);
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFt);
SSE_MULSS_M32_to_XMM(xmmT1, (uptr)mVU_S5);
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmT1);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_ESQRT() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg5(xmmFs, _Fs_, _Fsf_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE_SQRTSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_ESUM() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg6(xmmFs, _Fs_);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
SSE2_PSHUFD_XMM_to_XMM(xmmFt, xmmFs, 0x1b);
SSE_ADDPS_XMM_to_XMM(xmmFs, xmmFt);
SSE2_PSHUFD_XMM_to_XMM(xmmFt, xmmFs, 0x01);
SSE_ADDSS_XMM_to_XMM(xmmFs, xmmFt);
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
}
}
microVUf(void) mVU_FCAND() {} microVUf(void) mVU_FCAND() {}
microVUf(void) mVU_FCEQ() {} microVUf(void) mVU_FCEQ() {}
@ -302,8 +473,11 @@ microVUf(void) mVU_IADD() {
if (recPass == 0) {} if (recPass == 0) {}
else { else {
mVUallocVIa<vuIndex>(gprT1, _Fs_); mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_); if (_Ft_ != _Fs_) {
ADD16RtoR(gprT1, gprT2); mVUallocVIa<vuIndex>(gprT2, _Ft_);
ADD16RtoR(gprT1, gprT2);
}
else ADD16RtoR(gprT1, gprT1);
mVUallocVIb<vuIndex>(gprT1, _Fd_); mVUallocVIb<vuIndex>(gprT1, _Fd_);
} }
} }
@ -330,8 +504,10 @@ microVUf(void) mVU_IAND() {
if (recPass == 0) {} if (recPass == 0) {}
else { else {
mVUallocVIa<vuIndex>(gprT1, _Fs_); mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_); if (_Ft_ != _Fs_) {
AND32RtoR(gprT1, gprT2); mVUallocVIa<vuIndex>(gprT2, _Ft_);
AND32RtoR(gprT1, gprT2);
}
mVUallocVIb<vuIndex>(gprT1, _Fd_); mVUallocVIb<vuIndex>(gprT1, _Fd_);
} }
} }
@ -340,8 +516,10 @@ microVUf(void) mVU_IOR() {
if (recPass == 0) {} if (recPass == 0) {}
else { else {
mVUallocVIa<vuIndex>(gprT1, _Fs_); mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_); if (_Ft_ != _Fs_) {
OR32RtoR(gprT1, gprT2); mVUallocVIa<vuIndex>(gprT2, _Ft_);
OR32RtoR(gprT1, gprT2);
}
mVUallocVIb<vuIndex>(gprT1, _Fd_); mVUallocVIb<vuIndex>(gprT1, _Fd_);
} }
} }
@ -349,10 +527,16 @@ microVUf(void) mVU_ISUB() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) {}
else { else {
mVUallocVIa<vuIndex>(gprT1, _Fs_); if (_Ft_ != _Fs_) {
mVUallocVIa<vuIndex>(gprT2, _Ft_); mVUallocVIa<vuIndex>(gprT1, _Fs_);
SUB16RtoR(gprT1, gprT2); mVUallocVIa<vuIndex>(gprT2, _Ft_);
mVUallocVIb<vuIndex>(gprT1, _Fd_); SUB16RtoR(gprT1, gprT2);
}
else if (!isMMX(_Fd_)) {
XOR32RtoR(gprT1, gprT1);
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
else { PXORRtoR(mmVI(_Fd_), mmVI(_Fd_)); }
} }
} }
microVUf(void) mVU_ISUBIU() { microVUf(void) mVU_ISUBIU() {
@ -376,14 +560,9 @@ microVUf(void) mVU_IBNE() {}
microVUf(void) mVU_JR() {} microVUf(void) mVU_JR() {}
microVUf(void) mVU_JALR() {} microVUf(void) mVU_JALR() {}
microVUf(void) mVU_ILW() {}
microVUf(void) mVU_ISW() {}
microVUf(void) mVU_ILWR() {}
microVUf(void) mVU_ISWR() {}
microVUf(void) mVU_MOVE() { microVUf(void) mVU_MOVE() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) { /*If (!_Ft_ || (_Ft_ == _Fs_)) nop();*/ }
else { else {
mVUloadReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], _X_Y_Z_W); mVUloadReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W); mVUsaveReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
@ -391,7 +570,7 @@ microVUf(void) mVU_MOVE() {
} }
microVUf(void) mVU_MFIR() { microVUf(void) mVU_MFIR() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else { else {
mVUallocVIa<vuIndex>(gprT1, _Fs_); mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOVSX32R16toR(gprT1, gprT1); MOVSX32R16toR(gprT1, gprT1);
@ -402,7 +581,7 @@ microVUf(void) mVU_MFIR() {
} }
microVUf(void) mVU_MFP() { microVUf(void) mVU_MFP() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else { else {
getPreg(xmmFt); getPreg(xmmFt);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W); mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
@ -418,21 +597,208 @@ microVUf(void) mVU_MTIR() {
} }
microVUf(void) mVU_MR32() { microVUf(void) mVU_MR32() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else { else {
mVUloadReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], (_X_Y_Z_W == 8) ? 4 : 15); mVUloadReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Fs_].UL[0], (_X_Y_Z_W == 8) ? 4 : 15);
if (_X_Y_Z_W != 8) { SSE_SHUFPS_XMM_to_XMM(xmmT1, xmmT1, 0x39); } if (_X_Y_Z_W != 8) { SSE2_PSHUFD_XMM_to_XMM(xmmT1, xmmT1, 0x39); }
mVUsaveReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W); mVUsaveReg<vuIndex>(xmmT1, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
} }
} }
microVUf(void) mVU_LQ() {} microVUf(void) mVU_ILW() {
microVUf(void) mVU_LQD() {} microVU* mVU = mVUx;
microVUf(void) mVU_LQI() {} if (recPass == 0) { /*If (!_Ft_) nop();*/ }
microVUf(void) mVU_SQ() {} else {
microVUf(void) mVU_SQD() {} if (!_Fs_) {
microVUf(void) mVU_SQI() {} MOVZX32M16toR( gprT1, (uptr)mVU->regs->Mem + getVUmem(_Imm11_) + offsetSS );
//microVUf(void) mVU_LOI() {} mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
ADD32ItoR(gprT1, _Imm11_);
mVUaddrFix<vuIndex>(gprT1);
MOV32RmSOffsettoR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS, 0); // ToDo: check if this works.
if (isMMX(_Ft_)) AND32ItoR(gprT1, 0xffff);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
}
}
microVUf(void) mVU_ILWR() {
microVU* mVU = mVUx;
if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else {
if (!_Fs_) {
MOVZX32M16toR( gprT1, (uptr)mVU->regs->Mem + offsetSS );
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUaddrFix<vuIndex>(gprT1);
MOV32RmSOffsettoR(gprT1, gprT1, (uptr)mVU->regs->Mem + offsetSS, 0); // ToDo: check if this works.
if (isMMX(_Ft_)) AND32ItoR(gprT1, 0xffff);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
}
}
microVUf(void) mVU_ISW() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (!_Fs_) {
int imm = getVUmem(_Imm11_);
mVUallocVIa<vuIndex>(gprT1, _Ft_);
if (_X) MOV32RtoM((uptr)mVU->regs->Mem + imm, gprT1);
if (_Y) MOV32RtoM((uptr)mVU->regs->Mem + imm + 4, gprT1);
if (_Z) MOV32RtoM((uptr)mVU->regs->Mem + imm + 8, gprT1);
if (_W) MOV32RtoM((uptr)mVU->regs->Mem + imm + 12, gprT1);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_);
ADD32ItoR(gprT1, _Imm11_);
mVUaddrFix<vuIndex>(gprT1);
if (_X) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem);
if (_Y) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem+4);
if (_Z) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem+8);
if (_W) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem+12);
}
}
}
microVUf(void) mVU_ISWR() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (!_Fs_) {
mVUallocVIa<vuIndex>(gprT1, _Ft_);
if (_X) MOV32RtoM((uptr)mVU->regs->Mem, gprT1);
if (_Y) MOV32RtoM((uptr)mVU->regs->Mem+4, gprT1);
if (_Z) MOV32RtoM((uptr)mVU->regs->Mem+8, gprT1);
if (_W) MOV32RtoM((uptr)mVU->regs->Mem+12, gprT1);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_);
mVUaddrFix<vuIndex>(gprT1);
if (_X) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem);
if (_Y) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem+4);
if (_Z) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem+8);
if (_W) MOV32RtoRmOffset(gprT1, gprT2, (uptr)mVU->regs->Mem+12);
}
}
}
microVUf(void) mVU_LQ() {
microVU* mVU = mVUx;
if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else {
if (!_Fs_) {
mVUloadReg<vuIndex>(xmmFt, (uptr)mVU->regs->Mem + getVUmem(_Imm11_), _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
ADD32ItoR(gprT1, _Imm11_);
mVUaddrFix<vuIndex>(gprT1);
mVUloadReg2<vuIndex>(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
}
}
microVUf(void) mVU_LQD() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (!_Fs_ && _Ft_) {
mVUloadReg<vuIndex>(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
SUB16ItoR(gprT1, 1);
mVUallocVIb<vuIndex>(gprT1, _Fs_); // ToDo: Backup to memory check.
if (_Ft_) {
mVUaddrFix<vuIndex>(gprT1);
mVUloadReg2<vuIndex>(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
}
}
}
microVUf(void) mVU_LQI() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (!_Fs_ && _Ft_) {
mVUloadReg<vuIndex>(xmmFt, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
else {
mVUallocVIa<vuIndex>((_Ft_) ? gprT1 : gprT2, _Fs_);
if (_Ft_) {
MOV32RtoR(gprT2, gprT1);
mVUaddrFix<vuIndex>(gprT1);
mVUloadReg2<vuIndex>(xmmFt, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
mVUsaveReg<vuIndex>(xmmFt, (uptr)&mVU->regs->VF[_Ft_].UL[0], _X_Y_Z_W);
}
ADD16ItoR(gprT2, 1);
mVUallocVIb<vuIndex>(gprT2, _Fs_); // ToDo: Backup to memory check.
}
}
}
microVUf(void) mVU_SQ() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (!_Ft_) {
getReg7(xmmFs, _Fs_);
mVUsaveReg<vuIndex>(xmmFs, (uptr)mVU->regs->Mem + getVUmem(_Imm11_), _X_Y_Z_W);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Ft_);
ADD32ItoR(gprT1, _Imm11_);
mVUaddrFix<vuIndex>(gprT1);
getReg7(xmmFs, _Fs_);
mVUsaveReg2<vuIndex>(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
}
}
}
microVUf(void) mVU_SQD() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (!_Ft_) {
getReg7(xmmFs, _Fs_);
mVUsaveReg<vuIndex>(xmmFs, (uptr)mVU->regs->Mem, _X_Y_Z_W);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Ft_);
SUB16ItoR(gprT1, 1);
mVUallocVIb<vuIndex>(gprT1, _Ft_); // ToDo: Backup to memory check.
mVUaddrFix<vuIndex>(gprT1);
getReg7(xmmFs, _Fs_);
mVUsaveReg2<vuIndex>(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
}
}
}
microVUf(void) mVU_SQI() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (!_Ft_) {
getReg7(xmmFs, _Fs_);
mVUsaveReg<vuIndex>(xmmFs, (uptr)mVU->regs->Mem, _X_Y_Z_W);
}
else {
mVUallocVIa<vuIndex>(gprT1, _Ft_);
MOV32RtoR(gprT2, gprT1);
mVUaddrFix<vuIndex>(gprT1);
getReg7(xmmFs, _Fs_);
mVUsaveReg2<vuIndex>(xmmFs, gprT1, (uptr)mVU->regs->Mem, _X_Y_Z_W);
ADD16ItoR(gprT2, 1);
mVUallocVIb<vuIndex>(gprT2, _Ft_); // ToDo: Backup to memory check.
}
}
}
microVUf(void) mVU_RINIT() {} microVUf(void) mVU_RINIT() {}
microVUf(void) mVU_RGET() {} microVUf(void) mVU_RGET() {}

View File

@ -21,16 +21,11 @@
//------------------------------------------------------------------ //------------------------------------------------------------------
// Global Variables // Global Variables
//------------------------------------------------------------------ //------------------------------------------------------------------
PCSX2_ALIGNED16_EXTERN(const u32 mVU_absclip[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_absclip[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_signbit[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_signbit[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_minvals[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_minvals[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_maxvals[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_maxvals[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_FTOI_4[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_FTOI_12[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_FTOI_15[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_4[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_12[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_15[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_T1[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_T1[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_T2[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_T2[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_T3[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_T3[4]);
@ -40,6 +35,22 @@ PCSX2_ALIGNED16_EXTERN(const u32 mVU_T6[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_T7[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_T7[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_T8[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_T8[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_Pi4[4]); PCSX2_ALIGNED16_EXTERN(const u32 mVU_Pi4[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_S2[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_S3[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_S4[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_S5[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_E1[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_E2[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_E3[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_E4[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_E5[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_E6[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_FTOI_4[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_FTOI_12[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_FTOI_15[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_4[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_12[4]);
PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_15[4]);
//------------------------------------------------------------------ //------------------------------------------------------------------
// Helper Macros // Helper Macros
@ -73,6 +84,9 @@ PCSX2_ALIGNED16_EXTERN(const u32 mVU_Pi4[4]);
#define _Imm5_ (((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf)) #define _Imm5_ (((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf))
#define _Imm15_ (((mVU->code >> 10) & 0x7800) | (mVU->code & 0x7ff)) #define _Imm15_ (((mVU->code >> 10) & 0x7800) | (mVU->code & 0x7ff))
#define getVUmem(x) (((vuIndex == 1) ? (x & 0x3ff) : ((x >= 0x400) ? (x & 0x43f) : (x & 0xff))) * 16)
#define offsetSS ((_X) ? (0) : ((_Y) ? (4) : ((_Z) ? 8: 12)))
#define xmmT1 0 // Temp Reg #define xmmT1 0 // Temp Reg
#define xmmFs 1 // Holds the Value of Fs (writes back result Fd) #define xmmFs 1 // Holds the Value of Fs (writes back result Fd)
#define xmmFt 2 // Holds the Value of Ft #define xmmFt 2 // Holds the Value of Ft
@ -129,4 +143,7 @@ PCSX2_ALIGNED16_EXTERN(const u32 mVU_Pi4[4]);
//#define getFs (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<13)) //#define getFs (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<13))
//#define getFt (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<14)) //#define getFt (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<14))
#define isMMX(_VIreg_) (_VIreg_ >= 1 && _VIreg_ <=9)
#define mmVI(_VIreg_) (_VIreg_ - 1)
#include "microVU_Misc.inl" #include "microVU_Misc.inl"

View File

@ -73,82 +73,113 @@ microVUx(void) mVUunpack_xyzw(int dstreg, int srcreg, int xyzw) {
} }
} }
microVUx(void) mVUloadReg(int reg, u32 offset, int xyzw) { microVUx(void) mVUloadReg(int reg, uptr offset, int xyzw) {
switch( xyzw ) { switch( xyzw ) {
case 8: SSE_MOVSS_M32_to_XMM(reg, offset); break; // X case 8: SSE_MOVSS_M32_to_XMM(reg, offset); break; // X
case 4: SSE_MOVSS_M32_to_XMM(reg, offset+4); break; // Y case 4: SSE_MOVSS_M32_to_XMM(reg, offset+4); break; // Y
case 2: SSE_MOVSS_M32_to_XMM(reg, offset+8); break; // Z case 2: SSE_MOVSS_M32_to_XMM(reg, offset+8); break; // Z
case 1: SSE_MOVSS_M32_to_XMM(reg, offset+12); break; // W case 1: SSE_MOVSS_M32_to_XMM(reg, offset+12); break; // W
//case 3: SSE_MOVHPS_M64_to_XMM(reg, offset+8); break; // ZW (not sure if this is faster than default)
//case 12: SSE_MOVLPS_M64_to_XMM(reg, offset); break; // XY (not sure if this is faster than default)
default: SSE_MOVAPS_M128_to_XMM(reg, offset); break; default: SSE_MOVAPS_M128_to_XMM(reg, offset); break;
} }
} }
microVUx(void) mVUsaveReg(int reg, u32 offset, int xyzw) { microVUx(void) mVUloadReg2(int reg, int gprReg, uptr offset, int xyzw) {
switch( xyzw ) {
case 8: SSE_MOVSS_RmOffset_to_XMM(reg, gprReg, offset); break; // X
case 4: SSE_MOVSS_RmOffset_to_XMM(reg, gprReg, offset+4); break; // Y
case 2: SSE_MOVSS_RmOffset_to_XMM(reg, gprReg, offset+8); break; // Z
case 1: SSE_MOVSS_RmOffset_to_XMM(reg, gprReg, offset+12); break; // W
default: SSE_MOVAPSRmtoROffset(reg, gprReg, offset); break;
}
}
microVUx(void) mVUsaveReg(int reg, uptr offset, int xyzw) {
switch ( xyzw ) { switch ( xyzw ) {
case 1: // W case 5: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xB1);
SSE_MOVSS_XMM_to_M32(offset+12, reg); SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
break; SSE_MOVSS_XMM_to_M32(offset+4, reg);
case 2: // Z SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+8, reg); break; // YW
break; case 6: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0xc9);
case 3: // ZW SSE_MOVLPS_XMM_to_M64(offset+4, xmmT1);
SSE_MOVHPS_XMM_to_M64(offset+8, reg); break; // YZ
break; case 7: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x93); //ZYXW
case 4: // Y SSE_MOVHPS_XMM_to_M64(offset+4, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+4, reg); SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break; break; // YZW
case 5: // YW case 9: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xB1); SSE_MOVSS_XMM_to_M32(offset, reg);
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg); if ( cpucaps.hasStreamingSIMD3Extensions ) SSE3_MOVSLDUP_XMM_to_XMM(xmmT1, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+4, reg); else SSE2_PSHUFD_XMM_to_XMM(xmmT1, xmmT1, 0x55);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1); SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break; break; // XW
case 6: // YZ case 10: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0xc9); SSE_MOVSS_XMM_to_M32(offset, reg);
SSE_MOVLPS_XMM_to_M64(offset+4, xmmT1); SSE_MOVSS_XMM_to_M32(offset+8, xmmT1);
break; break; //XZ
case 7: // YZW case 11: SSE_MOVSS_XMM_to_M32(offset, reg);
SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x93); //ZYXW SSE_MOVHPS_XMM_to_M64(offset+8, reg);
SSE_MOVHPS_XMM_to_M64(offset+4, xmmT1); break; //XZW
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1); case 13: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x4b); //YXZW
break; SSE_MOVHPS_XMM_to_M64(offset, xmmT1);
case 8: // X SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
SSE_MOVSS_XMM_to_M32(offset, reg); break; // XYW
break; case 14: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
case 9: // XW SSE_MOVLPS_XMM_to_M64(offset, reg);
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg); SSE_MOVSS_XMM_to_M32(offset+8, xmmT1);
SSE_MOVSS_XMM_to_M32(offset, reg); break; // XYZ
if ( cpucaps.hasStreamingSIMD3Extensions ) SSE3_MOVSLDUP_XMM_to_XMM(xmmT1, xmmT1); case 8: SSE_MOVSS_XMM_to_M32(offset, reg); break; // X
else SSE_SHUFPS_XMM_to_XMM(xmmT1, xmmT1, 0x55); case 4: SSE_MOVSS_XMM_to_M32(offset+4, reg); break; // Y
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1); case 2: SSE_MOVSS_XMM_to_M32(offset+8, reg); break; // Z
break; case 1: SSE_MOVSS_XMM_to_M32(offset+12, reg); break; // W
case 10: //XZ case 12: SSE_MOVLPS_XMM_to_M64(offset, reg); break; // XY
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg); case 3: SSE_MOVHPS_XMM_to_M64(offset+8, reg); break; // ZW
SSE_MOVSS_XMM_to_M32(offset, reg); default: SSE_MOVAPS_XMM_to_M128(offset, reg); break; // XYZW
SSE_MOVSS_XMM_to_M32(offset+8, xmmT1); }
break; }
case 11: //XZW
SSE_MOVSS_XMM_to_M32(offset, reg); microVUx(void) mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) {
SSE_MOVHPS_XMM_to_M64(offset+8, reg); switch ( xyzw ) {
break; case 5: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xB1);
case 12: // XY SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVLPS_XMM_to_M64(offset, reg); SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+4, reg);
break; SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+12, xmmT1);
case 13: // XYW break; // YW
SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x4b); //YXZW case 6: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0xc9);
SSE_MOVHPS_XMM_to_M64(offset, xmmT1); SSE_MOVLPS_XMM_to_RmOffset(gprReg, offset+4, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1); break; // YZ
break; case 7: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x93); //ZYXW
case 14: // XYZ SSE_MOVHPS_XMM_to_RmOffset(gprReg, offset+4, xmmT1);
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg); SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+12, xmmT1);
SSE_MOVLPS_XMM_to_M64(offset, reg); break; // YZW
SSE_MOVSS_XMM_to_M32(offset+8, xmmT1); case 9: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
break; SSE_MOVSS_XMM_to_RmOffset(gprReg, offset, reg);
case 15: // XYZW if ( cpucaps.hasStreamingSIMD3Extensions ) SSE3_MOVSLDUP_XMM_to_XMM(xmmT1, xmmT1);
SSE_MOVAPS_XMM_to_M128(offset, reg); else SSE2_PSHUFD_XMM_to_XMM(xmmT1, xmmT1, 0x55);
break; SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+12, xmmT1);
break; // XW
case 10: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset, reg);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+8, xmmT1);
break; //XZ
case 11: SSE_MOVSS_XMM_to_RmOffset(gprReg, offset, reg);
SSE_MOVHPS_XMM_to_RmOffset(gprReg, offset+8, reg);
break; //XZW
case 13: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x4b); //YXZW
SSE_MOVHPS_XMM_to_RmOffset(gprReg, offset, xmmT1);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+12, xmmT1);
break; // XYW
case 14: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVLPS_XMM_to_RmOffset(gprReg, offset, reg);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+8, xmmT1);
break; // XYZ
case 8: SSE_MOVSS_XMM_to_RmOffset(gprReg, offset, reg); break; // X
case 4: SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+4, reg); break; // Y
case 2: SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+8, reg); break; // Z
case 1: SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+12, reg); break; // W
case 12: SSE_MOVLPS_XMM_to_RmOffset(gprReg, offset, reg); break; // XY
case 3: SSE_MOVHPS_XMM_to_RmOffset(gprReg, offset+8, reg); break; // ZW
default: SSE_MOVAPSRtoRmOffset(gprReg, offset, reg); break; // XYZW
} }
} }
@ -174,10 +205,10 @@ microVUx(void) mVUmergeRegs(int dest, int src, int xyzw) {
SSE2_MOVSD_XMM_to_XMM(dest, src); SSE2_MOVSD_XMM_to_XMM(dest, src);
break; break;
case 5: SSE_SHUFPS_XMM_to_XMM(dest, src, 0xd8); case 5: SSE_SHUFPS_XMM_to_XMM(dest, src, 0xd8);
SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xd8); SSE2_PSHUFD_XMM_to_XMM(dest, dest, 0xd8);
break; break;
case 6: SSE_SHUFPS_XMM_to_XMM(dest, src, 0x9c); case 6: SSE_SHUFPS_XMM_to_XMM(dest, src, 0x9c);
SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x78); SSE2_PSHUFD_XMM_to_XMM(dest, dest, 0x78);
break; break;
case 7: SSE_MOVSS_XMM_to_XMM(src, dest); case 7: SSE_MOVSS_XMM_to_XMM(src, dest);
SSE_MOVAPS_XMM_to_XMM(dest, src); SSE_MOVAPS_XMM_to_XMM(dest, src);
@ -185,10 +216,10 @@ microVUx(void) mVUmergeRegs(int dest, int src, int xyzw) {
case 8: SSE_MOVSS_XMM_to_XMM(dest, src); case 8: SSE_MOVSS_XMM_to_XMM(dest, src);
break; break;
case 9: SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc9); case 9: SSE_SHUFPS_XMM_to_XMM(dest, src, 0xc9);
SSE_SHUFPS_XMM_to_XMM(dest, dest, 0xd2); SSE2_PSHUFD_XMM_to_XMM(dest, dest, 0xd2);
break; break;
case 10: SSE_SHUFPS_XMM_to_XMM(dest, src, 0x8d); case 10: SSE_SHUFPS_XMM_to_XMM(dest, src, 0x8d);
SSE_SHUFPS_XMM_to_XMM(dest, dest, 0x72); SSE2_PSHUFD_XMM_to_XMM(dest, dest, 0x72);
break; break;
case 11: SSE_MOVSS_XMM_to_XMM(dest, src); case 11: SSE_MOVSS_XMM_to_XMM(dest, src);
SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4); SSE_SHUFPS_XMM_to_XMM(dest, src, 0xe4);
@ -210,4 +241,23 @@ microVUx(void) mVUmergeRegs(int dest, int src, int xyzw) {
} }
} }
// Transforms the Address in gprReg to valid VU0/VU1 Address
microVUt(void) mVUaddrFix(int gprReg) {
if ( vuIndex == 1 ) {
AND32ItoR(EAX, 0x3ff); // wrap around
SHL32ItoR(EAX, 4);
}
else {
u8 *jmpA, *jmpB;
CMP32ItoR(EAX, 0x400);
jmpA = JL8(0); // if addr >= 0x4000, reads VU1's VF regs and VI regs
AND32ItoR(EAX, 0x43f);
jmpB = JMP8(0);
x86SetJ8(jmpA);
AND32ItoR(EAX, 0xff); // if addr < 0x4000, wrap around
x86SetJ8(jmpB);
SHL32ItoR(EAX, 4); // multiply by 16 (shift left by 4)
}
}
#endif //PCSX2_MICROVU #endif //PCSX2_MICROVU

View File

@ -78,12 +78,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
// Helper Macros // Helper Macros
//------------------------------------------------------------------ //------------------------------------------------------------------
// FMAC1 - Normal FMAC Opcodes
#define mVU_FMAC1(operation) { \ #define mVU_FMAC1(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, Fs, Ft; \ int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC1a<vuIndex>(Fd, Fs, Ft); \ mVUallocFMAC1a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -91,13 +91,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC1b<vuIndex>(Fd); \ mVUallocFMAC1b<vuIndex>(Fd); \
} \ } \
} }
// FMAC3 - BC(xyzw) FMAC Opcodes
#define mVU_FMAC3(operation) { \ #define mVU_FMAC3(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, Fs, Ft; \ int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC3a<vuIndex>(Fd, Fs, Ft); \ mVUallocFMAC3a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -105,13 +104,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC3b<vuIndex>(Fd); \ mVUallocFMAC3b<vuIndex>(Fd); \
} \ } \
} }
// FMAC4 - FMAC Opcodes Storing Result to ACC
#define mVU_FMAC4(operation) { \ #define mVU_FMAC4(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACC, Fs, Ft; \ int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC4a<vuIndex>(ACC, Fs, Ft); \ mVUallocFMAC4a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -119,13 +117,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC4b<vuIndex>(ACC, Fs); \ mVUallocFMAC4b<vuIndex>(ACC, Fs); \
} \ } \
} }
// FMAC5 - FMAC BC(xyzw) Opcodes Storing Result to ACC
#define mVU_FMAC5(operation) { \ #define mVU_FMAC5(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACC, Fs, Ft; \ int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC5a<vuIndex>(ACC, Fs, Ft); \ mVUallocFMAC5a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -133,13 +130,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC5b<vuIndex>(ACC, Fs); \ mVUallocFMAC5b<vuIndex>(ACC, Fs); \
} \ } \
} }
// FMAC6 - Normal FMAC Opcodes (I Reg)
#define mVU_FMAC6(operation) { \ #define mVU_FMAC6(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, Fs, Ft; \ int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC6a<vuIndex>(Fd, Fs, Ft); \ mVUallocFMAC6a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -147,13 +143,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC6b<vuIndex>(Fd); \ mVUallocFMAC6b<vuIndex>(Fd); \
} \ } \
} }
// FMAC7 - FMAC Opcodes Storing Result to ACC (I Reg)
#define mVU_FMAC7(operation) { \ #define mVU_FMAC7(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACC, Fs, Ft; \ int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC7a<vuIndex>(ACC, Fs, Ft); \ mVUallocFMAC7a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -161,13 +156,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC7b<vuIndex>(ACC, Fs); \ mVUallocFMAC7b<vuIndex>(ACC, Fs); \
} \ } \
} }
// FMAC8 - MADD FMAC Opcode Storing Result to Fd
#define mVU_FMAC8(operation) { \ #define mVU_FMAC8(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC8a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC8a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -181,13 +175,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC8b<vuIndex>(Fd); \ mVUallocFMAC8b<vuIndex>(Fd); \
} \ } \
} }
// FMAC9 - MSUB FMAC Opcode Storing Result to Fd
#define mVU_FMAC9(operation) { \ #define mVU_FMAC9(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC9a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC9a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -201,13 +194,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC9b<vuIndex>(Fd); \ mVUallocFMAC9b<vuIndex>(Fd); \
} \ } \
} }
// FMAC10 - MADD FMAC BC(xyzw) Opcode Storing Result to Fd
#define mVU_FMAC10(operation) { \ #define mVU_FMAC10(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC10a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC10a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -221,13 +213,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC10b<vuIndex>(Fd); \ mVUallocFMAC10b<vuIndex>(Fd); \
} \ } \
} }
// FMAC11 - MSUB FMAC BC(xyzw) Opcode Storing Result to Fd
#define mVU_FMAC11(operation) { \ #define mVU_FMAC11(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC11a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC11a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -241,13 +232,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC11b<vuIndex>(Fd); \ mVUallocFMAC11b<vuIndex>(Fd); \
} \ } \
} }
// FMAC12 - MADD FMAC Opcode Storing Result to Fd (I Reg)
#define mVU_FMAC12(operation) { \ #define mVU_FMAC12(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC12a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC12a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -261,13 +251,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC12b<vuIndex>(Fd); \ mVUallocFMAC12b<vuIndex>(Fd); \
} \ } \
} }
// FMAC13 - MSUB FMAC Opcode Storing Result to Fd (I Reg)
#define mVU_FMAC13(operation) { \ #define mVU_FMAC13(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC13a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC13a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -281,13 +270,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC13b<vuIndex>(Fd); \ mVUallocFMAC13b<vuIndex>(Fd); \
} \ } \
} }
// FMAC14 - MADDA FMAC Opcode
#define mVU_FMAC14(operation) { \ #define mVU_FMAC14(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC14a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC14a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -301,13 +289,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC14b<vuIndex>(ACCw, Fs); \ mVUallocFMAC14b<vuIndex>(ACCw, Fs); \
} \ } \
} }
// FMAC15 - MSUBA FMAC Opcode
#define mVU_FMAC15(operation) { \ #define mVU_FMAC15(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC15a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC15a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -321,13 +308,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC15b<vuIndex>(ACCw, ACCr); \ mVUallocFMAC15b<vuIndex>(ACCw, ACCr); \
} \ } \
} }
// FMAC16 - MADDA BC(xyzw) FMAC Opcode
#define mVU_FMAC16(operation) { \ #define mVU_FMAC16(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC16a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC16a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -341,13 +327,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC16b<vuIndex>(ACCw, Fs); \ mVUallocFMAC16b<vuIndex>(ACCw, Fs); \
} \ } \
} }
// FMAC17 - MSUBA BC(xyzw) FMAC Opcode
#define mVU_FMAC17(operation) { \ #define mVU_FMAC17(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC17a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC17a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -361,26 +346,24 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC17b<vuIndex>(ACCw, ACCr); \ mVUallocFMAC17b<vuIndex>(ACCw, ACCr); \
} \ } \
} }
// FMAC18 - OPMULA FMAC Opcode
#define mVU_FMAC18(operation) { \ #define mVU_FMAC18(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACC, Fs, Ft; \ int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC18a<vuIndex>(ACC, Fs, Ft); \ mVUallocFMAC18a<vuIndex>(ACC, Fs, Ft); \
SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
mVUupdateFlags<vuIndex>(Fs, xmmT1, Ft, _X_Y_Z_W, 0); \ mVUupdateFlags<vuIndex>(Fs, xmmT1, Ft, _X_Y_Z_W, 0); \
mVUallocFMAC18b<vuIndex>(ACC, Fs); \ mVUallocFMAC18b<vuIndex>(ACC, Fs); \
} \ } \
} }
// FMAC19 - OPMULA FMAC Opcode
#define mVU_FMAC19(operation) { \ #define mVU_FMAC19(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC19a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC19a<vuIndex>(Fd, ACC, Fs, Ft); \
SSE_MULPS_XMM_to_XMM(Fs, Ft); \ SSE_MULPS_XMM_to_XMM(Fs, Ft); \
SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \ SSE_##operation##PS_XMM_to_XMM(ACC, Fs); \
@ -388,13 +371,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC19b<vuIndex>(Fd); \ mVUallocFMAC19b<vuIndex>(Fd); \
} \ } \
} }
// FMAC20 - MADDA FMAC Opcode (I Reg)
#define mVU_FMAC20(operation) { \ #define mVU_FMAC20(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC20a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC20a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -408,13 +390,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC20b<vuIndex>(ACCw, Fs); \ mVUallocFMAC20b<vuIndex>(ACCw, Fs); \
} \ } \
} }
// FMAC21 - MSUBA FMAC Opcode (I Reg)
#define mVU_FMAC21(operation) { \ #define mVU_FMAC21(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC21a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC21a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -428,13 +409,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC21b<vuIndex>(ACCw, ACCr); \ mVUallocFMAC21b<vuIndex>(ACCw, ACCr); \
} \ } \
} }
// FMAC22 - Normal FMAC Opcodes (Q Reg)
#define mVU_FMAC22(operation) { \ #define mVU_FMAC22(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, Fs, Ft; \ int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC22a<vuIndex>(Fd, Fs, Ft); \ mVUallocFMAC22a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -442,13 +422,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC22b<vuIndex>(Fd); \ mVUallocFMAC22b<vuIndex>(Fd); \
} \ } \
} }
// FMAC23 - FMAC Opcodes Storing Result to ACC (Q Reg)
#define mVU_FMAC23(operation) { \ #define mVU_FMAC23(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACC, Fs, Ft; \ int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC23a<vuIndex>(ACC, Fs, Ft); \ mVUallocFMAC23a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \ if (_XYZW_SS && _X) SSE_##operation##SS_XMM_to_XMM(Fs, Ft); \
else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \ else SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
@ -456,13 +435,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC23b<vuIndex>(ACC, Fs); \ mVUallocFMAC23b<vuIndex>(ACC, Fs); \
} \ } \
} }
// FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg)
#define mVU_FMAC24(operation) { \ #define mVU_FMAC24(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC24a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC24a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -476,13 +454,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC24b<vuIndex>(Fd); \ mVUallocFMAC24b<vuIndex>(Fd); \
} \ } \
} }
// FMAC25 - MSUB FMAC Opcode Storing Result to Fd (Q Reg)
#define mVU_FMAC25(operation) { \ #define mVU_FMAC25(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int Fd, ACC, Fs, Ft; \ int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC25a<vuIndex>(Fd, ACC, Fs, Ft); \ mVUallocFMAC25a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -496,13 +473,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC25b<vuIndex>(Fd); \ mVUallocFMAC25b<vuIndex>(Fd); \
} \ } \
} }
// FMAC26 - MADDA FMAC Opcode (Q Reg)
#define mVU_FMAC26(operation) { \ #define mVU_FMAC26(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC26a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC26a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -516,13 +492,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
mVUallocFMAC26b<vuIndex>(ACCw, Fs); \ mVUallocFMAC26b<vuIndex>(ACCw, Fs); \
} \ } \
} }
// FMAC27 - MSUBA FMAC Opcode (Q Reg)
#define mVU_FMAC27(operation) { \ #define mVU_FMAC27(operation) { \
microVU* mVU = mVUx; \ microVU* mVU = mVUx; \
if (recPass == 0) {} \ if (recPass == 0) {} \
else { \ else { \
int ACCw, ACCr, Fs, Ft; \ int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC27a<vuIndex>(ACCw, ACCr, Fs, Ft); \ mVUallocFMAC27a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \ if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \ SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -546,7 +521,6 @@ microVUf(void) mVU_ABS() {
if (recPass == 0) {} if (recPass == 0) {}
else { else {
int Fs, Ft; int Fs, Ft;
if (isNOP) return;
mVUallocFMAC2a<vuIndex>(Fs, Ft); mVUallocFMAC2a<vuIndex>(Fs, Ft);
SSE_ANDPS_M128_to_XMM(Fs, (uptr)mVU_absclip); SSE_ANDPS_M128_to_XMM(Fs, (uptr)mVU_absclip);
mVUallocFMAC1b<vuIndex>(Ft); mVUallocFMAC1b<vuIndex>(Ft);
@ -646,7 +620,6 @@ microVUq(void) mVU_FTOIx(uptr addr) {
if (recPass == 0) {} if (recPass == 0) {}
else { else {
int Fs, Ft; int Fs, Ft;
if (isNOP) return;
mVUallocFMAC2a<vuIndex>(Fs, Ft); mVUallocFMAC2a<vuIndex>(Fs, Ft);
// Note: For help understanding this algorithm see recVUMI_FTOI_Saturate() // Note: For help understanding this algorithm see recVUMI_FTOI_Saturate()
@ -672,7 +645,6 @@ microVUq(void) mVU_ITOFx(uptr addr) {
if (recPass == 0) {} if (recPass == 0) {}
else { else {
int Fs, Ft; int Fs, Ft;
if (isNOP) return;
mVUallocFMAC2a<vuIndex>(Fs, Ft); mVUallocFMAC2a<vuIndex>(Fs, Ft);
SSE2_CVTDQ2PS_XMM_to_XMM(Ft, Fs); SSE2_CVTDQ2PS_XMM_to_XMM(Ft, Fs);