microVU: backing up current code, going to have to rethink some things :/

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@836 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-03-23 04:11:39 +00:00
parent 157e696182
commit 235b19c858
7 changed files with 82 additions and 50 deletions

View File

@ -125,6 +125,7 @@ struct microVU {
u32 code; // Contains the current Instruction u32 code; // Contains the current Instruction
u32 iReg; // iReg (only used in recompilation, not execution) u32 iReg; // iReg (only used in recompilation, not execution)
u32 clipFlag[4]; // 4 instances of clip flag (used in execution) u32 clipFlag[4]; // 4 instances of clip flag (used in execution)
u32 divFlag[2]; // 2 Instances of I/D flags
/* /*
uptr x86eax; // Accumulator register. Used in arithmetic operations. uptr x86eax; // Accumulator register. Used in arithmetic operations.

View File

@ -46,32 +46,34 @@ template<u32 pSize>
struct microAllocInfo { struct microAllocInfo {
microRegInfo regs; // Pipeline info microRegInfo regs; // Pipeline info
microTempRegInfo regsTemp; // Temp Pipeline info (used so that new pipeline info isn't conflicting between upper and lower instructions in the same cycle) microTempRegInfo regsTemp; // Temp Pipeline info (used so that new pipeline info isn't conflicting between upper and lower instructions in the same cycle)
u8 branch; // 0 = No Branch, 1 = Branch, 2 = Conditional Branch, 3 = Jump (JALR/JR) u8 branch; // 0 = No Branch, 1 = Branch, 2 = Conditional Branch, 3 = Jump (JALR/JR)
u32 curPC; // Current PC u8 divFlag; // 0 = Transfer DS/IS flags normally, 1 = Clear DS/IS Flags, > 1 = set DS/IS flags to bit 2::1 of divFlag
u32 cycles; // Cycles for current block u8 divFlagTimer; // Used to ensure divFlag's contents are merged at the appropriate time.
u32 maxStall; // Helps in computing stalls (stores the max amount of cycles to stall for the current opcodes) u32 curPC; // Current PC
u32 info[pSize];// bit 00 = Lower Instruction is NOP u32 cycles; // Cycles for current block
// bit 01 u32 maxStall; // Helps in computing stalls (stores the max amount of cycles to stall for the current opcodes)
// bit 02 u32 info[pSize]; // bit 00 = Lower Instruction is NOP
// bit 03 // bit 01
// bit 04 // bit 02
// bit 05 = Write to Q1 or Q2? // bit 03
// bit 06 = Read Q1 or Q2? // bit 04
// bit 07 = Read/Write to P1 or P2? // bit 05 = Write to Q1 or Q2?
// bit 08 = Update Mac Flags? // bit 06 = Read Q1 or Q2?
// bit 09 = Update Status Flags? // bit 07 = Read/Write to P1 or P2?
// bit 10 = Used with bit 11 to make a 2-bit key for mac flag instance // bit 08 = Update Mac Flags?
// bit 11 // bit 09 = Update Status Flags?
// bit 12 = Used with bit 13 to make a 2-bit key for status flag instance // bit 10 = Used with bit 11 to make a 2-bit key for mac flag instance
// bit 13 // bit 11
// bit 14 = Used with bit 15 to make a 2-bit key for clip flag instance // bit 12 = Used with bit 13 to make a 2-bit key for status flag instance
// bit 15 // bit 13
// bit 16 = Used with bit 17 to make a 2-bit key for mac flag instance // bit 14 = Used with bit 15 to make a 2-bit key for clip flag instance
// bit 17 // bit 15
// bit 18 = Used with bit 19 to make a 2-bit key for status flag instance // bit 16 = Used with bit 17 to make a 2-bit key for mac flag instance
// bit 19 // bit 17
// bit 20 = Used with bit 21 to make a 2-bit key for clip flag instance // bit 18 = Used with bit 19 to make a 2-bit key for status flag instance
// bit 21 // bit 19
// bit 22 = Read VI(Fs) from backup memory? // bit 20 = Used with bit 21 to make a 2-bit key for clip flag instance
// bit 23 = Read VI(Ft) from backup memory? // bit 21
// bit 22 = Read VI(Fs) from backup memory?
// bit 23 = Read VI(Ft) from backup memory?
}; };

View File

@ -678,9 +678,20 @@ microVUt(void) mVUallocFMAC26b(int& ACCw, int& ACCr) {
} \ } \
} }
microVUt(void) mVUallocSFLAGa(int reg, int fInstance) { microVUt(void) mVUallocSFLAGa(int reg, int fInstance, bool mergeDivFlag) {
microVU* mVU = mVUx;
getFlagReg(fInstance, fInstance); getFlagReg(fInstance, fInstance);
MOVZX32R16toR(reg, fInstance); MOVZX32R16toR(reg, fInstance);
if (mergeDivFlag) {
if (mVUdivFlag && !mVUdivFlagT) {
AND32ItoR(reg, 0xc00);
if (mVUdivFlag > 1) { OR32ItoR(reg, (u32)((mVUdivFlag << 9) & 0xc00)); }
}
else {
AND32ItoR(reg, 0x30);
OR32MtoR(reg, (uptr)&mVU->divFlag[readQ]);
}
}
} }
microVUt(void) mVUallocSFLAGb(int reg, int fInstance) { microVUt(void) mVUallocSFLAGb(int reg, int fInstance) {
@ -712,6 +723,18 @@ microVUt(void) mVUallocCFLAGb(int reg, int fInstance) {
MOV32RtoM(mVU->clipFlag[fInstance], reg); MOV32RtoM(mVU->clipFlag[fInstance], reg);
} }
microVUt(void) mVUallocDFLAGa(int reg) {
microVU* mVU = mVUx;
if (!mVUdivFlag) { MOV32MtoR(reg, (uptr)&mVU->divFlag[readQ]); AND32ItoR(reg, 0xc00); }
else if (mVUdivFlag & 1) { XOR32RtoR(reg, reg); }
else { MOV32ItoR(reg, (u32)((mVUdivFlag << 9) & 0xc00)); }
}
microVUt(void) mVUallocDFLAGb(int reg) {
microVU* mVU = mVUx;
MOV32RtoM((uptr)&mVU->divFlag[writeQ], reg);
}
//------------------------------------------------------------------ //------------------------------------------------------------------
// VI Reg Allocators // VI Reg Allocators
//------------------------------------------------------------------ //------------------------------------------------------------------

View File

@ -65,6 +65,7 @@ microVUx(void) mVUcompile(u32 startPC, u32 pipelineState, microRegInfo* pState,
// First Pass // First Pass
setCode(); setCode();
mVUcycles = 1; // Skips "M" phase, and starts counting cycles at "T" stage
for (;;) { for (;;) {
startLoop(); startLoop();
mVUopU<vuIndex, 0>(); mVUopU<vuIndex, 0>();

View File

@ -25,15 +25,14 @@
microVUf(void) mVU_DIV() { microVUf(void) mVU_DIV() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) { mVUanalyzeFDIV<vuIndex>(_Fs_, _Fsf_, _Ft_, _Ftf_); }
else { else {
//u8 *pjmp;, *pjmp1; u8 *pjmp, *pjmp1;
u32 *ajmp32, *bjmp32; u32 *ajmp32, *bjmp32;
getReg5(xmmFs, _Fs_, _Fsf_); getReg5(xmmFs, _Fs_, _Fsf_);
getReg5(xmmFt, _Ft_, _Ftf_); getReg5(xmmFt, _Ft_, _Ftf_);
mVUallocDFLAGa<vuIndex>(gprT2); // Get DS/IS flags
//AND32ItoM(VU_VI_ADDR(REG_STATUS_FLAG, 2), 0xFCF); // Clear D/I flags
// FT can be zero here! so we need to check if its zero and set the correct flag. // FT can be zero here! so we need to check if its zero and set the correct flag.
SSE_XORPS_XMM_to_XMM(xmmT1, xmmT1); // Clear xmmT1 SSE_XORPS_XMM_to_XMM(xmmT1, xmmT1); // Clear xmmT1
@ -42,17 +41,17 @@ microVUf(void) mVU_DIV() {
AND32ItoR(gprT1, 1); // Grab "Is Zero" bits from the previous calculation AND32ItoR(gprT1, 1); // Grab "Is Zero" bits from the previous calculation
ajmp32 = JZ32(0); // Skip if none are ajmp32 = JZ32(0); // Skip if none are
//SSE_XORPS_XMM_to_XMM(xmmT1, xmmT1); // Clear xmmT1 SSE_XORPS_XMM_to_XMM(xmmT1, xmmT1); // Clear xmmT1
//SSE_CMPEQPS_XMM_to_XMM(xmmT1, xmmFs); // Set all F's if each vector is zero SSE_CMPEQPS_XMM_to_XMM(xmmT1, xmmFs); // Set all F's if each vector is zero
//SSE_MOVMSKPS_XMM_to_R32(gprT1, xmmT1); // Move the sign bits of the previous calculation SSE_MOVMSKPS_XMM_to_R32(gprT1, xmmT1); // Move the sign bits of the previous calculation
//AND32ItoR(gprT1, 1); // Grab "Is Zero" bits from the previous calculation AND32ItoR(gprT1, 1); // Grab "Is Zero" bits from the previous calculation
//pjmp = JZ8(0); pjmp = JZ8(0);
// OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x410 ); // Set invalid flag (0/0) OR32ItoR(gprT2, 0x410); // Set invalid flag (0/0)
// pjmp1 = JMP8(0); pjmp1 = JMP8(0);
//x86SetJ8(pjmp); x86SetJ8(pjmp);
// OR32ItoM( VU_VI_ADDR(REG_STATUS_FLAG, 2), 0x820 ); // Zero divide (only when not 0/0) OR32ItoR(gprT2, 0x820); // Zero divide (only when not 0/0)
//x86SetJ8(pjmp1); x86SetJ8(pjmp1);
SSE_XORPS_XMM_to_XMM(xmmFs, xmmFt); SSE_XORPS_XMM_to_XMM(xmmFs, xmmFt);
SSE_ANDPS_M128_to_XMM(xmmFs, (uptr)mVU_signbit); SSE_ANDPS_M128_to_XMM(xmmFs, (uptr)mVU_signbit);
@ -68,11 +67,12 @@ microVUf(void) mVU_DIV() {
mVUunpack_xyzw<vuIndex>(xmmFs, xmmFs, 0); mVUunpack_xyzw<vuIndex>(xmmFs, xmmFs, 0);
mVUmergeRegs<vuIndex>(xmmPQ, xmmFs, writeQ ? 4 : 8); mVUmergeRegs<vuIndex>(xmmPQ, xmmFs, writeQ ? 4 : 8);
mVUallocDFLAGb<vuIndex>(gprT2);
} }
} }
microVUf(void) mVU_SQRT() { microVUf(void) mVU_SQRT() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) { mVUanalyzeFDIV<vuIndex>(0, 0, _Ft_, _Ftf_); }
else { else {
//u8* pjmp; //u8* pjmp;
getReg5(xmmFt, _Ft_, _Ftf_); getReg5(xmmFt, _Ft_, _Ftf_);
@ -94,7 +94,7 @@ microVUf(void) mVU_SQRT() {
} }
microVUf(void) mVU_RSQRT() { microVUf(void) mVU_RSQRT() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) { mVUanalyzeFDIV<vuIndex>(_Fs_, _Fsf_, _Ft_, _Ftf_); }
else { else {
u8 *ajmp8, *bjmp8; u8 *ajmp8, *bjmp8;
@ -478,7 +478,7 @@ microVUf(void) mVU_FSAND() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) {}
else { else {
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance); mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance, !!(_Imm12_ & 0xc30));
AND16ItoR(gprT1, _Imm12_); AND16ItoR(gprT1, _Imm12_);
mVUallocVIb<vuIndex>(gprT1, _Ft_); mVUallocVIb<vuIndex>(gprT1, _Ft_);
} }
@ -487,7 +487,7 @@ microVUf(void) mVU_FSEQ() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) {}
else { else {
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance); mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance, 1);
XOR16ItoR(gprT1, _Imm12_); XOR16ItoR(gprT1, _Imm12_);
SUB16ItoR(gprT1, 1); SUB16ItoR(gprT1, 1);
SHR16ItoR(gprT1, 15); SHR16ItoR(gprT1, 15);
@ -498,18 +498,21 @@ microVUf(void) mVU_FSOR() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) {}
else { else {
mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance); mVUallocSFLAGa<vuIndex>(gprT1, fvsInstance, !!((_Imm12_ & 0xc30) == 0xc30));
OR16ItoR(gprT1, _Imm12_); OR16ItoR(gprT1, _Imm12_);
mVUallocVIb<vuIndex>(gprT1, _Ft_); mVUallocVIb<vuIndex>(gprT1, _Ft_);
} }
} }
microVUf(void) mVU_FSSET() { microVUf(void) mVU_FSSET() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!recPass) {} if (!recPass) { mVUdivFlagT = 4; }
else { else {
int flagReg; int flagReg;
getFlagReg(flagReg, fsInstance); getFlagReg(flagReg, fsInstance);
MOV16ItoR(gprT1, (_Imm12_ & 0xfc0)); MOV16ItoR(gprT1, (_Imm12_ & 0xfc0));
if (_Imm12_ & 0xc00) { mVUdivFlag = _Imm12_ >> 9; }
else { mVUdivFlag = 1; }
mVUdivFlagT = 4;
} }
} }

View File

@ -144,6 +144,8 @@ declareAllVariables
#define mVUbranch mVUallocInfo.branch #define mVUbranch mVUallocInfo.branch
#define mVUcycles mVUallocInfo.cycles #define mVUcycles mVUallocInfo.cycles
#define mVUstall mVUallocInfo.maxStall #define mVUstall mVUallocInfo.maxStall
#define mVUdivFlag mVUallocInfo.divFlag
#define mVUdivFlagT mVUallocInfo.divFlagTimer
#define mVUregs mVUallocInfo.regs #define mVUregs mVUallocInfo.regs
#define mVUregsTemp mVUallocInfo.regsTemp #define mVUregsTemp mVUallocInfo.regsTemp
#define mVUinfo mVUallocInfo.info[mVUallocInfo.curPC / 2] #define mVUinfo mVUallocInfo.info[mVUallocInfo.curPC / 2]

View File

@ -38,7 +38,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
else SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); // Flip wzyx to xyzw else SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); // Flip wzyx to xyzw
if (doStatus) { if (doStatus) {
getFlagReg(sReg, fsInstance); // Set sReg to valid GPR by Cur Flag Instance getFlagReg(sReg, fsInstance); // Set sReg to valid GPR by Cur Flag Instance
mVUallocSFLAGa<vuIndex>(sReg, fpsInstance); // Get Prev Status Flag mVUallocSFLAGa<vuIndex>(sReg, fpsInstance, 0); // Get Prev Status Flag
AND16ItoR(sReg, 0xff0); // Keep Sticky and D/I flags AND16ItoR(sReg, 0xff0); // Keep Sticky and D/I flags
} }