Merge pull request #593 from LegendOfDragoon/master

Optimize some opcode functions in RSP Recompiler
This commit is contained in:
zilmar 2015-09-15 10:54:32 +10:00
commit 33cb42e3dd
3 changed files with 123 additions and 8 deletions

View File

@ -444,7 +444,9 @@ void Compile_ADDI ( void ) {
if (RSPOpC.rt == 0) return; if (RSPOpC.rt == 0) return;
if (RSPOpC.rt == RSPOpC.rs) { if (RSPOpC.rt == RSPOpC.rs) {
AddConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); if(Immediate != 0) {
AddConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
}
} else if (RSPOpC.rs == 0) { } else if (RSPOpC.rs == 0) {
MoveConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); MoveConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
} else if ((IsRegConst(RSPOpC.rs) & 1) != 0) { } else if ((IsRegConst(RSPOpC.rs) & 1) != 0) {
@ -470,24 +472,52 @@ void Compile_ADDIU ( void ) {
if (RSPOpC.rt == 0) return; if (RSPOpC.rt == 0) return;
if (RSPOpC.rt == RSPOpC.rs) { if (RSPOpC.rt == RSPOpC.rs) {
AddConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); if(Immediate != 0) {
AddConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
}
} else if (RSPOpC.rs == 0) { } else if (RSPOpC.rs == 0) {
MoveConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); MoveConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
} else { } else {
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_EAX); MoveVariableToX86reg(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_EAX);
AddConstToX86Reg(x86_EAX, Immediate); if(Immediate != 0) {
AddConstToX86Reg(x86_EAX, Immediate);
}
MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
} }
} }
void Compile_SLTI ( void ) { void Compile_SLTI ( void ) {
#ifndef Compile_Immediates
Cheat_r4300iOpcode(RSP_Opcode_SLTI,"RSP_Opcode_SLTI"); Cheat_r4300iOpcode(RSP_Opcode_SLTI,"RSP_Opcode_SLTI");
#endif
int Immediate;
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (RSPOpC.rt == 0) return;
Immediate = (short)RSPOpC.immediate;
XorX86RegToX86Reg(x86_ECX, x86_ECX);
CompConstToVariable(Immediate, &RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs));
Setl(x86_ECX);
MoveX86regToVariable(x86_ECX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
} }
void Compile_SLTIU ( void ) { void Compile_SLTIU ( void ) {
#ifndef Compile_Immediates
Cheat_r4300iOpcode(RSP_Opcode_SLTIU,"RSP_Opcode_SLTIU"); Cheat_r4300iOpcode(RSP_Opcode_SLTIU,"RSP_Opcode_SLTIU");
#endif
int Immediate;
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (RSPOpC.rt == 0) return;
Immediate = (short)RSPOpC.immediate;
XorX86RegToX86Reg(x86_ECX, x86_ECX);
CompConstToVariable(Immediate, &RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs));
Setb(x86_ECX);
MoveX86regToVariable(x86_ECX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
} }
void Compile_ANDI ( void ) { void Compile_ANDI ( void ) {
@ -590,6 +620,17 @@ void Compile_LB ( void ) {
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC)); CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (IsRegConst(RSPOpC.base) == TRUE) {
char Address[32];
DWORD Addr = (MipsRegConst(RSPOpC.base) + Offset) ^ 3;
Addr &= 0xfff;
sprintf(Address, "Dmem + %Xh", Addr);
MoveSxVariableToX86regByte(RSPInfo.DMEM + Addr, Address, x86_EAX);
MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
return;
}
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX); MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset); if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset);
XorConstToX86Reg(x86_EBX, 3); XorConstToX86Reg(x86_EBX, 3);
@ -614,8 +655,15 @@ void Compile_LH ( void ) {
Addr &= 0xfff; Addr &= 0xfff;
if ((Addr & 1) != 0) { if ((Addr & 1) != 0) {
CompilerWarning("Unaligned LH at constant address PC = %04X", CompilePC); if ((Addr & 2) == 0) {
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_LH,"RSP_Opcode_LH"); CompilerWarning("Unaligned LH at constant address PC = %04X", CompilePC);
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_LH,"RSP_Opcode_LH");
} else {
char Address[32];
sprintf(Address, "Dmem + %Xh", Addr);
MoveSxVariableToX86regHalf(RSPInfo.DMEM + (Addr ^ 2), Address, x86_EAX);
MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
}
} else { } else {
char Address[32]; char Address[32];
sprintf(Address, "Dmem + %Xh", Addr); sprintf(Address, "Dmem + %Xh", Addr);
@ -667,9 +715,18 @@ void Compile_LW ( void ) {
if (IsRegConst(RSPOpC.base) == TRUE) { if (IsRegConst(RSPOpC.base) == TRUE) {
DWORD Addr = (MipsRegConst(RSPOpC.base) + Offset) & 0xfff; DWORD Addr = (MipsRegConst(RSPOpC.base) + Offset) & 0xfff;
if ((Addr & 3) != 0) { if ((Addr & 1) != 0) {
CompilerWarning("Unaligned LW at constant address PC = %04X", CompilePC); CompilerWarning("Unaligned LW at constant address PC = %04X", CompilePC);
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_LW,"RSP_Opcode_LW"); Cheat_r4300iOpcodeNoMessage(RSP_Opcode_LW,"RSP_Opcode_LW");
} else if ((Addr & 2) != 0) {
char Address[32];
sprintf(Address, "Dmem + %Xh", Addr - 2);
MoveVariableToX86regHalf(RSPInfo.DMEM + Addr - 2, Address, x86_EAX);
sprintf(Address, "Dmem + %Xh", Addr);
MoveVariableToX86regHalf(RSPInfo.DMEM + Addr + 4, Address, x86_ECX);
MoveX86regHalfToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UHW[1], GPR_Name(RSPOpC.rt));
MoveX86regHalfToVariable(x86_ECX, &RSP_GPR[RSPOpC.rt].UHW[0], GPR_Name(RSPOpC.rt));
} else { } else {
char Address[32]; char Address[32];
sprintf(Address, "Dmem + %Xh", Addr); sprintf(Address, "Dmem + %Xh", Addr);
@ -730,6 +787,17 @@ void Compile_LBU ( void ) {
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC)); CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (IsRegConst(RSPOpC.base) == TRUE) {
char Address[32];
DWORD Addr = (MipsRegConst(RSPOpC.base) + Offset) ^ 3;
Addr &= 0xfff;
sprintf(Address, "Dmem + %Xh", Addr);
MoveZxVariableToX86regByte(RSPInfo.DMEM + Addr, Address, x86_EAX);
MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
return;
}
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX); MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
XorX86RegToX86Reg(x86_EAX, x86_EAX); XorX86RegToX86Reg(x86_EAX, x86_EAX);
@ -756,8 +824,15 @@ void Compile_LHU ( void ) {
Addr &= 0xfff; Addr &= 0xfff;
if ((Addr & 1) != 0) { if ((Addr & 1) != 0) {
CompilerWarning("Unaligned LHU at constant address PC = %04X", CompilePC); if ((Addr & 2) == 0) {
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_LHU,"RSP_Opcode_LHU"); CompilerWarning("Unaligned LHU at constant address PC = %04X", CompilePC);
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_LHU, "RSP_Opcode_LHU");
} else {
char Address[32];
sprintf(Address, "Dmem + %Xh", Addr);
MoveZxVariableToX86regHalf(RSPInfo.DMEM + (Addr ^ 2), Address, x86_ECX);
MoveX86regToVariable(x86_ECX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
}
return; return;
} else { } else {
char Address[32]; char Address[32];

View File

@ -1824,6 +1824,25 @@ void MoveSxX86RegPtrDispToX86RegHalf(int AddrReg, BYTE Disp, int Destination) {
PUTDST8(RecompPos, Disp); PUTDST8(RecompPos, Disp);
} }
void MoveSxVariableToX86regByte(void *Variable, char *VariableName, int x86reg) {
CPU_Message(" movsx %s, byte ptr [%s]",x86_Name(x86reg),VariableName);
PUTDST16(RecompPos, 0xbe0f);
switch (x86reg) {
case x86_EAX: PUTDST8(RecompPos,0x05); break;
case x86_EBX: PUTDST8(RecompPos,0x1D); break;
case x86_ECX: PUTDST8(RecompPos,0x0D); break;
case x86_EDX: PUTDST8(RecompPos,0x15); break;
case x86_ESI: PUTDST8(RecompPos,0x35); break;
case x86_EDI: PUTDST8(RecompPos,0x3D); break;
case x86_ESP: PUTDST8(RecompPos,0x25); break;
case x86_EBP: PUTDST8(RecompPos,0x2D); break;
default: DisplayError("MoveSxVariableToX86regByte\nUnknown x86 Register");
}
PUTDST32(RecompPos,Variable);
}
void MoveSxVariableToX86regHalf(void *Variable, char *VariableName, int x86reg) { void MoveSxVariableToX86regHalf(void *Variable, char *VariableName, int x86reg) {
CPU_Message(" movsx %s, word ptr [%s]",x86_Name(x86reg),VariableName); CPU_Message(" movsx %s, word ptr [%s]",x86_Name(x86reg),VariableName);
@ -1963,6 +1982,25 @@ void MoveZxX86RegPtrDispToX86RegHalf(int AddrReg, BYTE Disp, int Destination) {
PUTDST8(RecompPos, Disp); PUTDST8(RecompPos, Disp);
} }
void MoveZxVariableToX86regByte(void *Variable, char *VariableName, int x86reg) {
CPU_Message(" movzx %s, byte ptr [%s]",x86_Name(x86reg),VariableName);
PUTDST16(RecompPos, 0xb60f);
switch (x86reg) {
case x86_EAX: PUTDST8(RecompPos,0x05); break;
case x86_EBX: PUTDST8(RecompPos,0x1D); break;
case x86_ECX: PUTDST8(RecompPos,0x0D); break;
case x86_EDX: PUTDST8(RecompPos,0x15); break;
case x86_ESI: PUTDST8(RecompPos,0x35); break;
case x86_EDI: PUTDST8(RecompPos,0x3D); break;
case x86_ESP: PUTDST8(RecompPos,0x25); break;
case x86_EBP: PUTDST8(RecompPos,0x2D); break;
default: DisplayError("MoveZxVariableToX86regByte\nUnknown x86 Register");
}
PUTDST32(RecompPos,Variable);
}
void MoveZxVariableToX86regHalf(void *Variable, char *VariableName, int x86reg) { void MoveZxVariableToX86regHalf(void *Variable, char *VariableName, int x86reg) {
CPU_Message(" movzx %s, word ptr [%s]",x86_Name(x86reg),VariableName); CPU_Message(" movzx %s, word ptr [%s]",x86_Name(x86reg),VariableName);

View File

@ -141,11 +141,13 @@ void MoveSxX86RegHalfToX86Reg ( int Source, int Destination );
void MoveSxX86RegPtrDispToX86RegHalf( int AddrReg, BYTE Disp, int Destination ); void MoveSxX86RegPtrDispToX86RegHalf( int AddrReg, BYTE Disp, int Destination );
void MoveSxN64MemToX86regByte ( int x86reg, int AddrReg ); void MoveSxN64MemToX86regByte ( int x86reg, int AddrReg );
void MoveSxN64MemToX86regHalf ( int x86reg, int AddrReg ); void MoveSxN64MemToX86regHalf ( int x86reg, int AddrReg );
void MoveSxVariableToX86regByte ( void *Variable, char *VariableName, int x86reg );
void MoveSxVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg ); void MoveSxVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg );
void MoveZxX86RegHalfToX86Reg ( int Source, int Destination ); void MoveZxX86RegHalfToX86Reg ( int Source, int Destination );
void MoveZxX86RegPtrDispToX86RegHalf( int AddrReg, BYTE Disp, int Destination ); void MoveZxX86RegPtrDispToX86RegHalf( int AddrReg, BYTE Disp, int Destination );
void MoveZxN64MemToX86regByte ( int x86reg, int AddrReg ); void MoveZxN64MemToX86regByte ( int x86reg, int AddrReg );
void MoveZxN64MemToX86regHalf ( int x86reg, int AddrReg ); void MoveZxN64MemToX86regHalf ( int x86reg, int AddrReg );
void MoveZxVariableToX86regByte ( void *Variable, char *VariableName, int x86reg );
void MoveZxVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg ); void MoveZxVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg );
void MulX86reg ( int x86reg ); void MulX86reg ( int x86reg );
void NegateX86reg ( int x86reg ); void NegateX86reg ( int x86reg );