implemented all vu lower instructions (second pass).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@792 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-03-15 10:03:34 +00:00
parent 0efde91a92
commit 7a0e3dca12
5 changed files with 178 additions and 30 deletions

View File

@ -64,7 +64,7 @@ PCSX2_ALIGNED16(const float mVU_ITOF_15[4]) = {0.000030517578125, 0.000030517578
// Micro VU - Main Functions // Micro VU - Main Functions
//------------------------------------------------------------------ //------------------------------------------------------------------
// Only run this once! ;) // Only run this once per VU! ;)
microVUt(void) mVUinit(VURegs* vuRegsPtr) { microVUt(void) mVUinit(VURegs* vuRegsPtr) {
microVU* mVU = mVUx; microVU* mVU = mVUx;

View File

@ -20,6 +20,7 @@
#define _EmitterId_ (vuIndex+1) #define _EmitterId_ (vuIndex+1)
#include "Common.h" #include "Common.h"
#include "VU.h" #include "VU.h"
#include "GS.h"
#include "ix86/ix86.h" #include "ix86/ix86.h"
#include "microVU_Alloc.h" #include "microVU_Alloc.h"
@ -104,15 +105,16 @@ struct microVU {
u32 microSize; // VU Micro Memory Size u32 microSize; // VU Micro Memory Size
u32 progSize; // VU Micro Program Size (microSize/8) u32 progSize; // VU Micro Program Size (microSize/8)
u32 cacheAddr; // VU Cache Start Address u32 cacheAddr; // VU Cache Start Address
static const u32 cacheSize = 0x400000; // VU Cache Size static const u32 cacheSize = 0x500000; // VU Cache Size
microProgManager<0x800> prog; // Micro Program Data microProgManager<0x800> prog; // Micro Program Data
VURegs* regs; // VU Regs Struct VURegs* regs; // VU Regs Struct
u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to) u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to)
u8* ptr; // Pointer to next place to write recompiled code to u8* ptr; // Pointer to next place to write recompiled code to
u32 code; // Contains the current Instruction u32 code; // Contains the current Instruction
u32 iReg; // iReg u32 iReg; // iReg (only used in recompilation, not execution)
u32 clipFlag[4]; // 4 instances of clip flag (used in execution)
/* /*
uptr x86eax; // Accumulator register. Used in arithmetic operations. uptr x86eax; // Accumulator register. Used in arithmetic operations.

View File

@ -741,6 +741,16 @@ microVUt(void) mVUallocMFLAGb(int reg, int fInstance) {
OR32RtoR(fInstance, reg); OR32RtoR(fInstance, reg);
} }
microVUt(void) mVUallocCFLAGa(int reg, int fInstance) {
microVU* mVU = mVUx;
MOV32MtoR(reg, mVU->clipFlag[fInstance]);
}
microVUt(void) mVUallocCFLAGb(int reg, int fInstance) {
microVU* mVU = mVUx;
MOV32RtoM(mVU->clipFlag[fInstance], reg);
}
//------------------------------------------------------------------ //------------------------------------------------------------------
// VI Reg Allocators // VI Reg Allocators
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -788,4 +798,10 @@ microVUt(void) mVUallocVIb(int GPRreg, int _reg_) {
if (!_reg_) { getZero(reg); } \ if (!_reg_) { getZero(reg); } \
else { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); } \ else { mVUloadReg<vuIndex>(reg, (uptr)&mVU->regs->VF[_reg_].UL[0], _X_Y_Z_W); } \
} }
// VF to GPR
#define getReg8(GPRreg, _reg_, _fxf_) { \
if (!_reg_ && (_fxf_ < 3)) { XOR32RtoR(GPRreg, GPRreg); } \
else { MOV32MtoR(GPRreg, (uptr)&mVU->regs->VF[_reg_].UL[0]); } \
}
#endif //PCSX2_MICROVU #endif //PCSX2_MICROVU

View File

@ -207,11 +207,11 @@ microVUf(void) mVU_EATANxz() {
mVU_EATAN_<vuIndex>(); mVU_EATAN_<vuIndex>();
} }
} }
#define eexpHelper(addr) { \ #define eexpHelper(addr) { \
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \ SSE_MULSS_XMM_to_XMM(xmmT1, xmmFs); \
SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmT1); \ SSE_MOVAPS_XMM_to_XMM(xmmFt, xmmT1); \
SSE_MULSS_M32_to_XMM(xmmFt, (uptr)addr); \ SSE_MULSS_M32_to_XMM(xmmFt, (uptr)addr); \
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \ SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFt); \
} }
microVUf(void) mVU_EEXP() { microVUf(void) mVU_EEXP() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
@ -334,11 +334,11 @@ microVUf(void) mVU_ESADD() {
SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back SSE2_PSHUFD_XMM_to_XMM(xmmPQ, xmmPQ, writeP ? 0x27 : 0xC6); // Flip back
} }
} }
#define esinHelper(addr) { \ #define esinHelper(addr) { \
SSE_MULSS_XMM_to_XMM(xmmT1, xmmFt); \ SSE_MULSS_XMM_to_XMM(xmmT1, xmmFt); \
SSE_MOVAPS_XMM_to_XMM(xmmFs, xmmT1); \ SSE_MOVAPS_XMM_to_XMM(xmmFs, xmmT1); \
SSE_MULSS_M32_to_XMM(xmmFs, (uptr)addr); \ SSE_MULSS_M32_to_XMM(xmmFs, (uptr)addr); \
SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs); \ SSE_ADDSS_XMM_to_XMM(xmmPQ, xmmFs); \
} }
microVUf(void) mVU_ESIN() { microVUf(void) mVU_ESIN() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
@ -390,11 +390,56 @@ microVUf(void) mVU_ESUM() {
} }
} }
microVUf(void) mVU_FCAND() {} microVUf(void) mVU_FCAND() {
microVUf(void) mVU_FCEQ() {} microVU* mVU = mVUx;
microVUf(void) mVU_FCOR() {} if (recPass == 0) {}
microVUf(void) mVU_FCSET() {} else {
microVUf(void) mVU_FCGET() {} mVUallocCFLAGa<vuIndex>(gprT2, fvcInstance);
XOR32RtoR(gprT1, gprT1);
AND32ItoR(gprT2, _Imm24_);
SETNZ8R(gprT1);
mVUallocVIb<vuIndex>(gprT1, 1);
}
}
microVUf(void) mVU_FCEQ() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
mVUallocCFLAGa<vuIndex>(gprT2, fvcInstance);
XOR32RtoR(gprT1, gprT1);
CMP32ItoR(gprT2, _Imm24_);
SETNZ8R(gprT1);
mVUallocVIb<vuIndex>(gprT1, 1);
}
}
microVUf(void) mVU_FCGET() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
mVUallocCFLAGa<vuIndex>(gprT1, fvcInstance);
AND32ItoR(gprT1, 0xfff);
mVUallocVIb<vuIndex>(gprT1, _Ft_);
}
}
microVUf(void) mVU_FCOR() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
mVUallocCFLAGa<vuIndex>(gprT1, fvcInstance);
OR32ItoR(gprT1, _Imm24_);
ADD32ItoR(gprT1, 1); // If 24 1's will make 25th bit 1, else 0
SHR32ItoR(gprT1, 24); // Get the 25th bit (also clears the rest of the garbage in the reg)
mVUallocVIb<vuIndex>(gprT1, 1);
}
}
microVUf(void) mVU_FCSET() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
MOV32ItoR(gprT1, _Imm24_);
mVUallocCFLAGb<vuIndex>(gprT1, fcInstance);
}
}
microVUf(void) mVU_FMAND() { microVUf(void) mVU_FMAND() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
@ -800,15 +845,76 @@ microVUf(void) mVU_SQI() {
} }
} }
microVUf(void) mVU_RINIT() {} microVUf(void) mVU_RINIT() {
microVUf(void) mVU_RGET() {} microVU* mVU = mVUx;
microVUf(void) mVU_RNEXT() {} if (recPass == 0) {}
microVUf(void) mVU_RXOR() {} else {
if (_Fs_ || (_Fsf_ == 3)) {
getReg8(gprR, _Fs_, _Fsf_);
AND32ItoR(gprR, 0x007fffff);
OR32ItoR (gprR, 0x3f800000);
}
else MOV32ItoR(gprR, 0x3f800000);
}
}
microVUt(void) mVU_RGET_() {
microVU* mVU = mVUx;
if (_Ft_) {
if (_X) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[0], gprR);
if (_Y) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[1], gprR);
if (_Z) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[2], gprR);
if (_W) MOV32RtoM((uptr)&mVU->regs->VF[_Ft_].UL[3], gprR);
}
}
microVUf(void) mVU_RGET() {
microVU* mVU = mVUx;
if (recPass == 0) { /*if (!_Ft_) nop();*/ }
else { mVU_RGET_<vuIndex>(); }
}
microVUf(void) mVU_RNEXT() {
microVU* mVU = mVUx;
if (recPass == 0) { /*if (!_Ft_) nop();*/ }
else {
// algorithm from www.project-fao.org
MOV32RtoR(gprT1, gprR);
SHR32ItoR(gprT1, 4);
AND32ItoR(gprT1, 1);
microVUf(void) mVU_WAITP() {} MOV32RtoR(gprT2, gprR);
microVUf(void) mVU_WAITQ() {} SHR32ItoR(gprT2, 22);
AND32ItoR(gprT2, 1);
SHL32ItoR(gprR, 1);
XOR32RtoR(gprT1, gprT2);
XOR32RtoR(gprR, gprT1);
AND32ItoR(gprR, 0x007fffff);
OR32ItoR (gprR, 0x3f800000);
mVU_RGET_<vuIndex>();
}
}
microVUf(void) mVU_RXOR() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
if (_Fs_ || (_Fsf_ == 3)) {
getReg8(gprT1, _Fs_, _Fsf_);
AND32ItoR(gprT1, 0x7fffff);
XOR32RtoR(gprR, gprT1);
}
}
}
microVUf(void) mVU_WAITP() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {}
}
microVUf(void) mVU_WAITQ() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {}
}
microVUf(void) mVU_XGKICK() {}
microVUf(void) mVU_XTOP() { microVUf(void) mVU_XTOP() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (recPass == 0) {} if (recPass == 0) {}
@ -825,4 +931,25 @@ microVUf(void) mVU_XITOP() {
mVUallocVIb<vuIndex>(gprT1, _Ft_); mVUallocVIb<vuIndex>(gprT1, _Ft_);
} }
} }
microVUt(void) __fastcall mVU_XGKICK_(u32 addr) {
microVU* mVU = mVUx;
u32 *data = (u32*)(mVU->regs->Mem + (addr&0x3fff));
u32 size = mtgsThread->PrepDataPacket( GIF_PATH_1, data, (0x4000-(addr&0x3fff)) >> 4);
u8 *pDest = mtgsThread->GetDataPacketPtr();
memcpy_aligned(pDest, mVU->regs->Mem + addr, size<<4);
mtgsThread->SendDataPacket();
}
void __fastcall mVU_XGKICK0(u32 addr) { mVU_XGKICK_<0>(addr); }
void __fastcall mVU_XGKICK1(u32 addr) { mVU_XGKICK_<1>(addr); }
microVUf(void) mVU_XGKICK() {
microVU* mVU = mVUx;
if (recPass == 0) {}
else {
mVUallocVIa<vuIndex>(gprT2, _Fs_); // gprT2 = ECX for __fastcall
if (!vuIndex) CALLFunc((uptr)mVU_XGKICK0);
else CALLFunc((uptr)mVU_XGKICK1);
}
}
#endif //PCSX2_MICROVU #endif //PCSX2_MICROVU

