Merge pull request #1187 from LegendOfDragoon/master
Improve RSP Recompiler
This commit is contained in:
commit
721aadbd89
|
@ -517,9 +517,17 @@ void Compile_SLTI ( void ) {
|
|||
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);
|
||||
if (Immediate == 0)
|
||||
{
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_ECX);
|
||||
ShiftRightUnsignImmed(x86_ECX, 31);
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -555,6 +563,9 @@ void Compile_ANDI ( void ) {
|
|||
AndConstToVariable(Immediate, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
|
||||
} else if (RSPOpC.rs == 0) {
|
||||
MoveConstToVariable(0, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
|
||||
} else if (Immediate == 0xFFFF) {
|
||||
MoveZxVariableToX86regHalf(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_EAX);
|
||||
MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
|
||||
} else {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_EAX);
|
||||
AndConstToX86Reg(x86_EAX, Immediate);
|
||||
|
@ -910,14 +921,40 @@ void Compile_SB ( void ) {
|
|||
|
||||
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
|
||||
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
|
||||
MoveVariableToX86regByte(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
if (IsRegConst(RSPOpC.base) == TRUE) {
|
||||
char Address[32];
|
||||
DWORD Addr = (MipsRegConst(RSPOpC.base) + Offset) ^ 3;
|
||||
Addr &= 0xfff;
|
||||
sprintf(Address, "Dmem + %Xh", Addr);
|
||||
|
||||
if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset);
|
||||
XorConstToX86Reg(x86_EBX, 3);
|
||||
AndConstToX86Reg(x86_EBX, 0x0fff);
|
||||
if (IsRegConst(RSPOpC.rt) == TRUE) {
|
||||
MoveConstByteToVariable(MipsRegConst(RSPOpC.rt), RSPInfo.DMEM + Addr, Address);
|
||||
return;
|
||||
} else {
|
||||
MoveVariableToX86regByte(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regByteToVariable(x86_EAX, RSPInfo.DMEM + Addr, Address);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MoveX86regByteToN64Mem(x86_EAX, x86_EBX);
|
||||
if (IsRegConst(RSPOpC.rt) == TRUE) {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
|
||||
|
||||
if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset);
|
||||
XorConstToX86Reg(x86_EBX, 3);
|
||||
AndConstToX86Reg(x86_EBX, 0x0fff);
|
||||
|
||||
MoveConstByteToN64Mem(MipsRegConst(RSPOpC.rt), x86_EBX);
|
||||
} else {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
|
||||
MoveVariableToX86regByte(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
|
||||
if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset);
|
||||
XorConstToX86Reg(x86_EBX, 3);
|
||||
AndConstToX86Reg(x86_EBX, 0x0fff);
|
||||
|
||||
MoveX86regByteToN64Mem(x86_EAX, x86_EBX);
|
||||
}
|
||||
}
|
||||
|
||||
void Compile_SH ( void ) {
|
||||
|
@ -941,8 +978,12 @@ void Compile_SH ( void ) {
|
|||
} else {
|
||||
char Address[32];
|
||||
sprintf(Address, "Dmem + %Xh", Addr);
|
||||
MoveVariableToX86regHalf(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regHalfToVariable(x86_EAX, RSPInfo.DMEM + Addr, Address);
|
||||
if (IsRegConst(RSPOpC.rt) == TRUE) {
|
||||
MoveConstHalfToVariable(MipsRegConst(RSPOpC.rt), RSPInfo.DMEM + Addr, Address);
|
||||
} else {
|
||||
MoveVariableToX86regHalf(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regHalfToVariable(x86_EAX, RSPInfo.DMEM + Addr, Address);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -968,8 +1009,12 @@ void Compile_SH ( void ) {
|
|||
XorConstToX86Reg(x86_EBX, 2);
|
||||
AndConstToX86Reg(x86_EBX, 0x0fff);
|
||||
|
||||
MoveVariableToX86regHalf(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regHalfToN64Mem(x86_EAX, x86_EBX);
|
||||
if (IsRegConst(RSPOpC.rt) == TRUE) {
|
||||
MoveConstHalfToN64Mem(MipsRegConst(RSPOpC.rt), x86_EBX);
|
||||
} else {
|
||||
MoveVariableToX86regHalf(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regHalfToN64Mem(x86_EAX, x86_EBX);
|
||||
}
|
||||
|
||||
CPU_Message(" Done:");
|
||||
x86_SetBranch32b(Jump[1], RecompPos);
|
||||
|
@ -986,17 +1031,38 @@ void Compile_SW ( void ) {
|
|||
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
|
||||
|
||||
if (IsRegConst(RSPOpC.base) == TRUE) {
|
||||
char Address[32];
|
||||
DWORD Addr = (MipsRegConst(RSPOpC.base) + Offset) & 0xfff;
|
||||
|
||||
if ((Addr & 3) != 0) {
|
||||
CompilerWarning("Unaligned SW at constant address PC = %04X", CompilePC);
|
||||
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_SW,"RSP_Opcode_SW");
|
||||
if (Addr > 0xFFC) {
|
||||
DisplayError("hmmmm.... Problem with:\nRSP_SW_DMEM");
|
||||
return;
|
||||
}
|
||||
if (IsRegConst(RSPOpC.rt) == TRUE) {
|
||||
DWORD Value = MipsRegConst(RSPOpC.rt);
|
||||
sprintf(Address, "Dmem + %Xh", (Addr + 0) ^ 3);
|
||||
MoveConstByteToVariable((Value >> 24) & 0xFF, RSPInfo.DMEM + ((Addr + 0) ^ 3), Address);
|
||||
sprintf(Address, "Dmem + %Xh", (Addr + 1) ^ 3);
|
||||
MoveConstByteToVariable((Value >> 16) & 0xFF, RSPInfo.DMEM + ((Addr + 1) ^ 3), Address);
|
||||
sprintf(Address, "Dmem + %Xh", (Addr + 2) ^ 3);
|
||||
MoveConstByteToVariable((Value >> 8) & 0xFF, RSPInfo.DMEM + ((Addr + 2) ^ 3), Address);
|
||||
sprintf(Address, "Dmem + %Xh", (Addr + 3) ^ 3);
|
||||
MoveConstByteToVariable((Value >> 0) & 0xFF, RSPInfo.DMEM + ((Addr + 3) ^ 3), Address);
|
||||
} else {
|
||||
CompilerWarning("Unaligned SW at constant address PC = %04X", CompilePC);
|
||||
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_SW,"RSP_Opcode_SW");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
char Address[32];
|
||||
sprintf(Address, "Dmem + %Xh", Addr);
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regToVariable(x86_EAX, RSPInfo.DMEM + Addr, Address);
|
||||
|
||||
if (IsRegConst(RSPOpC.rt) == TRUE) {
|
||||
MoveConstToVariable(MipsRegConst(RSPOpC.rt), RSPInfo.DMEM + Addr, Address);
|
||||
} else {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regToVariable(x86_EAX, RSPInfo.DMEM + Addr, Address);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1043,12 +1109,12 @@ void Compile_SW ( void ) {
|
|||
|
||||
CompilerToggleBuffer();
|
||||
|
||||
if (RSPOpC.rt == 0) {
|
||||
XorX86RegToX86Reg(x86_EAX,x86_EAX);
|
||||
if (IsRegConst(RSPOpC.rt) == TRUE) {
|
||||
MoveConstToN64Mem(MipsRegConst(RSPOpC.rt), x86_EBX);
|
||||
} else {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
MoveX86regToN64Mem(x86_EAX, x86_EBX);
|
||||
}
|
||||
MoveX86regToN64Mem(x86_EAX, x86_EBX);
|
||||
|
||||
CPU_Message(" Done:");
|
||||
x86_SetBranch32b(Jump[1], RecompPos);
|
||||
|
@ -1432,26 +1498,26 @@ void Compile_Special_SLT ( void ) {
|
|||
#endif
|
||||
|
||||
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
|
||||
if (RSPOpC.rt == 0) { return; }
|
||||
if (RSPOpC.rd == 0) { return; }
|
||||
|
||||
if (RSPOpC.rt == RSPOpC.rs) {
|
||||
MoveConstToVariable(0, &RSP_GPR[RSPOpC.rd].UW, GPR_Name(RSPOpC.rd));
|
||||
} else {
|
||||
XorX86RegToX86Reg(x86_EBX, x86_EBX);
|
||||
if (RSPOpC.rs == 0) {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX);
|
||||
XorX86RegToX86Reg(x86_ECX, x86_ECX);
|
||||
CompConstToX86reg(x86_EAX, 0);
|
||||
Setg(x86_EBX);
|
||||
Setg(x86_ECX);
|
||||
} else if (RSPOpC.rt == 0) {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_EAX);
|
||||
CompConstToX86reg(x86_EAX, 0);
|
||||
Setl(x86_EBX);
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_ECX);
|
||||
ShiftRightUnsignImmed(x86_ECX, 31);
|
||||
} else {
|
||||
MoveVariableToX86reg(&RSP_GPR[RSPOpC.rs].UW, GPR_Name(RSPOpC.rs), x86_EAX);
|
||||
XorX86RegToX86Reg(x86_ECX, x86_ECX);
|
||||
CompX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
|
||||
Setl(x86_EBX);
|
||||
Setl(x86_ECX);
|
||||
}
|
||||
MoveX86regToVariable(x86_EBX, &RSP_GPR[RSPOpC.rd].UW, GPR_Name(RSPOpC.rd));
|
||||
MoveX86regToVariable(x86_ECX, &RSP_GPR[RSPOpC.rd].UW, GPR_Name(RSPOpC.rd));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1154,6 +1154,51 @@ void LeaSourceAndOffset(int x86DestReg, int x86SourceReg, size_t offset) {
|
|||
}
|
||||
}
|
||||
|
||||
void MoveConstByteToN64Mem(BYTE Const, int AddrReg) {
|
||||
WORD x86Command = 0;
|
||||
|
||||
CPU_Message(" mov byte ptr [%s+Dmem], %Xh", x86_Name(AddrReg), Const);
|
||||
switch (AddrReg) {
|
||||
case x86_EAX: x86Command = 0x80C6; break;
|
||||
case x86_EBX: x86Command = 0x83C6; break;
|
||||
case x86_ECX: x86Command = 0x81C6; break;
|
||||
case x86_EDX: x86Command = 0x82C6; break;
|
||||
case x86_ESI: x86Command = 0x86C6; break;
|
||||
case x86_EDI: x86Command = 0x87C6; break;
|
||||
case x86_ESP: x86Command = 0x84C6; break;
|
||||
case x86_EBP: x86Command = 0x85C6; break;
|
||||
default:
|
||||
DisplayError("MoveConstByteToN64Mem\nUnknown x86 Register");
|
||||
}
|
||||
|
||||
PUTDST16(RecompPos, x86Command);
|
||||
PUTDST32(RecompPos, RSPInfo.DMEM);
|
||||
PUTDST8(RecompPos, Const);
|
||||
}
|
||||
|
||||
void MoveConstHalfToN64Mem(WORD Const, int AddrReg) {
|
||||
BYTE x86Command = 0;
|
||||
|
||||
CPU_Message(" mov word ptr [%s+Dmem], %Xh", x86_Name(AddrReg), Const);
|
||||
PUTDST16(RecompPos, 0xC766);
|
||||
switch (AddrReg) {
|
||||
case x86_EAX: x86Command = 0x80; break;
|
||||
case x86_EBX: x86Command = 0x83; break;
|
||||
case x86_ECX: x86Command = 0x81; break;
|
||||
case x86_EDX: x86Command = 0x82; break;
|
||||
case x86_ESI: x86Command = 0x86; break;
|
||||
case x86_EDI: x86Command = 0x87; break;
|
||||
case x86_ESP: x86Command = 0x84; break;
|
||||
case x86_EBP: x86Command = 0x85; break;
|
||||
default:
|
||||
DisplayError("MoveConstHalfToN64Mem\nUnknown x86 Register");
|
||||
}
|
||||
|
||||
PUTDST8(RecompPos, x86Command);
|
||||
PUTDST32(RecompPos, RSPInfo.DMEM);
|
||||
PUTDST16(RecompPos, Const);
|
||||
}
|
||||
|
||||
void MoveConstByteToVariable (BYTE Const,void *Variable, char *VariableName) {
|
||||
CPU_Message(" mov byte ptr [%s], %Xh",VariableName,Const);
|
||||
PUTDST16(RecompPos,0x05C6);
|
||||
|
@ -1169,6 +1214,28 @@ void MoveConstHalfToVariable (WORD Const,void *Variable, char *VariableName) {
|
|||
PUTDST16(RecompPos,Const);
|
||||
}
|
||||
|
||||
void MoveConstToN64Mem(DWORD Const, int AddrReg) {
|
||||
WORD x86Command = 0;
|
||||
|
||||
CPU_Message(" mov dword ptr [%s+Dmem], %Xh", x86_Name(AddrReg), Const);
|
||||
switch (AddrReg) {
|
||||
case x86_EAX: x86Command = 0x80C7; break;
|
||||
case x86_EBX: x86Command = 0x83C7; break;
|
||||
case x86_ECX: x86Command = 0x81C7; break;
|
||||
case x86_EDX: x86Command = 0x82C7; break;
|
||||
case x86_ESI: x86Command = 0x86C7; break;
|
||||
case x86_EDI: x86Command = 0x87C7; break;
|
||||
case x86_ESP: x86Command = 0x84C7; break;
|
||||
case x86_EBP: x86Command = 0x85C7; break;
|
||||
default:
|
||||
DisplayError("MoveConstToN64Mem\nUnknown x86 Register");
|
||||
}
|
||||
|
||||
PUTDST16(RecompPos, x86Command);
|
||||
PUTDST32(RecompPos, RSPInfo.DMEM);
|
||||
PUTDST32(RecompPos, Const);
|
||||
}
|
||||
|
||||
void MoveConstToVariable (DWORD Const,void *Variable, char *VariableName) {
|
||||
CPU_Message(" mov dword ptr [%s], %Xh",VariableName,Const);
|
||||
PUTDST16(RecompPos,0x05C7);
|
||||
|
|
Loading…
Reference in New Issue