diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 3255d6c51..ffe5d940b 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -297,38 +297,38 @@ void R4300iOp::BuildInterpreter(bool Force32bit) Jump_Opcode[29] = &R4300iOp::UnknownOpcode; Jump_Opcode[30] = &R4300iOp::UnknownOpcode; Jump_Opcode[31] = &R4300iOp::ReservedInstruction; - Jump_Opcode[32] = &R4300iOp::LB; - Jump_Opcode[33] = &R4300iOp::LH; - Jump_Opcode[34] = &R4300iOp::LWL; + Jump_Opcode[32] = Force32bit ? &R4300iOp::LB_32 : &R4300iOp::LB; + Jump_Opcode[33] = Force32bit ? &R4300iOp::LH_32 : &R4300iOp::LH; + Jump_Opcode[34] = Force32bit ? &R4300iOp::LWL_32 : &R4300iOp::LWL; Jump_Opcode[35] = Force32bit ? &R4300iOp::LW_32 : &R4300iOp::LW; - Jump_Opcode[36] = &R4300iOp::LBU; - Jump_Opcode[37] = &R4300iOp::LHU; - Jump_Opcode[38] = &R4300iOp::LWR; - Jump_Opcode[39] = &R4300iOp::LWU; - Jump_Opcode[40] = &R4300iOp::SB; - Jump_Opcode[41] = &R4300iOp::SH; - Jump_Opcode[42] = &R4300iOp::SWL; + Jump_Opcode[36] = Force32bit ? &R4300iOp::LBU_32 : &R4300iOp::LBU; + Jump_Opcode[37] = Force32bit ? &R4300iOp::LHU_32 : &R4300iOp::LHU; + Jump_Opcode[38] = Force32bit ? &R4300iOp::LWR_32 : &R4300iOp::LWR; + Jump_Opcode[39] = Force32bit ? &R4300iOp::LWU_32 : &R4300iOp::LWU; + Jump_Opcode[40] = Force32bit ? &R4300iOp::SB_32 : &R4300iOp::SB; + Jump_Opcode[41] = Force32bit ? &R4300iOp::SH_32 : &R4300iOp::SH; + Jump_Opcode[42] = Force32bit ? &R4300iOp::SWL_32 : &R4300iOp::SWL; Jump_Opcode[43] = Force32bit ? &R4300iOp::SW_32 : &R4300iOp::SW; - Jump_Opcode[44] = &R4300iOp::SDL; - Jump_Opcode[45] = &R4300iOp::SDR; - Jump_Opcode[46] = &R4300iOp::SWR; + Jump_Opcode[44] = Force32bit ? &R4300iOp::SDL_32 : &R4300iOp::SDL; + Jump_Opcode[45] = Force32bit ? &R4300iOp::SDR_32 : &R4300iOp::SDR; + Jump_Opcode[46] = Force32bit ? &R4300iOp::SWR_32 : &R4300iOp::SWR; Jump_Opcode[47] = &R4300iOp::CACHE; - Jump_Opcode[48] = &R4300iOp::LL; - Jump_Opcode[49] = &R4300iOp::LWC1; + Jump_Opcode[48] = Force32bit ? &R4300iOp::LL_32 : &R4300iOp::LL; + Jump_Opcode[49] = Force32bit ? &R4300iOp::LWC1_32 : &R4300iOp::LWC1; Jump_Opcode[50] = &R4300iOp::UnknownOpcode; Jump_Opcode[51] = &R4300iOp::UnknownOpcode; - Jump_Opcode[52] = &R4300iOp::LLD; - Jump_Opcode[53] = &R4300iOp::LDC1; + Jump_Opcode[52] = Force32bit ? &R4300iOp::LLD_32 : &R4300iOp::LLD; + Jump_Opcode[53] = Force32bit ? &R4300iOp::LDC1_32 : &R4300iOp::LDC1; Jump_Opcode[54] = &R4300iOp::UnknownOpcode; - Jump_Opcode[55] = &R4300iOp::LD; - Jump_Opcode[56] = &R4300iOp::SC; - Jump_Opcode[57] = &R4300iOp::SWC1; + Jump_Opcode[55] = Force32bit ? &R4300iOp::LD_32 : &R4300iOp::LD; + Jump_Opcode[56] = Force32bit ? &R4300iOp::SC_32 : &R4300iOp::SC; + Jump_Opcode[57] = Force32bit ? &R4300iOp::SWC1_32 : &R4300iOp::SWC1; Jump_Opcode[58] = &R4300iOp::UnknownOpcode; Jump_Opcode[59] = &R4300iOp::UnknownOpcode; Jump_Opcode[60] = &R4300iOp::UnknownOpcode; - Jump_Opcode[61] = &R4300iOp::SDC1; + Jump_Opcode[61] = Force32bit ? &R4300iOp::SDC1_32 : &R4300iOp::SDC1; Jump_Opcode[62] = &R4300iOp::UnknownOpcode; - Jump_Opcode[63] = &R4300iOp::SD; + Jump_Opcode[63] = Force32bit ? &R4300iOp::SD_32 : &R4300iOp::SD; Jump_Special[0] = &R4300iOp::SPECIAL_SLL; Jump_Special[1] = &R4300iOp::UnknownOpcode; @@ -1148,6 +1148,16 @@ void R4300iOp::LB() } } +void R4300iOp::LB_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint8_t MemoryValue; + if (m_MMU.LB_Memory(Address, MemoryValue)) + { + m_GPR[m_Opcode.rt].DW = (int8_t)MemoryValue; + } +} + void R4300iOp::LH() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1158,6 +1168,16 @@ void R4300iOp::LH() } } +void R4300iOp::LH_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint16_t MemoryValue; + if (m_MMU.LH_Memory(Address, MemoryValue)) + { + m_GPR[m_Opcode.rt].DW = (int16_t)MemoryValue; + } +} + void R4300iOp::LWL() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1171,6 +1191,19 @@ void R4300iOp::LWL() } } +void R4300iOp::LWL_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + + if (m_MMU.LW_Memory((Address & ~3), MemoryValue)) + { + uint32_t Offset = Address & 3; + m_GPR[m_Opcode.rt].DW = (int32_t)(m_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]); + m_GPR[m_Opcode.rt].DW += (int32_t)(MemoryValue << LWL_SHIFT[Offset]); + } +} + void R4300iOp::LW() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1203,6 +1236,16 @@ void R4300iOp::LBU() } } +void R4300iOp::LBU_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint8_t MemoryValue; + if (m_MMU.LB_Memory(Address, MemoryValue)) + { + m_GPR[m_Opcode.rt].UDW = MemoryValue; + } +} + void R4300iOp::LHU() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1213,6 +1256,16 @@ void R4300iOp::LHU() } } +void R4300iOp::LHU_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint16_t MemoryValue; + if (m_MMU.LH_Memory(Address, MemoryValue)) + { + m_GPR[m_Opcode.rt].UDW = MemoryValue; + } +} + void R4300iOp::LWR() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1226,6 +1279,19 @@ void R4300iOp::LWR() } } +void R4300iOp::LWR_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + + if (m_MMU.LW_Memory((Address & ~3), MemoryValue)) + { + uint32_t Offset = Address & 3; + m_GPR[m_Opcode.rt].DW = (int32_t)(m_GPR[m_Opcode.rt].W[0] & LWR_MASK[Offset]); + m_GPR[m_Opcode.rt].DW += (int32_t)(MemoryValue >> LWR_SHIFT[Offset]); + } +} + void R4300iOp::LWU() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1237,18 +1303,41 @@ void R4300iOp::LWU() } } +void R4300iOp::LWU_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + + if (m_MMU.LW_Memory(Address, MemoryValue)) + { + m_GPR[m_Opcode.rt].UDW = MemoryValue; + } +} + void R4300iOp::SB() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; m_MMU.SB_Memory(Address, m_GPR[m_Opcode.rt].UW[0]); } +void R4300iOp::SB_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.SB_Memory(Address, m_GPR[m_Opcode.rt].UW[0]); +} + void R4300iOp::SH() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; m_MMU.SH_Memory(Address, m_GPR[m_Opcode.rt].UW[0]); } +void R4300iOp::SH_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.SH_Memory(Address, m_GPR[m_Opcode.rt].UW[0]); +} + void R4300iOp::SWL() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1267,6 +1356,24 @@ void R4300iOp::SWL() } } +void R4300iOp::SWL_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + + if (m_MMU.MemoryValue32(Address & ~3, MemoryValue)) + { + uint32_t Offset = Address & 3; + MemoryValue &= SWL_MASK[Offset]; + MemoryValue += m_GPR[m_Opcode.rt].UW[0] >> SWL_SHIFT[Offset]; + m_MMU.SW_Memory(Address & ~3, MemoryValue); + } + else + { + m_Reg.TriggerAddressException(Address, EXC_WMISS); + } +} + void R4300iOp::SW() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1306,6 +1413,23 @@ void R4300iOp::SDL() } } +void R4300iOp::SDL_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint64_t MemoryValue; + if (m_MMU.MemoryValue64((Address & ~7), MemoryValue)) + { + uint32_t Offset = Address & 7; + MemoryValue &= SDL_MASK[Offset]; + MemoryValue += m_GPR[m_Opcode.rt].UDW >> SDL_SHIFT[Offset]; + m_MMU.SD_Memory((Address & ~7), MemoryValue); + } + else + { + m_Reg.TriggerAddressException(Address, EXC_WMISS); + } +} + uint64_t SDR_MASK[8] = {0x00FFFFFFFFFFFFFF, 0x0000FFFFFFFFFFFF, 0x000000FFFFFFFFFF, @@ -1334,6 +1458,23 @@ void R4300iOp::SDR() } } +void R4300iOp::SDR_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint64_t MemoryValue; + if (m_MMU.MemoryValue64((Address & ~7), MemoryValue)) + { + uint32_t Offset = Address & 7; + MemoryValue &= SDR_MASK[Offset]; + MemoryValue += m_GPR[m_Opcode.rt].UDW << SDR_SHIFT[Offset]; + m_MMU.SD_Memory((Address & ~7), MemoryValue); + } + else + { + m_Reg.TriggerAddressException(Address, EXC_WMISS); + } +} + void R4300iOp::SWR() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1352,6 +1493,24 @@ void R4300iOp::SWR() } } +void R4300iOp::SWR_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + + if (m_MMU.MemoryValue32((Address & ~3), MemoryValue)) + { + uint32_t Offset = Address & 3; + MemoryValue &= SWR_MASK[Offset]; + MemoryValue += m_GPR[m_Opcode.rt].UW[0] << SWR_SHIFT[Offset]; + m_MMU.SW_Memory((Address & ~0x03), MemoryValue); + } + else + { + m_Reg.TriggerAddressException(Address, EXC_WMISS); + } +} + void R4300iOp::CACHE() { if (!LogCache()) @@ -1377,6 +1536,22 @@ void R4300iOp::LL() } } +void R4300iOp::LL_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + + if (m_MMU.LW_Memory(Address, MemoryValue)) + { + m_GPR[m_Opcode.rt].DW = (int32_t)MemoryValue; + m_LLBit = 1; + uint32_t PhysicalAddr; + bool MemoryUsed; + m_TLB.VAddrToPAddr(Address, PhysicalAddr, MemoryUsed); + m_CP0[17] = PhysicalAddr >> 4; + } +} + void R4300iOp::LWC1() { if (TestCop1UsableException()) @@ -1387,6 +1562,16 @@ void R4300iOp::LWC1() m_MMU.LW_Memory(Address, *(uint32_t *)m_FPR_S[m_Opcode.ft]); } +void R4300iOp::LWC1_32() +{ + if (TestCop1UsableException()) + { + return; + } + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.LW_Memory(Address, *(uint32_t *)m_FPR_S[m_Opcode.ft]); +} + void R4300iOp::SC() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1396,6 +1581,15 @@ void R4300iOp::SC() } } +void R4300iOp::SC_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + if (m_LLBit != 1 || m_MMU.SW_Memory(Address, m_GPR[m_Opcode.rt].UW[0])) + { + m_GPR[m_Opcode.rt].UW[0] = m_LLBit; + } +} + void R4300iOp::LD() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1410,6 +1604,20 @@ void R4300iOp::LD() } } +void R4300iOp::LD_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + if (m_MMU.LD_Memory(Address, m_GPR[m_Opcode.rt].UDW)) + { +#ifdef Interpreter_StackTest + if (m_Opcode.rt == 29) + { + StackValue = m_GPR[m_Opcode.rt].W[0]; + } +#endif + } +} + void R4300iOp::LLD() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; @@ -1423,6 +1631,19 @@ void R4300iOp::LLD() } } +void R4300iOp::LLD_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + if (m_MMU.LD_Memory(Address, m_GPR[m_Opcode.rt].UDW)) + { + m_LLBit = 1; + uint32_t PhysicalAddr; + bool MemoryUsed; + m_TLB.VAddrToPAddr(Address, PhysicalAddr, MemoryUsed); + m_CP0[17] = PhysicalAddr >> 4; + } +} + void R4300iOp::LDC1() { if (TestCop1UsableException()) @@ -1433,6 +1654,16 @@ void R4300iOp::LDC1() m_MMU.LD_Memory(Address, *(uint64_t *)m_FPR_D[m_Opcode.ft]); } +void R4300iOp::LDC1_32() +{ + if (TestCop1UsableException()) + { + return; + } + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.LD_Memory(Address, *(uint64_t *)m_FPR_D[m_Opcode.ft]); +} + void R4300iOp::SWC1() { if (TestCop1UsableException()) @@ -1444,6 +1675,17 @@ void R4300iOp::SWC1() m_MMU.SW_Memory(Address, *(uint32_t *)m_FPR_S[m_Opcode.ft]); } +void R4300iOp::SWC1_32() +{ + if (TestCop1UsableException()) + { + return; + } + + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.SW_Memory(Address, *(uint32_t *)m_FPR_S[m_Opcode.ft]); +} + void R4300iOp::SDC1() { if (TestCop1UsableException()) @@ -1454,12 +1696,28 @@ void R4300iOp::SDC1() m_MMU.SD_Memory(Address, *((uint64_t *)m_FPR_D[m_Opcode.ft])); } +void R4300iOp::SDC1_32() +{ + if (TestCop1UsableException()) + { + return; + } + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.SD_Memory(Address, *((uint64_t *)m_FPR_D[m_Opcode.ft])); +} + void R4300iOp::SD() { uint64_t Address = m_GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; m_MMU.SD_Memory(Address, m_GPR[m_Opcode.rt].UDW); } +void R4300iOp::SD_32() +{ + uint64_t Address = m_GPR[m_Opcode.base].W[0] + (int16_t)m_Opcode.offset; + m_MMU.SD_Memory(Address, m_GPR[m_Opcode.rt].UDW); +} + // R4300i opcodes: Special void R4300iOp::SPECIAL_SLL() diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h index 95bb96ca5..4e976258e 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h @@ -69,34 +69,58 @@ private: void DADDI(); void DADDIU(); void LDL(); + void LDL_32(); void LDR(); + void LDR_32(); void LB(); + void LB_32(); void LH(); + void LH_32(); void LWL(); + void LWL_32(); void LW(); void LW_32(); void LBU(); + void LBU_32(); void LHU(); + void LHU_32(); void LWR(); + void LWR_32(); void LWU(); + void LWU_32(); void SB(); + void SB_32(); void SH(); + void SH_32(); void SWL(); + void SWL_32(); void SW(); void SW_32(); void SDL(); + void SDL_32(); void SDR(); + void SDR_32(); void SWR(); + void SWR_32(); void CACHE(); void LL(); + void LL_32(); void LWC1(); + void LWC1_32(); void LLD(); + void LLD_32(); void LDC1(); + void LDC1_32(); void LD(); + void LD_32(); void SC(); + void SC_32(); void SWC1(); + void SWC1_32(); void SDC1(); + void SDC1_32(); void SD(); + void SD_32(); // R4300i opcodes: Special void SPECIAL_SLL(); diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index a2671bc57..6e4885192 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -9476,7 +9476,7 @@ void CX86RecompilerOps::CompileSystemCheck(uint32_t TargetPC, const CRegInfo & R { m_Assembler.CompConstByteToVariable((void *)&m_SystemEvents.DoSomething(), "m_SystemEvents.DoSomething()", 0); asmjit::Label Jump = m_Assembler.newLabel(); - m_Assembler.JeLabel("Continue_From_Interrupt_Test", Jump); + m_Assembler.JeLabel8("Continue_From_Interrupt_Test", Jump); if (TargetPC != (uint32_t)-1) { m_Assembler.MoveConstToVariable(&g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER", TargetPC); diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp index adb46da11..049b78eea 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp @@ -253,6 +253,15 @@ void CX86Ops::JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel) jecxz(JumpLabel); } +void CX86Ops::JeLabel8(const char * LabelName, asmjit::Label & JumpLabel) +{ + if (CDebugSettings::bRecordRecompilerAsm()) + { + AddLabelSymbol(JumpLabel, LabelName); + } + short_().je(JumpLabel); +} + void CX86Ops::JeLabel(const char * LabelName, asmjit::Label & JumpLabel) { if (CDebugSettings::bRecordRecompilerAsm()) diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86ops.h b/Source/Project64-core/N64System/Recompiler/x86/x86ops.h index 8f48d4c38..de1498322 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86ops.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86ops.h @@ -56,6 +56,7 @@ public: void JbLabel(const char * LabelName, asmjit::Label & JumpLabel); void JbeLabel(const char * LabelName, asmjit::Label & JumpLabel); void JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel); + void JeLabel8(const char * LabelName, asmjit::Label & JumpLabel); void JeLabel(const char * LabelName, asmjit::Label & JumpLabel); void JgeLabel(const char * LabelName, asmjit::Label & JumpLabel); void JgLabel(const char * LabelName, asmjit::Label & JumpLabel);