From 448b0ed6beeb24861c2098c782e7fe150a69616b Mon Sep 17 00:00:00 2001 From: LegendOfDragoon Date: Thu, 22 Jan 2015 14:05:34 -0800 Subject: [PATCH 1/2] Correct a mistake I made in LDV in RSP recompiler I totally forgot that LDV handles elements differently than SDV. I added a fallback to deal with unusual elements and added an alert to notify that it exists in a particular game. I removed the & 0xF since that's not needed. My previous change caused Stunt Racer 64 to have audio issues. It should now be fixed. --- Source/RSP/Recompiler Ops.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/Source/RSP/Recompiler Ops.c b/Source/RSP/Recompiler Ops.c index b10e37726..d284e6f78 100644 --- a/Source/RSP/Recompiler Ops.c +++ b/Source/RSP/Recompiler Ops.c @@ -4445,7 +4445,7 @@ void Compile_Opcode_LLV ( void ) { void Compile_Opcode_LDV ( void ) { char Reg[256]; - int offset = (RSPOpC.voffset << 3); + int offset = (RSPOpC.voffset << 3), length; BYTE * Jump[2], * LoopEntry; #ifndef CompileLdv @@ -4459,6 +4459,11 @@ void Compile_Opcode_LDV ( void ) { // rsp_UnknownOpcode(); // return; //} + if ((RSPOpC.del & 0x3) != 0) { + CompilerWarning("LDV's element = %X, PC = %04X", RSPOpC.del, CompilePC); + Cheat_r4300iOpcodeNoMessage(RSP_Opcode_LDV,"RSP_Opcode_LDV"); + return; + } if (IsRegConst(RSPOpC.base) == TRUE) { DWORD Addr = (MipsRegConst(RSPOpC.base) + offset) & 0xfff; @@ -4474,10 +4479,12 @@ void Compile_Opcode_LDV ( void ) { sprintf(Reg, "Dmem + %Xh", Addr + 4); MoveVariableToX86reg(RSPInfo.DMEM + Addr + 4, Reg, x86_ECX); - sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF); - MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg); - sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF); - MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg); + sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4); + MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg); + if(RSPOpC.del != 12){ + sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8); + MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg); + } return; } @@ -4495,7 +4502,11 @@ void Compile_Opcode_LDV ( void ) { x86_SetBranch32b(Jump[0], 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); + length = 8; + if(RSPOpC.del == 12){ + length = 4; + } + MoveConstToX86reg(length, x86_ECX); /* mov eax, ebx dec edi @@ -4526,11 +4537,12 @@ void Compile_Opcode_LDV ( void ) { MoveN64MemDispToX86reg(x86_ECX, x86_EBX, 4); /* Because of byte swapping this swizzle works nicely */ - sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF); - MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg); - sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF); - MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg); - + sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4); + MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg); + if(RSPOpC.del != 12){ + sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8); + MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg); + } CPU_Message(" Done:"); x86_SetBranch32b(Jump[1], RecompPos); } From 55fc2a62550d1dc89222bff69b3508c256716b88 Mon Sep 17 00:00:00 2001 From: LegendOfDragoon Date: Thu, 22 Jan 2015 14:53:16 -0800 Subject: [PATCH 2/2] Correct 2 mistakes I made in SQV in RSP recompiler It may be true that this SQV edge case only seems to happen when isRegConst = true, I forgot to account for the possibility that GPR Constant Analysis could be disabled. I also just noticed that I goofed with the non-sse shuffling ;/ . The registers weren't in order. --- Source/RSP/Recompiler Ops.c | 41 +++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Source/RSP/Recompiler Ops.c b/Source/RSP/Recompiler Ops.c index d284e6f78..507bdd7ae 100644 --- a/Source/RSP/Recompiler Ops.c +++ b/Source/RSP/Recompiler Ops.c @@ -4990,13 +4990,13 @@ void Compile_Opcode_SQV ( void ) { if (IsSseEnabled == FALSE) { if (RSPOpC.del == 12) { sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt); - MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDX); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EAX); sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt); - MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EBX); sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt); - MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EBX); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_ECX); sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt); - MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_ECX); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_EDX); } else { sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt); MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX); @@ -5048,14 +5048,25 @@ void Compile_Opcode_SQV ( void ) { AndConstToX86Reg(x86_EBX, 0x0fff); 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_ECX); - sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt); - MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_EDX); - sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt); - MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDI); + if (RSPOpC.del == 12) { + sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EAX); + sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_ECX); + sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EDX); + sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_EDI); + } 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_ECX); + sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_EDX); + sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt); + MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDI); + } MoveX86regToN64MemDisp(x86_EAX, x86_EBX, 0); MoveX86regToN64MemDisp(x86_ECX, x86_EBX, 4); @@ -5064,7 +5075,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); + } SseMoveUnalignedRegToN64Mem(x86_XMM0, x86_EBX); } CPU_Message(" Done:");