View File

@ -83,6 +83,7 @@ PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_15[4]);
#define _Imm12_ (((mVU->code >> 21 ) & 0x1) << 11) | (mVU->code & 0x7ff) #define _Imm12_ (((mVU->code >> 21 ) & 0x1) << 11) | (mVU->code & 0x7ff)
#define _Imm5_ (((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf)) #define _Imm5_ (((mVU->code & 0x400) ? 0xfff0 : 0) | ((mVU->code >> 6) & 0xf))
#define _Imm15_ (((mVU->code >> 10) & 0x7800) | (mVU->code & 0x7ff)) #define _Imm15_ (((mVU->code >> 10) & 0x7800) | (mVU->code & 0x7ff))
#define _Imm24_ (u32)(mVU->code & 0xffffff)
#define getVUmem(x) (((vuIndex == 1) ? (x & 0x3ff) : ((x >= 0x400) ? (x & 0x43f) : (x & 0xff))) * 16) #define getVUmem(x) (((vuIndex == 1) ? (x & 0x3ff) : ((x >= 0x400) ? (x & 0x43f) : (x & 0xff))) * 16)
#define offsetSS ((_X) ? (0) : ((_Y) ? (4) : ((_Z) ? 8: 12))) #define offsetSS ((_X) ? (0) : ((_Y) ? (4) : ((_Z) ? 8: 12)))
@ -107,7 +108,7 @@ PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_15[4]);
#define gprT1 0 // Temp Reg #define gprT1 0 // Temp Reg
#define gprT2 1 // Temp Reg #define gprT2 1 // Temp Reg
#define gprT3 2 // Temp Reg? #define gprR 2 // R Reg
#define gprF0 3 // MAC Flag::Status Flag 0 #define gprF0 3 // MAC Flag::Status Flag 0
#define gprESP 4 // Don't use? #define gprESP 4 // Don't use?
#define gprF1 5 // MAC Flag::Status Flag 1 #define gprF1 5 // MAC Flag::Status Flag 1
@ -140,6 +141,8 @@ PCSX2_ALIGNED16_EXTERN(const float mVU_ITOF_15[4]);
#define fpsInstance (((u8)((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<12)) >> 12) - 1) & 0x3) #define fpsInstance (((u8)((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<12)) >> 12) - 1) & 0x3)
#define fvmInstance ((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<14)) >> 14) #define fvmInstance ((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<14)) >> 14)
#define fvsInstance ((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<16)) >> 16) #define fvsInstance ((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<16)) >> 16)
#define fvcInstance 1//((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<14)) >> 14)
#define fcInstance 1//((mVUallocInfo.info[mVUallocInfo.curPC] & (3<<14)) >> 14)
//#define getFs (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<13)) //#define getFs (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<13))
//#define getFt (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<14)) //#define getFt (mVUallocInfo.info[mVUallocInfo.curPC] & (1<<14))