diff --git a/Source/RSP/Recompiler Ops.c b/Source/RSP/Recompiler Ops.c index 4bbd066da..34b1ba8b4 100644 --- a/Source/RSP/Recompiler Ops.c +++ b/Source/RSP/Recompiler Ops.c @@ -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)); } } diff --git a/Source/RSP/X86.c b/Source/RSP/X86.c index c85ad3d1f..bf15021b0 100644 --- a/Source/RSP/X86.c +++ b/Source/RSP/X86.c @@ -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);