mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
157e696182
commit
235b19c858
|
@ -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.
|
||||||
|
|
|
@ -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?
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue