Skip to content

Commit

Permalink
Matched RSP interpreter more closely
Browse files Browse the repository at this point in the history
I have only seen the edgecase for SQV happen when
IsRegConst(RSPOpC.base) == TRUE. Changing SQV fixed Telefoot / Mia Ham.

I optimized VAND, for games like Kirby64.
  • Loading branch information
LegendOfDragoon committed Jan 12, 2015
1 parent 02fe2e7 commit 1cb03b4
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 53 deletions.
3 changes: 1 addition & 2 deletions Source/RSP/Recompiler Analysis.c
Expand Up @@ -278,11 +278,10 @@ DWORD WriteToAccum2 (int Location, int PC, BOOL RecursiveCall) {
case RSP_VECTOR_VEQ:
case RSP_VECTOR_VGE:
case RSP_VECTOR_VMRG:
case RSP_VECTOR_VMOV:
if (Location == Low16BitAccum) { return FALSE; }
break;

case RSP_VECTOR_VMOV:
break;
case RSP_VECTOR_VSAW:
return TRUE;
default:
Expand Down
135 changes: 84 additions & 51 deletions Source/RSP/Recompiler Ops.c
Expand Up @@ -3134,10 +3134,11 @@ void Compile_Vector_VADD ( void ) {

AdcX86RegToX86Reg(x86_EAX, x86_EBX);

if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {
if (bWriteToDest != FALSE) {
CompX86RegToX86Reg(x86_EAX, x86_ESI);
CondMoveGreater(x86_EAX, x86_ESI);
CompX86RegToX86Reg(x86_EAX, x86_EDI);
Expand Down Expand Up @@ -3248,10 +3249,12 @@ void Compile_Vector_VSUB ( void ) {

SbbX86RegToX86Reg(x86_EAX, x86_EBX);

if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {

if (bWriteToDest != FALSE) {
CompX86RegToX86Reg(x86_EAX, x86_ESI);
CondMoveGreater(x86_EAX, x86_ESI);
CompX86RegToX86Reg(x86_EAX, x86_EDI);
Expand Down Expand Up @@ -3408,10 +3411,12 @@ void Compile_Vector_VADDC ( void ) {
}
OrX86RegToX86Reg(x86_ECX, x86_EDX);

if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {

if (bWriteToDest != FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
Expand Down Expand Up @@ -3470,10 +3475,11 @@ void Compile_Vector_VSUBC ( void ) {
ShiftLeftSignImmed(x86_EDX, 7 - el);
OrX86RegToX86Reg(x86_ECX, x86_EDX);

if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {
if (bWriteToDest != FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
Expand Down Expand Up @@ -3690,6 +3696,7 @@ BOOL Compile_Vector_VAND_MMX ( void ) {
void Compile_Vector_VAND ( void ) {
char Reg[256];
int el, del, count;
BOOL bWriteToDest = WriteToVectorDest(RSPOpC.sa, CompilePC);
BOOL bElement = ((RSPOpC.rs & 0x0f) >= 8) ? TRUE : FALSE;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);

Expand Down Expand Up @@ -3726,11 +3733,13 @@ void Compile_Vector_VAND ( void ) {
AndX86RegHalfToX86RegHalf(x86_EAX, x86_EBX);
}

sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
if (bWriteToDest != FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}

if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[el].HW[1]", el);
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
}
Expand Down Expand Up @@ -3964,13 +3973,22 @@ void Compile_Vector_VRCPH ( void ) {

void Compile_Vector_VMOV ( void ) {
char Reg[256];
int el;
int el, count;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
#ifndef CompileVmov
Cheat_r4300iOpcode(RSP_Vector_VMOV, "RSP_Vector_VMOV"); return;
#endif

#ifndef CompileVmov
Cheat_r4300iOpcode(RSP_Vector_VMOV,"RSP_Vector_VMOV"); return;
#endif
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));

CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (bWriteToAccum){
for (count = 0; count < 8; count++) {
sprintf(Reg, "RSP_Vect[%i].UHW[%i]", RSPOpC.rt, EleSpec[RSPOpC.rs].B[count]);
MoveVariableToX86regHalf(&RSP_Vect[RSPOpC.rt].UHW[EleSpec[RSPOpC.rs].B[count]], Reg, x86_EAX);
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", count);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[count].HW[1], Reg);
}
}

el = EleSpec[RSPOpC.rs].B[(RSPOpC.rd & 0x7)];
sprintf(Reg, "RSP_Vect[%i].UHW[%i]", RSPOpC.rt, el);
Expand Down Expand Up @@ -4585,40 +4603,40 @@ void Compile_Opcode_SLV ( void ) {
void Compile_Opcode_SDV ( void ) {
char Reg[256];
int offset = (RSPOpC.voffset << 3);
BYTE * Jump[2], * LoopEntry;
BYTE * Jump[2], *LoopEntry;

//if ((RSPOpC.del & 0x7) != 0) {
// rsp_UnknownOpcode();
// return;
//}

#ifndef CompileSdv
Cheat_r4300iOpcode(RSP_Opcode_SDV,"RSP_Opcode_SDV"); return;
#endif
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
#ifndef CompileSdv
Cheat_r4300iOpcode(RSP_Opcode_SDV, "RSP_Opcode_SDV"); return;
#endif

CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));

if (IsRegConst(RSPOpC.base) == TRUE) {
DWORD Addr = (MipsRegConst(RSPOpC.base) + offset) & 0xfff;

if ((Addr & 3) != 0) {
CompilerWarning("Unaligned SDV at constant address PC = %04X", CompilePC);
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_SDV,"RSP_Opcode_SDV");
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_SDV, "RSP_Opcode_SDV");
return;
}

sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg, x86_EBX);

sprintf(Reg, "Dmem + %Xh", Addr);
MoveX86regToVariable(x86_EAX, RSPInfo.DMEM + Addr, Reg);
sprintf(Reg, "Dmem + %Xh", Addr + 4);
MoveX86regToVariable(x86_EBX, RSPInfo.DMEM + Addr + 4, Reg);
return;
}

MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
if (offset != 0) {
AddConstToX86Reg(x86_EBX, offset);
Expand All @@ -4627,11 +4645,11 @@ void Compile_Opcode_SDV ( void ) {
TestConstToX86Reg(3, x86_EBX);
JneLabel32("Unaligned", 0);
Jump[0] = RecompPos - 4;

CompilerToggleBuffer();
CPU_Message(" Unaligned:");
x86_SetBranch32b((DWORD*)Jump[0], (DWORD*)RecompPos);

sprintf(Reg, "RSP_Vect[%i].UB[%i]", RSPOpC.rt, 15 - RSPOpC.del);
MoveOffsetToX86reg((DWORD)&RSP_Vect[RSPOpC.rt].UB[15 - RSPOpC.del], Reg, x86_EDI);
MoveConstToX86reg(8, x86_ECX);
Expand All @@ -4652,10 +4670,10 @@ void Compile_Opcode_SDV ( void ) {
Jump[1] = RecompPos - 4;
CompilerToggleBuffer();

sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg, x86_ECX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg, x86_ECX);
MoveX86regToN64Mem(x86_EAX, x86_EBX);
MoveX86regToN64MemDisp(x86_ECX, x86_EBX, 4);

Expand All @@ -4674,10 +4692,10 @@ void Compile_Opcode_SQV ( void ) {

CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));

if (RSPOpC.del != 0) {
rsp_UnknownOpcode();
return;
}
//if (RSPOpC.del != 0) {
// rsp_UnknownOpcode();
// return;
//}

if (IsRegConst(RSPOpC.base) == TRUE) {
DWORD Addr = (MipsRegConst(RSPOpC.base) + offset) & 0xfff;
Expand All @@ -4693,14 +4711,25 @@ void Compile_Opcode_SQV ( void ) {
*/

if (IsSseEnabled == FALSE) {
sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_ECX);
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDX);
if (RSPOpC.del == 12) {
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDX);
sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_ECX);
} else {
sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_ECX);
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDX);
}

sprintf(Reg, "Dmem+%Xh+0", Addr);
MoveX86regToVariable(x86_EAX, RSPInfo.DMEM + Addr + 0, Reg);
Expand All @@ -4713,7 +4742,11 @@ void Compile_Opcode_SQV ( void ) {
} else {
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
SseMoveAlignedVariableToReg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_XMM0);
SseShuffleReg(x86_XMM0, x86_MM0, 0x1b);
if (RSPOpC.del == 12) {
SseShuffleReg(x86_XMM0, x86_MM0, 0x6c);
} else {
SseShuffleReg(x86_XMM0, x86_MM0, 0x1b);
}
sprintf(Reg, "Dmem+%Xh", Addr);
SseMoveUnalignedRegToVariable(x86_XMM0, RSPInfo.DMEM + Addr, Reg);
}
Expand Down

0 comments on commit 1cb03b4

Please sign in to comment.