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
#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
export ZEROGSOPTIONS="--enable-sse2"

View File

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

View File

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

View File

@ -20,7 +20,7 @@
#include <ctype.h>
#include "PsxCommon.h"
#include "IopCommon.h"
#include "CDVDiso.h"
static cdvdStruct cdvd;
@ -462,7 +462,7 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
// get main elf name
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]);
// convert the number characters to a real 32bit number

View File

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

View File

@ -144,79 +144,259 @@ void WriteTLB(int 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 Interpreter {
namespace OpcodeImpl {
namespace COP0 {
void MFC0() {
if (!_Rt_) return;
if (_Rd_ != 9) { COP0_LOG("%s\n", disR5900Current.getCString() ); }
void MFC0()
{
// 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_]);
switch (_Rd_) {
case 12: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)(cpuRegs.CP0.r[_Rd_] & 0xf0c79c1f); break;
switch (_Rd_)
{
case 12:
cpuRegs.GPR.r[_Rt_].SD[0] = (s32)(cpuRegs.CP0.r[_Rd_] & 0xf0c79c1f);
break;
case 25:
switch(_Imm_ & 0x3F){
case 0: cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pccr; break;
case 1:
if((cpuRegs.PERF.n.pccr & 0x800003E0) == 0x80000020) {
cpuRegs.PERF.n.pcr0 += cpuRegs.cycle-s_iLastPERFCycle[0];
s_iLastPERFCycle[0] = cpuRegs.cycle;
}
cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pcr0;
break;
case 3:
if((cpuRegs.PERF.n.pccr & 0x800F8000) == 0x80008000) {
cpuRegs.PERF.n.pcr1 += cpuRegs.cycle-s_iLastPERFCycle[1];
s_iLastPERFCycle[1] = cpuRegs.cycle;
}
cpuRegs.GPR.r[_Rt_].UD[0] = (s64)cpuRegs.PERF.n.pcr1;
break;
switch(_Imm_ & 0x3F)
{
case 0: // MFPS [LSB is clear]
cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pccr.val;
break;
case 1: // MFPC [LSB is set] - read PCR0
COP0_UpdatePCCR();
cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr0;
break;
case 3: // MFPC [LSB is set] - read PCR1
COP0_UpdatePCCR();
cpuRegs.GPR.r[_Rt_].SD[0] = (s32)cpuRegs.PERF.n.pcr1;
break;
}
/*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);*/
break;
break;
case 24:
SysPrintf("MFC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF);
break;
Console::WriteLn("MFC0 Breakpoint debug Registers code = %x", params cpuRegs.code & 0x3FF);
break;
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;
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());
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) {
switch (_Rd_)
{
case 25:
/*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);*/
switch(_Imm_ & 0x3F){
case 0:
if((cpuRegs.PERF.n.pccr & 0x800003E0) == 0x80000020)
cpuRegs.PERF.n.pcr0 += cpuRegs.cycle-s_iLastPERFCycle[0];
if((cpuRegs.PERF.n.pccr & 0x800F8000) == 0x80008000)
cpuRegs.PERF.n.pcr1 += cpuRegs.cycle-s_iLastPERFCycle[1];
cpuRegs.PERF.n.pccr = cpuRegs.GPR.r[_Rt_].UL[0];
switch(_Imm_ & 0x3F)
{
case 0: // MTPS [LSB is clear]
// Updates PCRs and sets the PCCR.
COP0_UpdatePCCR();
cpuRegs.PERF.n.pccr.val = 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;
break;
case 3: // MTPC [LSB is set] - set PCR0
cpuRegs.PERF.n.pcr1 = cpuRegs.GPR.r[_Rt_].UL[0];
s_iLastPERFCycle[1] = cpuRegs.cycle;
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;
break;
case 24:
SysPrintf("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF);
break;
Console::WriteLn("MTC0 Breakpoint debug Registers code = %x", params cpuRegs.code & 0x3FF);
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;
default: cpuRegs.CP0.r[_Rd_] = cpuRegs.GPR.r[_Rt_].UL[0]; break;
case 9:
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() {
BC0(== 0);
COP0_LOG( "COP0 > BC0F\n" );
}
void BC0T() {
BC0(== 1);
COP0_LOG( "COP0 > BC0T\n" );
}
#define BC0L(cond) \
@ -248,12 +426,10 @@ void BC0T() {
void BC0FL() {
BC0L(== 0);
COP0_LOG( "COP0 > BC0FL\n" );
}
void BC0TL() {
BC0L(== 1);
COP0_LOG( "COP0 > BCOTL\n" );
}
void TLBR() {
@ -263,7 +439,6 @@ void TLBR() {
int i = cpuRegs.CP0.n.Index&0x1f;
COP0_LOG("COP0 > TLBR\n");
cpuRegs.CP0.n.PageMask = tlb[i].PageMask;
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00);
cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1);

View File

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

View File

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

View File

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

View File

@ -27,20 +27,20 @@
//#define PSXCLK 186864000 /* 36.864 Mhz */
#define PS2CLK 294912000 //hz /* 294.912 mhz */
#define PCSX2_VERSION "(beta)"
#include "Plugins.h"
#include "Misc.h"
#include "SaveState.h"
#include "DebugTools/Debug.h"
#include "R5900.h"
#include "Memory.h"
#include "Elfheader.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"
#define PCSX2_VERSION "(beta)"
#include "System.h"
#include "Pcsx2Config.h"
#endif /* __COMMON_H__ */

View File

@ -20,7 +20,7 @@
#ifndef __DEBUG_H__
#define __DEBUG_H__
#include "Misc.h"
#include "Pcsx2Config.h"
extern FILE *emuLog;
@ -73,15 +73,47 @@ namespace R3000A
#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 __Log( const char* fmt, ... );
extern bool SrcLog_CPU( 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_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_PAD( const char* fmt, ... );
extern bool SrcLog_GTE( const char* fmt, ... );
extern bool SrcLog_CDR( const char* fmt, ... );
extern bool SrcLog_GPU( const char* fmt, ... );
#define CPU_LOG (varLog & 0x00000001) && SrcLog_CPU
#define MEM_LOG (varLog & 0x00000002) && SrcLog_MEM
#define HW_LOG (varLog & 0x00000004) && SrcLog_HW
#define DMA_LOG (varLog & 0x00000008) && SrcLog_DMA
#define BIOS_LOG (varLog & 0x00000010) && SrcLog_BIOS
#define ELF_LOG (varLog & 0x00000020) && SrcLog_ELF
#define FPU_LOG (varLog & 0x00000040) && SrcLog_FPU
#define MMI_LOG (varLog & 0x00000080) && SrcLog_MMI
#define VU0_LOG (varLog & 0x00000100) && SrcLog_VU0
#define COP0_LOG (varLog & 0x00000200) && SrcLog_COP0
#define VIF_LOG (varLog & 0x00000400) && SrcLog_VIF
#define SPR_LOG (varLog & 0x00000800) && SrcLog_SPR
#define GIF_LOG (varLog & 0x00001000) && SrcLog_GIF
#define SIF_LOG (varLog & 0x00002000) && SrcLog_SIF
#define IPU_LOG (varLog & 0x00004000) && SrcLog_IPU
#define VUM_LOG (varLog & 0x00008000) && SrcLog_VUM
#define RPC_LOG (varLog & 0x00010000) && SrcLog_RPC
#define EECNT_LOG (varLog & 0x40000000) && SrcLog_EECNT
#define CPU_LOG (varLog.R5900) && SrcLog_CPU
#define MEM_LOG (varLog.Memory) && SrcLog_MEM
#define HW_LOG (varLog.Hardware) && SrcLog_HW
#define DMA_LOG (varLog.DMA) && SrcLog_DMA
#define BIOS_LOG (varLog.Bios) && SrcLog_BIOS
#define ELF_LOG (varLog.ELF) && SrcLog_ELF
#define VU0_LOG (varLog.VU0) && SrcLog_VU0
#define COP0_LOG (varLog.COP0) && SrcLog_COP0
#define VIF_LOG (varLog.VIF) && SrcLog_VIF
#define SPR_LOG (varLog.SPR) && SrcLog_SPR
#define GIF_LOG (varLog.GIF) && SrcLog_GIF
#define SIF_LOG (varLog.SIF) && SrcLog_SIF
#define IPU_LOG (varLog.IPU) && SrcLog_IPU
#define VUM_LOG (varLog.VUM) && SrcLog_VUM
#define RPC_LOG (varLog.RPC) && SrcLog_RPC
#define EECNT_LOG (varLog.Counters) && SrcLog_EECNT
#define PSXCPU_LOG (varLog & 0x00100000) && SrcLog_PSXCPU
#define PSXMEM_LOG (varLog & 0x00200000) && SrcLog_PSXMEM
#define PSXHW_LOG (varLog & 0x00400000) && SrcLog_PSXHW
#define PSXBIOS_LOG (varLog & 0x00800000) && SrcLog_PSXBIOS
#define PSXDMA_LOG (varLog & 0x01000000) && SrcLog_PSXDMA
#define PSXCNT_LOG (varLog & 0x20000000) && SrcLog_PSXCNT
#define PSXCPU_LOG (varLog.R3000A) && SrcLog_PSXCPU
#define PSXMEM_LOG (varLog.IopMemory) && SrcLog_PSXMEM
#define PSXHW_LOG (varLog.IopHardware) && SrcLog_PSXHW
#define PSXBIOS_LOG (varLog.IopBios) && SrcLog_PSXBIOS
#define PSXDMA_LOG (varLog.IopDMA) && SrcLog_PSXDMA
#define PSXCNT_LOG (varLog.IopCnt) && SrcLog_PSXCNT
//memcard has the same number as PAD_LOG for now
#define MEMCARDS_LOG (varLog & 0x02000000) && SrcLog_MEMCARDS
#define PAD_LOG (varLog & 0x02000000) && SrcLog_PAD
#define GTE_LOG (varLog & 0x04000000) && SrcLog_GTE
#define CDR_LOG (varLog & 0x08000000) && SrcLog_CDR
#define GPU_LOG (varLog & 0x10000000) && SrcLog_GPU
#define MEMCARDS_LOG (varLog.Memcards) && SrcLog_MEMCARDS
#define PAD_LOG (varLog.Pad) && SrcLog_PAD
#define CDR_LOG (varLog.CDVD) && SrcLog_CDR
#define GPU_LOG (varLog.GPU) && SrcLog_GPU
// fixme - currently we don't log cache
#define CACHE_LOG 0&&

View File

@ -148,7 +148,7 @@ static uint parseCommandLine( const char *filename )
{ // 4 + 4 + 256
const char * p;
int argc;
int i;
int i;
args_ptr -= 256;
@ -159,59 +159,47 @@ static uint parseCommandLine( const char *filename )
p = strrchr( filename, '\\' );
#else //linux
p = strrchr( filename, '/' );
if( p == NULL )
p = strchr(filename, '\\');
if( p == NULL ) p = strchr(filename, '\\');
#endif
if ( p )
{
p++;
}
if (p)
p++;
else
{
p = filename;
}
p = filename;
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
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 ) ) )
{
i--;
}
if ( PS2MEM_BASE[ args_ptr + i + 1 ] == ' ' )
{
PS2MEM_BASE[ args_ptr + i + 1 ] = 0;
}
while ( i && ( 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 ) )
{
while (i && ((PS2MEM_BASE[ args_ptr + i ] == 0) || (PS2MEM_BASE[ args_ptr + i ] == 32)))
{ i--; }
if ( PS2MEM_BASE[ args_ptr + i + 1 ] == ' ') PS2MEM_BASE[ args_ptr + i + 1 ] = 0;
while (i && (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
argc++;
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;
}
else
{
else
{
if ( ( PS2MEM_BASE[ args_ptr + i + 1 ] != 0 ) && ( PS2MEM_BASE[ args_ptr + i + 1 ] != 32 ) )
{
argc++;
if ( args_ptr - 4 - 4 - argc * 4 < 0 ) // fixme - Should this be cast to a signed int?
{
return 0;
}
((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 - 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) ||
(strnicmp( filename.c_str(), "cdrom1:", strlen("cdromN:")) == 0))
{
int fi;
fi = CDVDFS_open(filename.c_str() + strlen("cdromN:"), 1);//RDONLY
if (fi < 0)
throw Exception::FileNotFound( filename );
int fi = CDVDFS_open(filename.c_str() + strlen("cdromN:"), 1);//RDONLY
if (fi < 0) throw Exception::FileNotFound( filename );
CDVDFS_lseek( fi, 0, SEEK_SET );
rsize = CDVDFS_read( fi, (char*)data.GetPtr(), data.GetSizeInBytes() );
CDVDFS_close( fi );
@ -324,15 +312,14 @@ struct ElfObject
FILE *f;
f = fopen( filename.c_str(), "rb" );
if( f == NULL )
Exception::FileNotFound( filename );
if( f == NULL ) Exception::FileNotFound( filename );
fseek( f, 0, SEEK_SET );
rsize = fread( data.GetPtr(), 1, data.GetSizeInBytes(), f );
fclose( f );
}
if( rsize < data.GetSizeInBytes() )
throw Exception::EndOfStream( filename );
if( rsize < data.GetSizeInBytes() ) throw Exception::EndOfStream( filename );
}
u32 GetCRC() const
@ -426,37 +413,14 @@ struct ElfObject
switch ( secthead[ i ].sh_type )
{
default:
ELF_LOG("unknown %08x",secthead[i].sh_type);
break;
case 0x0:
ELF_LOG("null");
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;
case 0x0: ELF_LOG("null"); 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;
default: ELF_LOG("unknown %08x",secthead[i].sh_type); break;
}
ELF_LOG("\n");
@ -619,17 +583,6 @@ void LoadGameSpecificSettings()
g_FFXHack = 0;
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)
g_VUGameFixes |= VUFIX_XGKICKDELAY2; // Tested - still needed - arcum42
break;

View File

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

View File

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

View File

@ -19,28 +19,34 @@
#pragma once
//////////////////////////////////////////////////////////////////////////////////////////
// TestRun Parameters.
// Startup Parameters.
struct TESTRUNARGS
enum StartupMode
{
u8 enabled;
u8 jpgcapture;
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;
BootMode_Bios,
BootMode_Quick,
BootMode_Elf
};
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)

View File

@ -58,7 +58,7 @@ enum
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
{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.
// This saves 2-3 bytes per instruction where these are used. :)
"mov ecx, offset yuv2rgb_temp\n"
"mov edx, offset sse2_tables+64\n"
"mov ecx, offset %c[yuv2rgb_temp]\n"
"mov edx, offset %c[sse2_tables]+64\n"
".align 16\n"
"tworows:\n"
@ -240,15 +240,15 @@ ihatemsvc:
// unfortunately I don't think this will matter despite being
// technically potentially a little faster, but this is
// equivalent to an add or sub
"pxor xmm2, xmmword ptr [edx-0x40]\n" // xmm2 <-- 8 x (Cb - 128) << 8
"pxor xmm0, xmmword ptr [edx-0x40]\n" // xmm0 <-- 8 x (Cr - 128) << 8
"pxor xmm2, xmmword ptr [edx+%c[C_BIAS]]\n" // xmm2 <-- 8 x (Cb - 128) << 8
"pxor xmm0, xmmword ptr [edx+%c[C_BIAS]]\n" // xmm0 <-- 8 x (Cr - 128) << 8
"movaps xmm1, xmm0\n"
"movaps xmm3, xmm2\n"
"pmulhw xmm1, xmmword ptr [edx+0x10]\n"
"pmulhw xmm3, xmmword ptr [edx+0x20]\n"
"pmulhw xmm0, xmmword ptr [edx+0x30]\n"
"pmulhw xmm2, xmmword ptr [edx+0x40]\n"
"pmulhw xmm1, xmmword ptr [edx+%c[GCr_COEFF]]\n"
"pmulhw xmm3, xmmword ptr [edx+%c[GCb_COEFF]]\n"
"pmulhw xmm0, xmmword ptr [edx+%c[RCr_COEFF]]\n"
"pmulhw xmm2, xmmword ptr [edx+%c[BCb_COEFF]]\n"
"paddsw xmm1, xmm3\n"
// store for the next line; looking at the code above
// compared to the code below, I have to wonder whether
@ -270,13 +270,13 @@ ihatemsvc:
"movaps xmm5, xmm2\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"
"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 xmm7, xmmword ptr [edx+0x00]\n"
"pmulhuw xmm6, xmmword ptr [edx+%c[Y_COEFF]]\n"
"pmulhuw xmm7, xmmword ptr [edx+%c[Y_COEFF]]\n"
"paddsw xmm0, xmm6\n"
"paddsw xmm3, xmm7\n"
@ -286,7 +286,7 @@ ihatemsvc:
"paddsw xmm5, xmm7\n"
// round
"movaps xmm6, xmmword ptr [edx-0x10]\n"
"movaps xmm6, xmmword ptr [edx+%c[ROUND_1BIT]]\n"
"paddw xmm0, xmm6\n"
"paddw xmm1, xmm6\n"
"paddw xmm2, xmm6\n"
@ -342,6 +342,12 @@ ihatemsvc:
"cmp esi, 64\n"
"jne tworows\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
#error Unsupported compiler

View File

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

View File

@ -15,37 +15,25 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __PSXCOMMON_H__
#define __PSXCOMMON_H__
#include "PS2Etypes.h"
#include <assert.h>
#include "System.h"
extern long LoadCdBios;
extern int cdOpenCase;
#ifndef __IOPCOMMON_H__
#define __IOPCOMMON_H__
#define PSXCLK (36864000ULL) /* 36.864 Mhz */
#include "Plugins.h"
#include "Misc.h"
#include "SaveState.h"
#include "R3000A.h"
#include "Common.h"
#include "CdRom.h"
#include "CDVD.h"
#include "Sio.h"
#include "Sif.h"
#include "IopMem.h"
#include "IopHw.h"
#include "IopBios.h"
#include "IopDma.h"
#include "IopCounters.h"
#include "CdRom.h"
#include "Sio.h"
#include "DebugTools/Debug.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 <math.h>
#include "PsxCommon.h"
#include "IopCommon.h"
/* Config.PsxType == 1: PAL:
VBlank interlaced 50.00 Hz

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,8 +20,6 @@
#include "LnxSysExec.h"
#include "HostGui.h"
bool UseGui = true;
static bool sinit = false;
GtkWidget *FileSel;
@ -68,6 +66,7 @@ void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * )
bool ParseCommandLine(int argc, char *argv[], char *file)
{
int i = 1;
g_Startup.BootMode = BootMode_Bios;
while (i < argc)
{
@ -78,84 +77,50 @@ bool ParseCommandLine(int argc, char *argv[], char *file)
//Msgbox::Alert( phelpmsg );
return false;
}
else if (stricmp(token, "-efile") == 0)
{
token = argv[i++];
if (token != NULL)
{
efile = atoi(token);
}
}
else if (stricmp(token, "-nogui") == 0)
{
UseGui = FALSE;
g_Startup.NoGui = FALSE;
}
else if (stricmp(token, "-loadgs") == 0)
{
g_pRunGSState = argv[i++];
}
#ifdef PCSX2_DEVBUILD
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)
}
else if( strcmp(token, "-bootmode" ) == 0)
{
token = argv[i++];
if (token != NULL)
{
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;
g_Startup.BootMode = (StartupMode)atoi( token);
g_Startup.Enabled = true;
}
else if (stricmp(token, "-gs") == 0)
{
token = argv[i++];
g_TestRun.pgsdll = token;
g_Startup.gsdll = token;
}
else if (stricmp(token, "-cdvd") == 0)
{
token = argv[i++];
g_TestRun.pcdvddll = token;
g_Startup.cdvddll = token;
}
else if (stricmp(token, "-spu") == 0)
{
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)
{
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)
{
@ -183,9 +148,33 @@ void SysPrintf(const char *fmt, ...)
Console::Write(msg);
}
static std::string str_Default( "default" );
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();
PCSX2_MEM_PROTECT_END();
}
void OnStates_Load(GtkMenuItem *menuitem, gpointer user_data)
@ -319,8 +308,6 @@ bool SysInit()
mkdir(LOGS_DIR, 0755);
#ifdef PCSX2_DEVBUILD
if (g_TestRun.plogname != NULL)
emuLog = fopen(g_TestRun.plogname, "w");
if (emuLog == NULL)
emuLog = fopen(LOGS_DIR "/emuLog.txt", "wb");
#endif
@ -525,7 +512,7 @@ namespace HostGui
#endif
SysEndExecution();
if (!UseGui) exit(0);
if (g_Startup.NoGui) exit(0);
// fixme: The GUI is now capable of receiving control back from the
// emulator. Which means that when we call SysEscapeExecute() here, the

View File

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

View File

@ -18,7 +18,7 @@ RecoverySystem.cpp Saveslots.cpp
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 \
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 \
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 <string.h>
#include "Misc.h"
#include "PsxCommon.h"
#include "IopCommon.h"
#include "Mdec.h"
int iq_y[DCTSIZE2],iq_uv[DCTSIZE2];

View File

@ -19,46 +19,30 @@
#ifndef __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_.
// 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.
//extern void __fastcall memcpy_raz_udst(void *dest, const void *src, size_t bytes);
//extern void __fastcall memcpy_raz_usrc(void *dest, const void *src, size_t bytes);
//extern void __fastcall memcpy_raz_(void *dest, const void *src, size_t bytes);
#ifdef __LINUX__
extern "C" void __fastcall memcpy_amd_(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 u8 memcmp_mmx(const void* src1, const void* src2, 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_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
#define memcpy_fast memcpy_amd_
#define memcpy_aligned memcpy_amd_
#endif //Header

View File

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

View File

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

View File

@ -26,8 +26,7 @@
#include <ctype.h>
#include "Common.h"
#include "PsxCommon.h"
#include "IopCommon.h"
#include "HostGui.h"
#include "CDVDisodrv.h"
@ -52,6 +51,11 @@ char CdromId[12];
static int g_Pcsx2Recording = 0; // true 1 if recording video and sound
bool renderswitch = 0;
#define NUM_STATES 10
int StatesC = 0;
extern char strgametitle[256];
const char *LabelAuthors = {
"PCSX2, a PS2 emulator\n\n"
"Active Devs: Arcum42, Refraction,\n"
@ -80,73 +84,22 @@ const char *LabelGreets = {
"F|RES, MrBrown, razorblade, Seta-san, Skarmeth"
};
static struct {
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}
};
#define DIRENTRY_SIZE 16
void GetRPCVersion(char *ioprp, char *rpcver){
char *p=ioprp;
int i;
struct TocEntry te;
if (p && (CDVD_findfile(p+strlen("cdromN:"), &te) != -1)){
for (i=0; ioprps[i].size>0; i++)
if (te.fileSize==ioprps[i].size)
break;
if (ioprps[i].size>0)
p=(char *)ioprps[i].name;
}
// fixme - Is p really supposed to be set in the middle of an if statement?
if (p && (p=strstr(p, "IOPRP")+strlen("IOPRP"))){
for (i=0;(i<4) && p && (*p>='0') && (*p<='9');i++, p++) rpcver[i]=*p;
for ( ; i<4 ;i++ ) rpcver[i]='0';
}
}
#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
u32 GetBiosVersion() {
unsigned int fileOffset=0;
@ -267,44 +220,6 @@ int IsBIOS(char *filename, char *description)
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 f;
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D
@ -351,7 +266,6 @@ int GetPS2ElfName(char *name){
FILE *fp;
int i;
// inifile_read(CdromId);
fp = fopen("System.map", "r");
if( fp == NULL ) return 2;
@ -396,7 +310,6 @@ void SaveGSState(const string& file)
g_fGSSave->Freeze( g_nLeftGSFrames );
}
extern uptr pDsp;
void LoadGSState(const string& file)
{
int ret;
@ -448,11 +361,6 @@ void LoadGSState(const string& file)
#endif
#define NUM_STATES 10
int StatesC = 0;
extern char strgametitle[256];
char* mystrlwr( char* string )
{
assert( string != NULL );
@ -529,10 +437,10 @@ void CycleFrameLimit(int dir)
void ProcessFKeys(int fkey, int shift)
{
assert(fkey >= 1 && fkey <= 12 );
assert(fkey >= 1 && fkey <= 12 );
switch(fkey) {
case 1:
switch(fkey) {
case 1:
try
{
gzSavingState( SaveState::GetFilename( StatesC ) ).FreezeAll();
@ -653,93 +561,26 @@ void ProcessFKeys(int fkey, int shift)
#endif
case 12:
if( shift ) {
if( shift ) {
#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);
#endif
}
else {
g_Pcsx2Recording ^= 1;
if( mtgsThread != NULL ) {
}
else {
g_Pcsx2Recording ^= 1;
if( mtgsThread != NULL ) {
mtgsThread->SendSimplePacket(GS_RINGTYPE_RECORD, g_Pcsx2Recording, 0, 0);
}
else {
if( GSsetupRecording != NULL ) GSsetupRecording(g_Pcsx2Recording, NULL);
}
}
else {
if( GSsetupRecording != NULL ) GSsetupRecording(g_Pcsx2Recording, NULL);
}
if( SPU2setupRecording != NULL ) SPU2setupRecording(g_Pcsx2Recording, NULL);
}
}
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 )
{
jASSUME( (size & 0x1) == 0 );

View File

@ -56,18 +56,17 @@ extern bool g_EEFreezeRegs;
#ifndef __INTEL_COMPILER
extern "C" void FreezeXMMRegs_(int save);
extern "C" void FreezeMMXRegs_(int save);
extern "C" void FreezeRegs(int save);
#else
extern void FreezeXMMRegs_(int save);
extern void FreezeMMXRegs_(int save);
extern void FreezeRegs(int save);
#endif
// these macros check to see if needs freezing
#define FreezeXMMRegs(save) if( g_EEFreezeRegs ) { FreezeXMMRegs_(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.
extern void InitCPUTicks();
extern u64 GetCPUTicks();
@ -80,30 +79,8 @@ extern const char *LabelAuthors;
extern const char *LabelGreets;
void CycleFrameLimit(int dir);
// Only used in Misc.cpp
void SaveGSState(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__ */

View File

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

View File

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

View File

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

View File

@ -19,8 +19,7 @@
#include "PrecompiledHeader.h"
#include "PsxCommon.h"
#include "Common.h"
#include "IopCommon.h"
using namespace R3000A;
@ -380,8 +379,9 @@ void psxJALR() { if (_Rd_) { _SetLink(_Rd_); } doBranch(_u32(_rRs_)); }
static __forceinline void execI()
{
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.cycle++;
@ -395,6 +395,7 @@ static void doBranch(s32 tar) {
branch2 = iopIsDelaySlot = true;
branchPC = tar;
execI();
PSXCPU_LOG( "\n" );
iopIsDelaySlot = false;
psxRegs.pc = branchPC;

View File

@ -18,8 +18,7 @@
#include "PrecompiledHeader.h"
#include "PsxCommon.h"
#include "Common.h"
#include "IopCommon.h"
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 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 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 *

View File

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

View File

@ -52,8 +52,35 @@ union GPRregs {
};
union PERFregs {
struct {
u32 pccr, pcr0, pcr1, pad;
struct
{
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;
u32 r[4];
};

View File

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

View File

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

View File

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

View File

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

View File

@ -22,8 +22,7 @@
#include "GS.h"
TESTRUNARGS g_TestRun;
StartupParams g_Startup;
//////////////////////////////////////////////////////////////////////////////////////////
// Save Slot Detection System
@ -63,11 +62,11 @@ void States_Load( const string& file )
try
{
_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)
{
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
// 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.
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 )
message += "Since the savestate load was incomplete, the emulator must reset.\n";
@ -145,12 +144,12 @@ void States_Save( const string& file )
try
{
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 )
{
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()
);
}
@ -180,7 +179,7 @@ void States_Save(int num)
//
void vSyncDebugStuff( uint frame )
{
#ifdef PCSX2_DEVBUILD
#ifdef OLD_TESTBUILD_STUFF
if( g_TestRun.enabled && g_TestRun.frame > 0 ) {
if( frame > g_TestRun.frame ) {
// take a snapshot

View File

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

View File

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

View File

@ -37,7 +37,8 @@ using namespace R5900;
FILE *emuLog;
#ifdef PCSX2_DEVBUILD
u32 varLog;
LogSources varLog;
// these used by the depreciated _old_Log only
u16 logProtocol;
@ -67,7 +68,7 @@ void __Log( const char* fmt, ... )
// 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);
@ -105,7 +106,7 @@ static __forceinline void _vSourceLog( u16 protocol, u8 source, u32 cpuPc, u32 c
#endif
#endif
if (varLog & 0x80000000) // log to console enabled?
if (varLog.LogToConsole) // log to console enabled?
{
Console::WriteLn(tmp);
@ -145,7 +146,6 @@ IMPLEMENT_SOURCE_LOG( BIOS, 'E', 0 )
IMPLEMENT_SOURCE_LOG( CPU, 'E', 1 )
IMPLEMENT_SOURCE_LOG( FPU, 'E', 1 )
IMPLEMENT_SOURCE_LOG( MMI, 'E', 1 )
IMPLEMENT_SOURCE_LOG( COP0, 'E', 1 )
IMPLEMENT_SOURCE_LOG( MEM, 'E', 6 )

View File

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

View File

@ -391,7 +391,7 @@ void SysPrepareExecution( const char* elf_file, bool use_bios )
return;
}
if (OpenPlugins(g_TestRun.ptitle) == -1)
if (OpenPlugins(NULL) == -1)
return;
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.
// (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];
ename[0] = 0;
if( !use_bios )

View File

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

View File

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

View File

@ -35,12 +35,13 @@ else
DEBUG_FLAGS=" -O0 -g "
fi
WARNING_FLAGS="-Wall -Wno-format -Wno-unused-value"
NORMAL_FLAGS=" -pipe -msse -msse2 -O2 "
WARNING_FLAGS="-Wno-format -Wno-unused-value"
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.
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
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_MSG_CHECKING(turn on memcpy_fast_)
AC_ARG_ENABLE(memcpyfast, AC_HELP_STRING([--enable-memcpyfast], [Turns on memcpy_fast - EXPERIMENTAL]),
memcpyfast=$enableval,memcpyfast=no)
if test "x$memcpyfast" == xyes
then
AC_DEFINE(LINUX_USE_FAST_MEMORY,1,[LINUX_USE_FAST_MEMORY])
fi
AC_MSG_RESULT($memcpyfast)
#AC_MSG_CHECKING(turn on memcpy_fast_)
#AC_ARG_ENABLE(memcpyfast, AC_HELP_STRING([--enable-memcpyfast], [Turns on memcpy_fast - EXPERIMENTAL]),
#memcpyfast=$enableval,memcpyfast=no)
#if test "x$memcpyfast" == xyes
#then
# AC_DEFINE(LINUX_USE_FAST_MEMORY,1,[LINUX_USE_FAST_MEMORY])
#fi
#AC_MSG_RESULT($memcpyfast)
#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]),

View File

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

View File

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

View File

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

View File

@ -55,36 +55,26 @@ void strcatz(char *dst, char *src)
strcpy(dst + len, src);
}
//2002-09-20 (Florin)
BOOL APIENTRY CmdlineProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);//forward def
//-------------------
static const char* phelpmsg =
"pcsx2 [options] [file]\n\n"
"-cfg [file] {configuration file}\n"
"-efile [efile] {0 - reset, 1 - runcd (default), 2 - loadelf}\n"
"-help {display this help file}\n"
"-nogui {Don't use gui when launching}\n"
"-loadgs [file] {Loads a gsstate}\n"
"pcsx2 [options] [cdimage/elf file]\n\n"
"\t-cfg [file] {configuration file}\n"
"\t-bootmode [mode] {0 - quick (default), 1 - bios, 2 - load elf}\n"
"\t-nogui {disables display of the gui - skips right to opening the GS window}"
"\t-help {display this help file}\n"
"\t-loadgs [file] {Loads a gsstate}\n\n"
"Run without GUI Options:\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"
"\t-cdvd [dllpath] {specifies an override for the CDVD 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-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-pad2 [dllpath] {specifies an override for the PAD2 plugin only}\n"
"\t-dev9 [dllpath] {specifies an override for the DEV9 plugin}\n"
@ -189,21 +179,6 @@ void WinClose()
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] )
{
if( src == NULL || src[0] == 0 ) return;
@ -219,12 +194,12 @@ void WinRun()
memcpy( &winConfig, &Config, sizeof( PcsxConfig ) );
_doPluginOverride( "GS", g_TestRun.pgsdll, Config.GS );
_doPluginOverride( "CDVD", g_TestRun.pcdvddll, Config.CDVD );
_doPluginOverride( "SPU2", g_TestRun.pspudll, Config.SPU2 );
_doPluginOverride( "PAD1", g_TestRun.ppad1dll, Config.PAD1 );
_doPluginOverride( "PAD2", g_TestRun.ppad2dll, Config.PAD2 );
_doPluginOverride( "DEV9", g_TestRun.pdev9dll, Config.DEV9 );
_doPluginOverride( "GS", g_Startup.gsdll, Config.GS );
_doPluginOverride( "CDVD", g_Startup.cdvddll, Config.CDVD );
_doPluginOverride( "SPU2", g_Startup.spudll, Config.SPU2 );
_doPluginOverride( "PAD1", g_Startup.pad1dll, Config.PAD1 );
_doPluginOverride( "PAD2", g_Startup.pad2dll, Config.PAD2 );
_doPluginOverride( "DEV9", g_Startup.dev9dll, Config.DEV9 );
#ifndef _DEBUG
@ -239,8 +214,6 @@ void WinRun()
if (Pcsx2Configure(NULL) == FALSE) return;
}
if( TestRunMode() ) return;
#ifdef PCSX2_DEVBUILD
if( g_pRunGSState ) {
LoadGSState(g_pRunGSState);
@ -294,8 +267,6 @@ void WinRun()
textdomain(PACKAGE);
#endif
memzero_obj(g_TestRun);
_getcwd( g_WorkingFolder, g_MaxPath );
int argc;
@ -303,7 +274,7 @@ void WinRun()
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;
}
@ -396,6 +367,23 @@ void RunGui()
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
{
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) {
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) {
case WM_INITDIALOG:
for (i=0; i<32; i++)
if (varLog & (1<<i))
CheckDlgButton(hDlg, IDC_CPULOG+i, TRUE);
//for (i=0; i<32; i++)
// if (varLog & (1<<i))
// CheckDlgButton(hDlg, IDC_CPULOG+i, TRUE);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK) {
for (i=0; i<32; i++) {
int ret = Button_GetCheck(GetDlgItem(hDlg, IDC_CPULOG+i));
if (ret) varLog|= 1<<i;
else varLog&=~(1<<i);
}
//for (i=0; i<32; i++) {
// int ret = Button_GetCheck(GetDlgItem(hDlg, IDC_CPULOG+i));
// if (ret) varLog|= 1<<i;
// else varLog&=~(1<<i);
//}
SaveConfig();

View File

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

View File

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

View File

@ -44,11 +44,11 @@
memcmp_mmx:
// make sure mmx regs are stored
// FreezeMMXRegs(1);
cmp dword ptr [g_EEFreezeRegs], 0
je memcmp_mmx_begin
push 1
call FreezeMMXRegs_
add esp, 4
//cmp dword ptr [g_EEFreezeRegs], 0
//je memcmp_mmx_begin
//push 1
//call FreezeMMXRegs_
//add esp, 4
memcmp_mmx_begin:
push esi
@ -381,7 +381,7 @@ $memcpy_align_done: // destination is dword aligned
shr eax, 6 // get 64-byte block count
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
jae $memcpy_uc_test

View File

@ -128,16 +128,21 @@ void recMFC0( void )
{
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);
MOV32RtoR(EAX,ECX);
MOV32RtoR(EAX, ECX);
SUB32MtoR(EAX, (uptr)&s_iLastCOP0Cycle);
u8* skipInc = JNZ8( 0 );
INC32R(EAX);
x86SetJ8( skipInc );
ADD32RtoM((uptr)&cpuRegs.CP0.n.Count, EAX);
MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX);
MOV32MtoR( EAX, (uptr)&cpuRegs.CP0.r[ _Rd_ ] );
if( !_Rt_ ) return;
_deleteEEreg(_Rt_, 0);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
@ -148,52 +153,24 @@ void recMFC0( void )
else EEINST_RESETHASLIVE1(_Rt_);
return;
}
if( _Rd_ == 25 ) {
_deleteEEreg(_Rt_, 0);
switch(_Imm_ & 0x3F){
if ( !_Rt_ ) return;
if( _Rd_ == 25 )
{
switch(_Imm_ & 0x3F)
{
case 0:
MOV32MtoR(EAX, (uptr)&cpuRegs.PERF.n.pccr);
break;
break;
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:
// check if needs to be incremented
MOV32MtoR(ECX, (uptr)&cpuRegs.PERF.n.pccr);
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;
CALLFunc( (uptr)COP0_UpdatePCCR );
break;
}
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
_deleteEEreg(_Rt_, 0);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rt_].UL[0],EAX);
if(EEINST_ISLIVE1(_Rt_)) {
CDQ();
@ -201,10 +178,6 @@ void recMFC0( void )
}
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;
}
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()
{
if( GPR_IS_CONST1(_Rt_) ) {
switch (_Rd_) {
if( GPR_IS_CONST1(_Rt_) )
{
switch (_Rd_)
{
case 12:
iFlushCall(FLUSH_NODESTROY);
//_flushCachedRegs(); //NOTE: necessary?
_callFunctionArg1((uptr)WriteCP0Status, MEM_CONSTTAG, g_cpuConstRegs[_Rt_].UL[0]);
break;
break;
case 9:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX);
MOV32ItoM((uptr)&cpuRegs.CP0.r[9], g_cpuConstRegs[_Rt_].UL[0]);
break;
case 25:
COP0_LOG("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n",
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);
switch(_Imm_ & 0x3F){
case 0:
updatePCCR();
MOV32ItoM((uptr)&cpuRegs.PERF.n.pccr, g_cpuConstRegs[_Rt_].UL[0]);
break;
case 25:
switch(_Imm_ & 0x3F)
{
case 0:
CALLFunc( (uptr)COP0_UpdatePCCR );
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:
MOV32MtoR(EAX, (uptr)&cpuRegs.cycle);
MOV32ItoM((uptr)&cpuRegs.PERF.n.pcr0, g_cpuConstRegs[_Rt_].UL[0]);
MOV32RtoM((uptr)&s_iLastPERFCycle[0], EAX);
break;
break;
case 3:
MOV32MtoR(EAX, (uptr)&cpuRegs.cycle);
MOV32ItoM((uptr)&cpuRegs.PERF.n.pcr1, g_cpuConstRegs[_Rt_].UL[0]);
MOV32RtoM((uptr)&s_iLastPERFCycle[1], EAX);
break;
break;
}
break;
break;
case 24:
COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF);
break;
break;
default:
MOV32ItoM((uptr)&cpuRegs.CP0.r[_Rd_], g_cpuConstRegs[_Rt_].UL[0]);
break;
break;
}
}
else {
switch (_Rd_) {
else
{
switch (_Rd_)
{
case 12:
iFlushCall(FLUSH_NODESTROY);
//_flushCachedRegs(); //NOTE: necessary?
_callFunctionArg1((uptr)WriteCP0Status, MEM_GPRTAG|_Rt_, 0);
break;
break;
case 9:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
_eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[9], _Rt_);
MOV32RtoM((uptr)&s_iLastCOP0Cycle, ECX);
break;
case 25:
COP0_LOG("MTC0 PCCR = %x PCR0 = %x PCR1 = %x IMM= %x\n",
cpuRegs.PERF.n.pccr, cpuRegs.PERF.n.pcr0, cpuRegs.PERF.n.pcr1, _Imm_ & 0x3F);
switch(_Imm_ & 0x3F){
case 0:
updatePCCR();
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pccr, _Rt_);
break;
case 25:
switch(_Imm_ & 0x3F)
{
case 0:
CALLFunc( (uptr)COP0_UpdatePCCR );
_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:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr0, _Rt_);
MOV32RtoM((uptr)&s_iLastPERFCycle[0], ECX);
break;
break;
case 3:
MOV32MtoR(ECX, (uptr)&cpuRegs.cycle);
_eeMoveGPRtoM((uptr)&cpuRegs.PERF.n.pcr1, _Rt_);
MOV32RtoM((uptr)&s_iLastPERFCycle[1], ECX);
break;
break;
}
break;
break;
case 24:
COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF);
break;
break;
default:
_eeMoveGPRtoM((uptr)&cpuRegs.CP0.r[_Rd_], _Rt_);
break;
break;
}
}
}

View File

@ -324,6 +324,7 @@ void SetFPUstate();
#define MMX_TEMP 0x7f
#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)
struct _mmxregs {

View File

@ -25,17 +25,19 @@
#include "iFPU.h"
/* 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)
#define FPU_FLAGS_OVERFLOW 1
//set underflow flag (set only if FPU_RESULT is 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)
#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
//------------------------------------------------------------------
@ -126,270 +128,8 @@ static u32 PCSX2_ALIGNED16(s_pos[4]) = { 0x7fffffff, 0xffffffff, 0xffffffff, 0xf
//------------------------------------------------------------------
// *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
//------------------------------------------------------------------
@ -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)
//------------------------------------------------------------------
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)
{
@ -718,48 +458,6 @@ void recADDA_S_xmm(int info)
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)
{
int sreg, treg;
@ -787,12 +485,7 @@ void recC_EQ_xmm(int info)
}
FPURECOMPILE_CONSTCODE(C_EQ, XMMINFO_READS|XMMINFO_READT);
/*void recC_F()
{
AND32ItoM( (uptr)&fpuRegs.fprc[31], ~FPUflagC );
}*/
void recC_LE_xmm(int info )
{
recCMP(info);
@ -806,7 +499,6 @@ void recC_LE_xmm(int info )
}
FPURECOMPILE_CONSTCODE(C_LE, XMMINFO_READS|XMMINFO_READT);
//REC_FPUFUNC(C_LE);
void recC_LT_xmm(int info)
{
@ -821,7 +513,6 @@ void recC_LT_xmm(int info)
}
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);
void recCVT_W()
void recCVT_W() //called from iFPU.cpp's recCVT_W
{
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
//------------------------------------------------------------------
//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)
{
recFPUOp(info, EEREC_D, 2, false);
recMINMAX(info, false);
}
FPURECOMPILE_CONSTCODE(MAX_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
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);
@ -1322,6 +1038,5 @@ void recRSQRT_S_xmm(int info)
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 t1reg = _allocTempXMMreg(XMMT_INT, -1);
int t2reg = _allocTempXMMreg(XMMT_INT, -1);
int t3reg = _allocTempXMMreg(XMMT_INT, -1);
if ( cpucaps.hasStreamingSIMD4Extensions ) {
SSE4_PMOVSXDQ_XMM_to_XMM(t0reg, EEREC_S);
SSE4_PMOVSXDQ_XMM_to_XMM(t1reg, EEREC_T);
SSE2_PADDQ_XMM_to_XMM(t0reg, t1reg);
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] }
*/
// The idea is:
// s = x + y; (wrap-arounded)
// if Sign(x) == Sign(y) && Sign(s) != Sign(x) && Sign(x) == 0 then positive overflow (clamp with 0x7fffffff)
// if Sign(x) == Sign(y) && Sign(s) != Sign(x) && Sign(x) == 1 then negative overflow (clamp with 0x80000000)
SSEX_MOVDQA_XMM_to_XMM(t2reg, t0reg);
SSE_SHUFPS_XMM_to_XMM(t2reg, t1reg, 0xdd);
SSE2_PSRAD_I8_to_XMM(t2reg, 31);
/*
t2reg = { (Rs[0]+Rt[0]) < 0 ? 0xFFFFFFFF : 0,
(Rs[1]+Rt[1]) < 0 ? 0xFFFFFFFF : 0,
(Rs[2]+Rt[2]) < 0 ? 0xFFFFFFFF : 0,
(Rs[3]+Rt[3]) < 0 ? 0xFFFFFFFF : 0 }
*/
// get sign bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
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);
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 }
*/
// normal addition
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 {
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S);
SSE2_PADDD_XMM_to_XMM(EEREC_D, EEREC_T);
}
SSE2_PAND_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PANDN_XMM_to_XMM(t1reg, t2reg);
SSE2_POR_XMM_to_XMM(EEREC_D, t1reg);
/*
Rd = { t1reg[0] ? Rs[0]+Rt[0] : t2reg[0],
t1reg[1] ? Rs[1]+Rt[1] : t2reg[1],
t1reg[2] ? Rs[2]+Rt[2] : t2reg[2],
t1reg[3] ? Rs[3]+Rt[3] : t2reg[3] }
*/
// overflow check
// t2reg = 0xffffffff if 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_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(t1reg);
_freeXMMreg(t2reg);
_freeXMMreg(t3reg);
CPU_SSE_XMMCACHE_END
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 t1reg = _allocTempXMMreg(XMMT_INT, -1);
int t2reg = _allocTempXMMreg(XMMT_INT, -1);
int t3reg = _allocTempXMMreg(XMMT_INT, -1);
if ( cpucaps.hasStreamingSIMD4Extensions ) {
SSE4_PMOVSXDQ_XMM_to_XMM(t0reg, EEREC_S);
SSE4_PMOVSXDQ_XMM_to_XMM(t1reg, EEREC_T);
SSE2_PSUBQ_XMM_to_XMM(t0reg, t1reg);
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);
// The idea is:
// s = x - y; (wrap-arounded)
// if Sign(x) != Sign(y) && Sign(s) != Sign(x) && Sign(x) == 0 then positive overflow (clamp with 0x7fffffff)
// if Sign(x) != Sign(y) && Sign(s) != Sign(x) && Sign(x) == 1 then negative overflow (clamp with 0x80000000)
SSEX_MOVDQA_XMM_to_XMM(t2reg, t0reg);
SSE_SHUFPS_XMM_to_XMM(t2reg, t1reg, 0xdd);
SSE2_PSRAD_I8_to_XMM(t2reg, 31);
// get sign bit
SSEX_MOVDQA_XMM_to_XMM(t0reg, EEREC_S);
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);
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);
// normal subtraction
if( EEREC_D == EEREC_S ) SSE2_PSUBD_XMM_to_XMM(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);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, t0reg);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, t2reg);
}
else {
SSEX_MOVDQA_XMM_to_XMM(EEREC_D, EEREC_S);
SSE2_PSUBD_XMM_to_XMM(EEREC_D, EEREC_T);
}
SSE2_PAND_XMM_to_XMM(EEREC_D, t1reg);
SSE2_PANDN_XMM_to_XMM(t1reg, t2reg);
SSE2_POR_XMM_to_XMM(EEREC_D, t1reg);
// overflow check
// 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(t1reg);
_freeXMMreg(t2reg);
_freeXMMreg(t3reg);
CPU_SSE_XMMCACHE_END
if( _Rd_ ) _deleteEEreg(_Rd_, 0);

View File

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

View File

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

View File

@ -19,7 +19,7 @@
#include "PrecompiledHeader.h"
#include <time.h>
#include "PsxCommon.h"
#include "IopCommon.h"
#include "iR3000A.h"
#include "IopMem.h"
#include "IopDma.h"
@ -97,7 +97,7 @@ PSXRECOMPILE_CONSTCODE1(SLTI);
//// SLTIU
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)

View File

@ -698,19 +698,10 @@ void* SuperVUGetProgram(u32 startpc, int vuindex)
bool VuFunctionHeader::IsSame(void* pmem)
{
#ifdef SUPERVU_CACHING
//u32 checksum[2];
vector<RANGE>::iterator it;
FORIT(it, ranges) {
//memxor_mmx(checksum, (u8*)pmem+it->start, it->size);
//if( checksum[0] != it->checksum[0] || checksum[1] != it->checksum[1] )
// 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
FORIT(it, ranges)
{
if( memcmp_mmx((u8*)pmem+it->start, it->pmem, it->size) )
return false;
}
#endif
@ -3022,7 +3013,6 @@ void VuInstruction::Recompile(list<VuInstruction>::iterator& itinst, u32 vuxyz)
CMP32ItoM((uptr)&g_nLastBlockExecuted, nParentCheckForExecution);
u8* jptr = JNE8(0);
MOV32MtoR(EAX, pparentinst->pClipWrite);
MOV32ItoM(pparentinst->pClipWrite, 0);
MOV32RtoM(s_ClipRead, EAX);
x86SetJ8(jptr);
}

View File

@ -29,11 +29,6 @@
extern u32 g_vif1Masks[48], g_vif0Masks[48];
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
static PCSX2_ALIGNED16(u32 s_maskarr[16][4]) = {
0xffffffff, 0x00000000, 0x00000000, 0xffffffff,
@ -58,8 +53,6 @@ extern u8 s_maskwrite[256];
extern "C" PCSX2_ALIGNED16(u32 s_TempDecompress[4]) = {0};
//#if defined(_MSC_VER)
void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
{
u32 i;
@ -67,7 +60,7 @@ void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
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);
prev |= s_maskwrite[mask&0xff];
hasmask[i] = prev;
if( (mask&0xff) != (oldmask&0xff) ) {
@ -93,46 +86,3 @@ void __fastcall SetNewMask(u32* vif1masks, u32* hasmask, u32 mask, u32 oldmask)
}
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
for (i=0; i<MMXREGS; i++) {
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)) ) {
_freeMMXreg(i);
return i;

View File

@ -613,9 +613,12 @@ void recStep( void ) {
static __forceinline bool recEventTest()
{
#ifdef PCSX2_DEVBUILD
// dont' remove this check unless doing an official release
if( g_globalXMMSaved || g_globalMMXSaved)
// dont' remove this check unless doing an official release
if( g_globalXMMSaved || g_globalMMXSaved)
{
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);
#endif
@ -1198,11 +1201,12 @@ u32 eeScaleBlockCycles()
jNO_DEFAULT
}
s_nBlockCycles *=
const u32 temp = s_nBlockCycles * (
(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).

View File

@ -486,19 +486,6 @@ void recADDIU( 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_ )
{
return;
@ -520,7 +507,6 @@ void recDADDI( void )
}
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
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_PABSD_XMM_to_XMM eSSSE3_PABSD_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_M128_to_XMM eSSE4_BLENDVPS_M128_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_PMAXSD_XMM_to_XMM eSSE4_PMAXSD_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);
}
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
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);
}
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)
{
write8<I>(0x66);

View File

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

View File

@ -100,11 +100,13 @@ struct microProgManager {
};
struct microVU {
int index; // VU Index (VU0 or VU1)
u32 index; // VU Index (VU0 or VU1)
u32 microSize; // VU Micro Memory Size
u32 progSize; // VU Micro Program Size (microSize/8)
u32 cacheAddr; // VU Cache Start Address
static const u32 cacheSize = 0x400000; // VU Cache Size
microProgManager<0x800> prog; // Micro Program Data
VURegs* regs; // VU Regs Struct
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 x86edi; // Destination register. Used as a pointer to a destination in stream operations.
*/
microProgManager<0x800> prog; // Micro Program Data
};
// microVU rec structs

View File

@ -36,14 +36,14 @@
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); } \
else { SSE_XORPS_XMM_to_XMM(reg, reg); } \
}
#define getZero(reg) { \
if (_W) { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[0].UL[0], _X_Y_Z_W); } \
else { SSE_XORPS_XMM_to_XMM(reg, reg); } \
#define getReg6(reg, _reg_) { \
if (!_reg_) { getZero(reg); } \
else { getReg(reg, _reg_); } \
}
microVUt(void) mVUallocFMAC1a(int& Fd, int& Fs, int& Ft) {
@ -51,26 +51,9 @@ microVUt(void) mVUallocFMAC1a(int& Fd, int& Fs, int& Ft) {
Fs = xmmFs;
Ft = xmmFt;
Fd = xmmFs;
if (_XYZW_SS) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
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_); }
}
}
getReg6(Fs, _Fs_);
if (_Ft_ == _Fs_) { Ft = Fs; }
else { getReg6(Ft, _Ft_); }
}
microVUt(void) mVUallocFMAC1b(int& Fd) {
@ -88,14 +71,7 @@ microVUt(void) mVUallocFMAC2a(int& Fs, int& Ft) {
microVU* mVU = mVUx;
Fs = xmmFs;
Ft = xmmFs;
if (_XYZW_SS) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
}
getReg6(Fs, _Fs_);
}
microVUt(void) mVUallocFMAC2b(int& Ft) {
@ -139,21 +115,15 @@ microVUt(void) mVUallocFMAC3a(int& Fd, int& Fs, int& Ft) {
Ft = xmmFt;
Fd = xmmFs;
if (_XYZW_SS) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
getReg6(Fs, _Fs_);
if ( (_Ft_ == _Fs_) && ((_X && _bc_x) || (_Y && _bc_y) || (_Z && _bc_w) || (_W && _bc_w)) ) {
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
else if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
getReg6(Fs, _Fs_);
if (!_Ft_) { getZero3(Ft); }
else { getReg3(Ft, _Ft_); }
}
@ -188,24 +158,17 @@ microVUt(void) mVUallocFMAC4a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt;
getACC(ACC);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
getReg6(Fs, _Fs_);
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
else { getReg6(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
else if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
}
@ -225,16 +188,10 @@ microVUt(void) mVUallocFMAC5a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt;
getACC(ACC);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
if ( (_Ft_ == _Fs_) && _bc_x) {
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
getReg6(Fs, _Fs_);
if ((_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
@ -266,14 +223,7 @@ microVUt(void) mVUallocFMAC6a(int& Fd, int& Fs, int& Ft) {
Ft = xmmFt;
Fd = xmmFs;
getIreg(Ft);
if (_XYZW_SS) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
}
getReg6(Fs, _Fs_);
}
microVUt(void) mVUallocFMAC6b(int& Fd) {
@ -290,14 +240,9 @@ microVUt(void) mVUallocFMAC7a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt;
getACC(ACC);
getIreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _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;
ACC = xmmACC0 + readACC;
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
getReg6(Fs, _Fs_);
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
else { getReg6(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
else if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
}
@ -355,24 +293,17 @@ microVUt(void) mVUallocFMAC9a(int& Fd, int&ACC, int& Fs, int& Ft) {
ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
getReg6(Fs, _Fs_);
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
else { getReg6(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
else if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
}
@ -394,16 +325,10 @@ microVUt(void) mVUallocFMAC10a(int& Fd, int& ACC, int& Fs, int& Ft) {
Fd = xmmFs;
ACC = xmmACC0 + readACC;
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
if ( (_Ft_ == _Fs_) && _bc_x) {
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
getReg6(Fs, _Fs_);
if ( (_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
@ -430,16 +355,10 @@ microVUt(void) mVUallocFMAC11a(int& Fd, int& ACC, int& Fs, int& Ft) {
ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
if ( (_Ft_ == _Fs_) && _bc_x) {
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
getReg6(Fs, _Fs_);
if ( (_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
@ -465,14 +384,9 @@ microVUt(void) mVUallocFMAC12a(int& Fd, int&ACC, int& Fs, int& Ft) {
Fd = xmmFs;
ACC = xmmACC0 + readACC;
getIreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
microVUt(void) mVUallocFMAC12b(int& Fd) {
@ -491,14 +405,9 @@ microVUt(void) mVUallocFMAC13a(int& Fd, int&ACC, int& Fs, int& Ft) {
ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
getIreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
microVUt(void) mVUallocFMAC13b(int& Fd) {
@ -516,24 +425,17 @@ microVUt(void) mVUallocFMAC14a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt;
ACCr = xmmACC0 + readACC;
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
getReg6(Fs, _Fs_);
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZeroSS(Ft); }
else { getReg(Ft, _Ft_); }
}
else { getReg6(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
if (_Ft_ == _Fs_) { Ft = Fs; }
else {
if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
else if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
}
}
@ -570,16 +472,10 @@ microVUt(void) mVUallocFMAC16a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt;
ACCr = xmmACC0 + readACC;
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
if ( (_Ft_ == _Fs_) && _bc_x) {
Ft = Fs;
}
else {
if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
getReg6(Fs, _Fs_);
if ((_Ft_ == _Fs_) && _bc_x) { Ft = Fs; }
else if (!_Ft_) { getZero3SS(Ft); }
else { getReg3SS(Ft, _Ft_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
@ -624,8 +520,8 @@ microVUt(void) mVUallocFMAC18a(int& ACC, int& Fs, int& Ft) {
if (!_Ft_) { getZero4(Ft); }
else { getReg4(Ft, _Ft_); }
SSE_SHUFPS_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY
SSE_SHUFPS_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ
SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY
SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ
}
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); }
else { getReg4(Ft, _Ft_); }
SSE_SHUFPS_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY
SSE_SHUFPS_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ
SSE2_PSHUFD_XMM_to_XMM(Fs, Fs, 0xC9); // WXZY
SSE2_PSHUFD_XMM_to_XMM(Ft, Ft, 0xD2); // WYXZ
}
microVUt(void) mVUallocFMAC19b(int& Fd) {
@ -669,14 +565,9 @@ microVUt(void) mVUallocFMAC20a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt;
ACCr = xmmACC0 + readACC;
getIreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
microVUt(void) mVUallocFMAC20b(int& ACCw, int& Fs) {
@ -712,14 +603,7 @@ microVUt(void) mVUallocFMAC22a(int& Fd, int& Fs, int& Ft) {
Ft = xmmFt;
Fd = xmmFs;
getQreg(Ft);
if (_XYZW_SS) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero(Fs); }
else { getReg(Fs, _Fs_); }
}
getReg6(Fs, _Fs_);
}
microVUt(void) mVUallocFMAC22b(int& Fd) {
@ -736,21 +620,15 @@ microVUt(void) mVUallocFMAC23a(int& ACC, int& Fs, int& Ft) {
Ft = xmmFt;
getACC(ACC);
getQreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
microVUt(void) mVUallocFMAC23b(int& ACC, int& Fs) {
mVUallocFMAC4b<vuIndex>(ACC, Fs);
}
//------------------------------------------------------------------
// 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;
ACC = xmmACC0 + readACC;
getQreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
microVUt(void) mVUallocFMAC24b(int& Fd) {
@ -788,14 +661,9 @@ microVUt(void) mVUallocFMAC25a(int& Fd, int&ACC, int& Fs, int& Ft) {
ACC = xmmT1;
SSE_MOVAPS_XMM_to_XMM(ACC, xmmACC0 + readACC);
getQreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
microVUt(void) mVUallocFMAC25b(int& Fd) {
@ -813,14 +681,9 @@ microVUt(void) mVUallocFMAC26a(int& ACCw, int&ACCr, int& Fs, int& Ft) {
Ft = xmmFt;
ACCr = xmmACC0 + readACC;
getQreg(Ft);
if (_XYZW_SS && _X) {
if (!_Fs_) { getZeroSS(Fs); }
else { getReg(Fs, _Fs_); }
}
else {
if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _Fs_); }
}
if (_XYZW_SS && _X) { getReg6(Fs, _Fs_); }
else if (!_Fs_) { getZero4(Fs); }
else { getReg4(Fs, _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_) {
microVU* mVU = mVUx;
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); }
}
microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
microVU* mVU = mVUx;
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); }
}
@ -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_) { \
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_))); \
if (!_reg_) { \
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

View File

@ -137,7 +137,7 @@ microVUf(void) mVU_RSQRT() {
#define EATANhelper(addr) { \
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_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)
SSE_MOVSS_XMM_to_XMM(xmmPQ, xmmFs);
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_T3);
@ -158,16 +158,15 @@ microVUt(void) mVU_EATAN_() {
EATANhelper(mVU_T8);
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() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
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_SUBSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
SSE_ADDSS_M32_to_XMM(xmmPQ, (uptr)mVU_one);
@ -180,9 +179,9 @@ microVUf(void) mVU_EATANxy() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg5(xmmFs, _Fs_, 1);
getReg5(xmmFt, _Fs_, 0);
SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
getReg6(xmmFt, _Fs_);
SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFt, 0x01);
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_SUBSS_M32_to_XMM(xmmFs, (uptr)mVU_one);
@ -196,9 +195,9 @@ microVUf(void) mVU_EATANxz() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
getReg5(xmmFs, _Fs_, 2);
getReg5(xmmFt, _Fs_, 0);
SSE_SHUFPS_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip xmmPQ to get Valid P instance
getReg6(xmmFt, _Fs_);
SSE2_PSHUFD_XMM_to_XMM(xmmFs, xmmFt, 0x02);
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_SUBSS_XMM_to_XMM(xmmFs, xmmFt);
@ -208,16 +207,188 @@ microVUf(void) mVU_EATANxz() {
mVU_EATAN_<vuIndex>();
}
}
microVUf(void) mVU_EEXP() {}
microVUf(void) mVU_ELENG() {}
microVUf(void) mVU_ERCPR() {}
microVUf(void) mVU_ERLENG() {}
microVUf(void) mVU_ERSADD() {}
microVUf(void) mVU_ERSQRT() {}
microVUf(void) mVU_ESADD() {}
microVUf(void) mVU_ESIN() {}
microVUf(void) mVU_ESQRT() {}
microVUf(void) mVU_ESUM() {}
#define eexpHelper(addr) { \
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \
SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmT1); \
SSE_MULSS_M32_to_XMM(xmmFt, (uptr)addr); \
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \
}
microVUf(void) mVU_EEXP() {
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_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_FCEQ() {}
@ -302,8 +473,11 @@ microVUf(void) mVU_IADD() {
if (recPass == 0) {}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_);
ADD16RtoR(gprT1, gprT2);
if (_Ft_ != _Fs_) {
mVUallocVIa<vuIndex>(gprT2, _Ft_);
ADD16RtoR(gprT1, gprT2);
}
else ADD16RtoR(gprT1, gprT1);
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
}
@ -330,8 +504,10 @@ microVUf(void) mVU_IAND() {
if (recPass == 0) {}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_);
AND32RtoR(gprT1, gprT2);
if (_Ft_ != _Fs_) {
mVUallocVIa<vuIndex>(gprT2, _Ft_);
AND32RtoR(gprT1, gprT2);
}
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
}
@ -340,8 +516,10 @@ microVUf(void) mVU_IOR() {
if (recPass == 0) {}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_);
OR32RtoR(gprT1, gprT2);
if (_Ft_ != _Fs_) {
mVUallocVIa<vuIndex>(gprT2, _Ft_);
OR32RtoR(gprT1, gprT2);
}
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
}
@ -349,10 +527,16 @@ microVUf(void) mVU_ISUB() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_);
SUB16RtoR(gprT1, gprT2);
mVUallocVIb<vuIndex>(gprT1, _Fd_);
if (_Ft_ != _Fs_) {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
mVUallocVIa<vuIndex>(gprT2, _Ft_);
SUB16RtoR(gprT1, gprT2);
}
else if (!isMMX(_Fd_)) {
XOR32RtoR(gprT1, gprT1);
mVUallocVIb<vuIndex>(gprT1, _Fd_);
}
else { PXORRtoR(mmVI(_Fd_), mmVI(_Fd_)); }
}
}
microVUf(void) mVU_ISUBIU() {
@ -376,14 +560,9 @@ microVUf(void) mVU_IBNE() {}
microVUf(void) mVU_JR() {}
microVUf(void) mVU_JALR() {}
microVUf(void) mVU_ILW() {}
microVUf(void) mVU_ISW() {}
microVUf(void) mVU_ILWR() {}
microVUf(void) mVU_ISWR() {}
microVUf(void) mVU_MOVE() {
microVU* mVU = mVUx;
if (recPass == 0) {}
if (recPass == 0) { /*If (!_Ft_ || (_Ft_ == _Fs_)) nop();*/ }
else {
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);
@ -391,7 +570,7 @@ microVUf(void) mVU_MOVE() {
}
microVUf(void) mVU_MFIR() {
microVU* mVU = mVUx;
if (recPass == 0) {}
if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else {
mVUallocVIa<vuIndex>(gprT1, _Fs_);
MOVSX32R16toR(gprT1, gprT1);
@ -402,7 +581,7 @@ microVUf(void) mVU_MFIR() {
}
microVUf(void) mVU_MFP() {
microVU* mVU = mVUx;
if (recPass == 0) {}
if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else {
getPreg(xmmFt);
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() {
microVU* mVU = mVUx;
if (recPass == 0) {}
if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else {
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);
}
}
microVUf(void) mVU_LQ() {}
microVUf(void) mVU_LQD() {}
microVUf(void) mVU_LQI() {}
microVUf(void) mVU_SQ() {}
microVUf(void) mVU_SQD() {}
microVUf(void) mVU_SQI() {}
//microVUf(void) mVU_LOI() {}
microVUf(void) mVU_ILW() {
microVU* mVU = mVUx;
if (recPass == 0) { /*If (!_Ft_) nop();*/ }
else {
if (!_Fs_) {
MOVZX32M16toR( gprT1, (uptr)mVU->regs->Mem + getVUmem(_Imm11_) + offsetSS );
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_RGET() {}

View File

@ -21,16 +21,11 @@
//------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------
PCSX2_ALIGNED16_EXTERN(const u32 mVU_absclip[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_signbit[4]);
PCSX2_ALIGNED16_EXTERN(const u32 mVU_minvals[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_T2[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_T8[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
@ -73,6 +84,9 @@ PCSX2_ALIGNED16_EXTERN(const u32 mVU_Pi4[4]);
#define _Imm5_ (((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf))
#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 xmmFs 1 // Holds the Value of Fs (writes back result Fd)
#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 getFt (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<14))
#define isMMX(_VIreg_) (_VIreg_ >= 1 && _VIreg_ <=9)
#define mmVI(_VIreg_) (_VIreg_ - 1)
#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 ) {
case 8: SSE_MOVSS_M32_to_XMM(reg, offset); break; // X
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 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;
}
}
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 ) {
case 1: // W
SSE_MOVSS_XMM_to_M32(offset+12, reg);
break;
case 2: // Z
SSE_MOVSS_XMM_to_M32(offset+8, reg);
break;
case 3: // ZW
SSE_MOVHPS_XMM_to_M64(offset+8, reg);
break;
case 4: // Y
SSE_MOVSS_XMM_to_M32(offset+4, reg);
break;
case 5: // YW
SSE_SHUFPS_XMM_to_XMM(reg, reg, 0xB1);
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_M32(offset+4, reg);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break;
case 6: // YZ
SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0xc9);
SSE_MOVLPS_XMM_to_M64(offset+4, xmmT1);
break;
case 7: // YZW
SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x93); //ZYXW
SSE_MOVHPS_XMM_to_M64(offset+4, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break;
case 8: // X
SSE_MOVSS_XMM_to_M32(offset, reg);
break;
case 9: // XW
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_M32(offset, reg);
if ( cpucaps.hasStreamingSIMD3Extensions ) SSE3_MOVSLDUP_XMM_to_XMM(xmmT1, xmmT1);
else SSE_SHUFPS_XMM_to_XMM(xmmT1, xmmT1, 0x55);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break;
case 10: //XZ
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_M32(offset, reg);
SSE_MOVSS_XMM_to_M32(offset+8, xmmT1);
break;
case 11: //XZW
SSE_MOVSS_XMM_to_M32(offset, reg);
SSE_MOVHPS_XMM_to_M64(offset+8, reg);
break;
case 12: // XY
SSE_MOVLPS_XMM_to_M64(offset, reg);
break;
case 13: // XYW
SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x4b); //YXZW
SSE_MOVHPS_XMM_to_M64(offset, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break;
case 14: // XYZ
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVLPS_XMM_to_M64(offset, reg);
SSE_MOVSS_XMM_to_M32(offset+8, xmmT1);
break;
case 15: // XYZW
SSE_MOVAPS_XMM_to_M128(offset, reg);
break;
case 5: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xB1);
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_M32(offset+4, reg);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break; // YW
case 6: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0xc9);
SSE_MOVLPS_XMM_to_M64(offset+4, xmmT1);
break; // YZ
case 7: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x93); //ZYXW
SSE_MOVHPS_XMM_to_M64(offset+4, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break; // YZW
case 9: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_M32(offset, reg);
if ( cpucaps.hasStreamingSIMD3Extensions ) SSE3_MOVSLDUP_XMM_to_XMM(xmmT1, xmmT1);
else SSE2_PSHUFD_XMM_to_XMM(xmmT1, xmmT1, 0x55);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break; // XW
case 10: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_M32(offset, reg);
SSE_MOVSS_XMM_to_M32(offset+8, xmmT1);
break; //XZ
case 11: SSE_MOVSS_XMM_to_M32(offset, reg);
SSE_MOVHPS_XMM_to_M64(offset+8, reg);
break; //XZW
case 13: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x4b); //YXZW
SSE_MOVHPS_XMM_to_M64(offset, xmmT1);
SSE_MOVSS_XMM_to_M32(offset+12, xmmT1);
break; // XYW
case 14: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVLPS_XMM_to_M64(offset, reg);
SSE_MOVSS_XMM_to_M32(offset+8, xmmT1);
break; // XYZ
case 8: SSE_MOVSS_XMM_to_M32(offset, reg); break; // X
case 4: SSE_MOVSS_XMM_to_M32(offset+4, reg); break; // Y
case 2: SSE_MOVSS_XMM_to_M32(offset+8, reg); break; // Z
case 1: SSE_MOVSS_XMM_to_M32(offset+12, reg); break; // W
case 12: SSE_MOVLPS_XMM_to_M64(offset, reg); break; // XY
case 3: SSE_MOVHPS_XMM_to_M64(offset+8, reg); break; // ZW
default: SSE_MOVAPS_XMM_to_M128(offset, reg); break; // XYZW
}
}
microVUx(void) mVUsaveReg2(int reg, int gprReg, u32 offset, int xyzw) {
switch ( xyzw ) {
case 5: SSE2_PSHUFD_XMM_to_XMM(reg, reg, 0xB1);
SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+4, reg);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+12, xmmT1);
break; // YW
case 6: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0xc9);
SSE_MOVLPS_XMM_to_RmOffset(gprReg, offset+4, xmmT1);
break; // YZ
case 7: SSE2_PSHUFD_XMM_to_XMM(xmmT1, reg, 0x93); //ZYXW
SSE_MOVHPS_XMM_to_RmOffset(gprReg, offset+4, xmmT1);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset+12, xmmT1);
break; // YZW
case 9: SSE_MOVHLPS_XMM_to_XMM(xmmT1, reg);
SSE_MOVSS_XMM_to_RmOffset(gprReg, offset, reg);
if ( cpucaps.hasStreamingSIMD3Extensions ) SSE3_MOVSLDUP_XMM_to_XMM(xmmT1, xmmT1);
else SSE2_PSHUFD_XMM_to_XMM(xmmT1, xmmT1, 0x55);
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);
break;
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;
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;
case 7: SSE_MOVSS_XMM_to_XMM(src, dest);
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);
break;
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;
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;
case 11: SSE_MOVSS_XMM_to_XMM(dest, src);
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

View File

@ -78,12 +78,12 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
// Helper Macros
//------------------------------------------------------------------
// FMAC1 - Normal FMAC Opcodes
#define mVU_FMAC1(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC1a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_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); \
} \
}
// FMAC3 - BC(xyzw) FMAC Opcodes
#define mVU_FMAC3(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC3a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_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); \
} \
}
// FMAC4 - FMAC Opcodes Storing Result to ACC
#define mVU_FMAC4(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC4a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_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); \
} \
}
// FMAC5 - FMAC BC(xyzw) Opcodes Storing Result to ACC
#define mVU_FMAC5(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC5a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_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); \
} \
}
// FMAC6 - Normal FMAC Opcodes (I Reg)
#define mVU_FMAC6(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC6a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_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); \
} \
}
// FMAC7 - FMAC Opcodes Storing Result to ACC (I Reg)
#define mVU_FMAC7(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC7a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_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); \
} \
}
// FMAC8 - MADD FMAC Opcode Storing Result to Fd
#define mVU_FMAC8(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC8a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC9 - MSUB FMAC Opcode Storing Result to Fd
#define mVU_FMAC9(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC9a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC10 - MADD FMAC BC(xyzw) Opcode Storing Result to Fd
#define mVU_FMAC10(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC10a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC11 - MSUB FMAC BC(xyzw) Opcode Storing Result to Fd
#define mVU_FMAC11(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC11a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC12 - MADD FMAC Opcode Storing Result to Fd (I Reg)
#define mVU_FMAC12(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC12a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC13 - MSUB FMAC Opcode Storing Result to Fd (I Reg)
#define mVU_FMAC13(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC13a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC14 - MADDA FMAC Opcode
#define mVU_FMAC14(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC14a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC15 - MSUBA FMAC Opcode
#define mVU_FMAC15(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC15a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC16 - MADDA BC(xyzw) FMAC Opcode
#define mVU_FMAC16(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC16a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC17 - MSUBA BC(xyzw) FMAC Opcode
#define mVU_FMAC17(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC17a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC18 - OPMULA FMAC Opcode
#define mVU_FMAC18(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC18a<vuIndex>(ACC, Fs, Ft); \
SSE_##operation##PS_XMM_to_XMM(Fs, Ft); \
mVUupdateFlags<vuIndex>(Fs, xmmT1, Ft, _X_Y_Z_W, 0); \
mVUallocFMAC18b<vuIndex>(ACC, Fs); \
} \
}
// FMAC19 - OPMULA FMAC Opcode
#define mVU_FMAC19(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC19a<vuIndex>(Fd, ACC, Fs, Ft); \
SSE_MULPS_XMM_to_XMM(Fs, Ft); \
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); \
} \
}
// FMAC20 - MADDA FMAC Opcode (I Reg)
#define mVU_FMAC20(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC20a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC21 - MSUBA FMAC Opcode (I Reg)
#define mVU_FMAC21(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC21a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC22 - Normal FMAC Opcodes (Q Reg)
#define mVU_FMAC22(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC22a<vuIndex>(Fd, Fs, Ft); \
if (_XYZW_SS) SSE_##operation##SS_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); \
} \
}
// FMAC23 - FMAC Opcodes Storing Result to ACC (Q Reg)
#define mVU_FMAC23(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC23a<vuIndex>(ACC, Fs, Ft); \
if (_XYZW_SS && _X) SSE_##operation##SS_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); \
} \
}
// FMAC24 - MADD FMAC Opcode Storing Result to Fd (Q Reg)
#define mVU_FMAC24(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC24a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC25 - MSUB FMAC Opcode Storing Result to Fd (Q Reg)
#define mVU_FMAC25(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int Fd, ACC, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC25a<vuIndex>(Fd, ACC, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC26 - MADDA FMAC Opcode (Q Reg)
#define mVU_FMAC26(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC26a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
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); \
} \
}
// FMAC27 - MSUBA FMAC Opcode (Q Reg)
#define mVU_FMAC27(operation) { \
microVU* mVU = mVUx; \
if (recPass == 0) {} \
else { \
int ACCw, ACCr, Fs, Ft; \
if (isNOP) return; \
mVUallocFMAC27a<vuIndex>(ACCw, ACCr, Fs, Ft); \
if (_XYZW_SS && _X) { \
SSE_MULSS_XMM_to_XMM(Fs, Ft); \
@ -546,7 +521,6 @@ microVUf(void) mVU_ABS() {
if (recPass == 0) {}
else {
int Fs, Ft;
if (isNOP) return;
mVUallocFMAC2a<vuIndex>(Fs, Ft);
SSE_ANDPS_M128_to_XMM(Fs, (uptr)mVU_absclip);
mVUallocFMAC1b<vuIndex>(Ft);
@ -646,7 +620,6 @@ microVUq(void) mVU_FTOIx(uptr addr) {
if (recPass == 0) {}
else {
int Fs, Ft;
if (isNOP) return;
mVUallocFMAC2a<vuIndex>(Fs, Ft);
// Note: For help understanding this algorithm see recVUMI_FTOI_Saturate()
@ -672,7 +645,6 @@ microVUq(void) mVU_ITOFx(uptr addr) {
if (recPass == 0) {}
else {
int Fs, Ft;
if (isNOP) return;
mVUallocFMAC2a<vuIndex>(Fs, Ft);
SSE2_CVTDQ2PS_XMM_to_XMM(Ft, Fs);