From f113db705902bb598c84d39e2ad5badd6f57c490 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Sun, 19 Feb 2023 22:14:59 +0100 Subject: [PATCH] Use virtual class for different cpu types rather than that hot mess with pointers and shiz --- src/backend/Core.cpp | 39 +-- src/backend/Core.hpp | 33 +- src/backend/core/BaseCPU.hpp | 12 + src/backend/core/Dynarec.cpp | 19 +- src/backend/core/Dynarec.hpp | 19 +- src/backend/core/Interpreter.cpp | 21 +- src/backend/core/Interpreter.hpp | 59 ++-- src/backend/core/Mem.cpp | 8 +- src/backend/core/Mem.hpp | 10 +- src/backend/core/dynarec/MemoryManagement.cpp | 2 +- src/backend/core/dynarec/cop/cop0decode.cpp | 7 +- src/backend/core/dynarec/cop/cop0decode.hpp | 5 +- .../core/dynarec/cop/cop0instructions.cpp | 26 +- .../core/dynarec/cop/cop0instructions.hpp | 18 +- src/backend/core/dynarec/cop/cop1decode.cpp | 4 +- src/backend/core/dynarec/cop/cop1decode.hpp | 4 +- .../core/dynarec/cop/cop1instructions.cpp | 220 ++++++++----- .../core/dynarec/cop/cop1instructions.hpp | 124 +++---- src/backend/core/dynarec/decode.cpp | 6 +- src/backend/core/dynarec/instructions.cpp | 308 ++++++++++++------ src/backend/core/dynarec/instructions.hpp | 180 +++++----- src/backend/core/interpreter/decode.cpp | 48 +-- src/backend/core/interpreter/instructions.cpp | 46 +-- src/frontend/App.cpp | 2 +- src/frontend/imgui/Settings.cpp | 4 +- src/frontend/imgui/Window.cpp | 12 +- 26 files changed, 700 insertions(+), 536 deletions(-) create mode 100644 src/backend/core/BaseCPU.hpp diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 8219b60e..aad5ff57 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -9,63 +9,60 @@ Core::Core() { if(SDL_GameControllerAddMappingsFromFile("resources/gamecontrollerdb.txt") < 0) { Util::print("Failed to load game controller DB\n"); } - Stop(); } void Core::Stop() { - CpuReset(); - mem.Reset(); + cpu->Reset(); + cpu->mem.Reset(); pause = true; romLoaded = false; } CartInfo Core::LoadROM(const std::string& rom_) { rom = rom_; - CpuReset(); - mem.Reset(); + cpu->Reset(); + cpu->mem.Reset(); pause = false; romLoaded = true; - CartInfo cartInfo = mem.LoadROM(rom); + CartInfo cartInfo = cpu->mem.LoadROM(rom); isPAL = cartInfo.isPAL; - mem.mmio.si.pif.ExecutePIF(mem, CpuGetRegs(), cartInfo); + cpu->mem.mmio.si.pif.ExecutePIF(cpu->mem, cpu->regs, cartInfo); return cartInfo; } void Core::Run(Window& window, float volumeL, float volumeR) { - MMIO& mmio = mem.mmio; - Registers& regs = CpuGetRegs(); + MMIO& mmio = cpu->mem.mmio; - for(int field = 0; field < mmio.vi.numFields; field++) { + for (int field = 0; field < mmio.vi.numFields; field++) { int frameCycles = 0; - if(!pause && romLoaded) { + if (!pause && romLoaded) { for (int i = 0; i < mmio.vi.numHalflines; i++) { mmio.vi.current = (i << 1) + field; if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) { - InterruptRaise(mmio.mi, regs, Interrupt::VI); + InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI); } - int cpuCount = CpuStep(*this); + int cpuCount = cpu->Run(); frameCycles += cpuCount; - - mmio.rsp.Run(cpuCount, regs, mem); - mmio.ai.Step(mem, regs, cpuCount, volumeL, volumeR); - scheduler.tick(cpuCount, mem, regs); + mmio.rsp.Run(cpuCount, cpu->regs, cpu->mem); + mmio.ai.Step(cpu->mem, cpu->regs, cpuCount, volumeL, volumeR); + scheduler.tick(cpuCount, cpu->mem, cpu->regs); } if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) { - InterruptRaise(mmio.mi, regs, Interrupt::VI); + InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI); } UpdateScreenParallelRdp(*this, window, GetVI()); int missedCycles = N64_CYCLES_PER_FRAME(isPAL) - frameCycles; - mmio.ai.Step(mem, regs, missedCycles, volumeL, volumeR); - } else if(pause && romLoaded) { + mmio.ai.Step(cpu->mem, cpu->regs, missedCycles, volumeL, volumeR); + } else if (pause && romLoaded) { UpdateScreenParallelRdp(*this, window, GetVI()); - } else if(pause && !romLoaded) { + } else if (pause && !romLoaded) { UpdateScreenParallelRdpNoGame(*this, window); } } diff --git a/src/backend/Core.hpp b/src/backend/Core.hpp index 3723494b..fd159a66 100644 --- a/src/backend/Core.hpp +++ b/src/backend/Core.hpp @@ -22,34 +22,7 @@ struct Core { CartInfo LoadROM(const std::string&); void Run(Window&, float volumeL, float volumeR); void TogglePause() { pause = !pause; } - VI& GetVI() { return mem.mmio.vi; } - - void CpuReset() const { - switch(cpuType) { - case CpuType::Dynarec: cpuDynarec->Reset(); break; - case CpuType::Interpreter: cpuInterp->Reset(); break; - case CpuType::NONE: break; - } - } - - [[nodiscard]] Registers& CpuGetRegs() const { - switch(cpuType) { - case CpuType::Dynarec: return cpuDynarec->regs; - case CpuType::Interpreter: return cpuInterp->regs; - case CpuType::NONE: - Util::panic("BRUH\n"); - } - } - - static int CpuStep(Core& core) { - switch(core.cpuType) { - case CpuType::Dynarec: - return core.cpuDynarec->Step(core.mem); - case CpuType::Interpreter: - return core.cpuInterp->Run(core.mem); - case CpuType::NONE: return 0; - } - } + VI& GetVI() { return cpu->mem.mmio.vi; } u32 breakpoint = 0; @@ -58,10 +31,8 @@ struct Core { bool romLoaded = false; bool done = false; std::string rom; - Mem mem; CpuType cpuType = CpuType::NONE; - Interpreter* cpuInterp = nullptr; - JIT::Dynarec* cpuDynarec = nullptr; + std::unique_ptr cpu; Debugger debugger{*this}; }; } diff --git a/src/backend/core/BaseCPU.hpp b/src/backend/core/BaseCPU.hpp new file mode 100644 index 00000000..444dcb0c --- /dev/null +++ b/src/backend/core/BaseCPU.hpp @@ -0,0 +1,12 @@ +#pragma once +#include + +namespace n64 { +struct BaseCPU { + virtual ~BaseCPU() {} + virtual void Reset() {} + virtual int Run() {} + Registers regs; + Mem mem; +}; +} \ No newline at end of file diff --git a/src/backend/core/Dynarec.cpp b/src/backend/core/Dynarec.cpp index c6364fd3..036da448 100644 --- a/src/backend/core/Dynarec.cpp +++ b/src/backend/core/Dynarec.cpp @@ -1,8 +1,10 @@ -#include +#include #include #include +#include "Dynarec.hpp" -namespace n64::JIT { + +namespace n64 { namespace fs = std::filesystem; Dynarec::~Dynarec() { @@ -97,8 +99,8 @@ void Dynarec::AllocateOuter(u32 pc) { blockCache[pc >> 20] = (Fn*)bumpAlloc(0x1000 * sizeof(Fn)); } -int Dynarec::Step(Mem &mem) { - instrInBlock = 0; +int Dynarec::Run() { + /*instrInBlock = 0; regs.gpr[0] = 0; regs.prevDelaySlot = regs.delaySlot; regs.delaySlot = false; @@ -128,6 +130,13 @@ int Dynarec::Step(Mem &mem) { FireException(regs, ExceptionCode::Interrupt, 0, false); } - return instrInBlock; + return instrInBlock;*/ + Util::panic("JIT RECOMPILER NOT YET IMPLEMENTED!\n"); +} + +void Dynarec::Reset() { + code.reset(); + regs.Reset(); + InvalidateCache(); } } \ No newline at end of file diff --git a/src/backend/core/Dynarec.hpp b/src/backend/core/Dynarec.hpp index ccda7300..fb9b5414 100644 --- a/src/backend/core/Dynarec.hpp +++ b/src/backend/core/Dynarec.hpp @@ -2,11 +2,9 @@ #include #include #include -#include +#include -namespace n64 { struct Cop1; } - -namespace n64::JIT { +namespace n64 { using namespace Xbyak; using namespace Xbyak::util; using Fn = void (*)(); @@ -16,18 +14,13 @@ using Fn = void (*)(); #define CODECACHE_SIZE (2 << 25) #define CODECACHE_OVERHEAD (CODECACHE_SIZE - 1_kb) -struct Dynarec { +struct Dynarec : BaseCPU { Dynarec(); - ~Dynarec(); - int Step(Mem&); - void Reset() { - code.reset(); - regs.Reset(); - InvalidateCache(); - } + ~Dynarec() override; + int Run() override; + void Reset() override; u64 cop2Latch{}; CodeGenerator code; - n64::Registers regs; void InvalidatePage(u32); void InvalidateCache(); private: diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 5b8dbfbe..f08ddc6c 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -1,4 +1,4 @@ -#include +#include #include namespace n64 { @@ -21,10 +21,13 @@ inline void CheckCompareInterrupt(MI& mi, Registers& regs) { } } -int Interpreter::Run(Mem& mem) { - MMIO& mmio = mem.mmio; - int count = 0; - for(;count <= mmio.vi.cyclesPerHalfline; count++) { +void Interpreter::Reset() { + regs.Reset(); +} + +int Interpreter::Run() { + int cycles = 0; + for(; cycles <= mem.mmio.vi.cyclesPerHalfline; cycles++) { CheckCompareInterrupt(mem.mmio.mi, regs); regs.prevDelaySlot = regs.delaySlot; @@ -34,23 +37,23 @@ int Interpreter::Run(Mem& mem) { if(!MapVAddr(regs, LOAD, regs.pc, paddr)) { HandleTLBException(regs, regs.pc); FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, false); - return count; + return cycles; } u32 instruction = mem.Read32(regs, paddr); if(ShouldServiceInterrupt(regs)) { FireException(regs, ExceptionCode::Interrupt, 0, false); - return count; + return cycles; } regs.oldPC = regs.pc; regs.pc = regs.nextPC; regs.nextPC += 4; - Exec(mem, instruction); + Exec(instruction); } - return count; + return cycles; } } \ No newline at end of file diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 224ff7cc..24aeb114 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -2,16 +2,15 @@ #include #include #include +#include namespace n64 { -struct Interpreter { +struct Core; +struct Interpreter : BaseCPU { Interpreter() = default; ~Interpreter() = default; - int Run(Mem&); - void Reset() { - regs.Reset(); - } - Registers regs; + int Run() override; + void Reset() override; private: u64 cop2Latch{}; friend struct Cop1; @@ -19,7 +18,7 @@ private: void cop2Decode(u32); void special(u32); void regimm(u32); - void Exec(Mem&, u32); + void Exec(u32); void add(u32); void addu(u32); void addi(u32); @@ -58,19 +57,19 @@ private: void jal(u32); void jalr(u32); void lui(u32); - void lbu(Mem&, u32); - void lb(Mem&, u32); - void ld(Mem&, u32); - void ldl(Mem&, u32); - void ldr(Mem&, u32); - void lh(Mem&, u32); - void lhu(Mem&, u32); - void ll(Mem&, u32); - void lld(Mem&, u32); - void lw(Mem&, u32); - void lwl(Mem&, u32); - void lwu(Mem&, u32); - void lwr(Mem&, u32); + void lbu(u32); + void lb(u32); + void ld(u32); + void ldl(u32); + void ldr(u32); + void lh(u32); + void lhu(u32); + void ll(u32); + void lld(u32); + void lw(u32); + void lwl(u32); + void lwu(u32); + void lwr(u32); void mfhi(u32); void mflo(u32); void mult(u32); @@ -78,16 +77,16 @@ private: void mthi(u32); void mtlo(u32); void nor(u32); - void sb(Mem&, u32); - void sc(Mem&, u32); - void scd(Mem&, u32); - void sd(Mem&, u32); - void sdl(Mem&, u32); - void sdr(Mem&, u32); - void sh(Mem&, u32); - void sw(Mem&, u32); - void swl(Mem&, u32); - void swr(Mem&, u32); + void sb(u32); + void sc(u32); + void scd(u32); + void sd(u32); + void sdl(u32); + void sdr(u32); + void sh(u32); + void sw(u32); + void swl(u32); + void swr(u32); void slti(u32); void sltiu(u32); void slt(u32); diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index b5fac52e..c4817207 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -223,22 +223,22 @@ u64 Mem::Read64(n64::Registers ®s, u32 paddr) { } } -void Mem::Write8(Registers& regs, n64::JIT::Dynarec& dyn, u32 paddr, u32 val) { +void Mem::Write8(Registers& regs, n64::Dynarec& dyn, u32 paddr, u32 val) { dyn.InvalidatePage(BYTE_ADDRESS(paddr)); return Write8(regs, paddr, val); } -void Mem::Write16(Registers& regs, n64::JIT::Dynarec& dyn, u32 paddr, u32 val) { +void Mem::Write16(Registers& regs, n64::Dynarec& dyn, u32 paddr, u32 val) { dyn.InvalidatePage(HALF_ADDRESS(paddr)); return Write16(regs, paddr, val); } -void Mem::Write32(Registers& regs, n64::JIT::Dynarec& dyn, u32 paddr, u32 val) { +void Mem::Write32(Registers& regs, n64::Dynarec& dyn, u32 paddr, u32 val) { dyn.InvalidatePage(paddr); return Write32(regs, paddr, val); } -void Mem::Write64(Registers& regs, n64::JIT::Dynarec& dyn, u32 paddr, u64 val) { +void Mem::Write64(Registers& regs, n64::Dynarec& dyn, u32 paddr, u64 val) { dyn.InvalidatePage(paddr); return Write64(regs, paddr, val); } diff --git a/src/backend/core/Mem.hpp b/src/backend/core/Mem.hpp index 0317c476..4d092111 100644 --- a/src/backend/core/Mem.hpp +++ b/src/backend/core/Mem.hpp @@ -15,9 +15,7 @@ struct CartInfo { u32 crc; }; -namespace JIT { struct Dynarec; -} struct Mem { ~Mem() { @@ -34,10 +32,10 @@ struct Mem { u16 Read16(Registers&, u32); u32 Read32(Registers&, u32); u64 Read64(Registers&, u32); - void Write8(Registers&, JIT::Dynarec&, u32, u32); - void Write16(Registers&, JIT::Dynarec&, u32, u32); - void Write32(Registers&, JIT::Dynarec&, u32, u32); - void Write64(Registers&, JIT::Dynarec&, u32, u64); + void Write8(Registers&, Dynarec&, u32, u32); + void Write16(Registers&, Dynarec&, u32, u32); + void Write32(Registers&, Dynarec&, u32, u32); + void Write64(Registers&, Dynarec&, u32, u64); void Write8(Registers&, u32, u32); void Write16(Registers&, u32, u32); void Write32(Registers&, u32, u32); diff --git a/src/backend/core/dynarec/MemoryManagement.cpp b/src/backend/core/dynarec/MemoryManagement.cpp index a4431d2c..7201ba39 100644 --- a/src/backend/core/dynarec/MemoryManagement.cpp +++ b/src/backend/core/dynarec/MemoryManagement.cpp @@ -1,6 +1,6 @@ #include -namespace n64::JIT { +namespace n64 { void Dynarec::InvalidatePage(u32 paddr) { blockCache[paddr >> 20] = nullptr; } diff --git a/src/backend/core/dynarec/cop/cop0decode.cpp b/src/backend/core/dynarec/cop/cop0decode.cpp index 8fc359ac..bf7e6caa 100644 --- a/src/backend/core/dynarec/cop/cop0decode.cpp +++ b/src/backend/core/dynarec/cop/cop0decode.cpp @@ -2,8 +2,8 @@ #include #include -namespace n64::JIT { -void cop0Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { +namespace n64 { +void cop0Decode(Registers& regs, Dynarec& cpu, u32 instr) { u8 mask_cop = (instr >> 21) & 0x1F; u8 mask_cop2 = instr & 0x3F; Xbyak::CodeGenerator& code = cpu.code; @@ -36,14 +36,13 @@ void cop0Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x02: - code.and_(code.dword[code.rdi + offsetof(n64::Registers, cop0.index)], 0x3F); + code.and_(code.dword[code.rdi + offsetof(Registers, cop0.index)], 0x3F); code.mov(code.rsi, code.dword[code.rdi]); code.mov(code.rax, (u64)tlbw); code.call(code.rax); break; case 0x06: code.mov(code.rax, (u64)regs.cop0.GetRandom()); - code.call(code.rax); code.mov(code.rsi, code.rax); code.mov(code.rax, (u64)tlbw); code.call(code.rax); diff --git a/src/backend/core/dynarec/cop/cop0decode.hpp b/src/backend/core/dynarec/cop/cop0decode.hpp index 3cb4be8e..2e6c44d7 100644 --- a/src/backend/core/dynarec/cop/cop0decode.hpp +++ b/src/backend/core/dynarec/cop/cop0decode.hpp @@ -3,8 +3,5 @@ namespace n64 { struct Registers; -} - -namespace n64::JIT { -void cop0Decode(n64::Registers& regs, u32 instr, Dynarec& cpu); +void cop0Decode(Registers&, Dynarec& cpu, u32 instr); } \ No newline at end of file diff --git a/src/backend/core/dynarec/cop/cop0instructions.cpp b/src/backend/core/dynarec/cop/cop0instructions.cpp index 1e2e0bc5..ede0a86f 100644 --- a/src/backend/core/dynarec/cop/cop0instructions.cpp +++ b/src/backend/core/dynarec/cop/cop0instructions.cpp @@ -2,24 +2,29 @@ #include #include -namespace n64::JIT { -void mtc0(n64::Registers& regs, u32 instr) { +namespace n64 { +void mtc0(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop0.SetReg32(RD(instr), regs.gpr[RT(instr)]); } -void dmtc0(n64::Registers& regs, u32 instr) { +void dmtc0(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop0.SetReg64(RD(instr), regs.gpr[RT(instr)]); } -void mfc0(n64::Registers& regs, u32 instr) { +void mfc0(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.gpr[RT(instr)] = s32(regs.cop0.GetReg32(RD(instr))); } -void dmfc0(n64::Registers& regs, u32 instr) { +void dmfc0(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.gpr[RT(instr)] = s64(regs.cop0.GetReg64(RD(instr))); } -void eret(n64::Registers& regs) { +void eret(Dynarec& cpu) { + Registers& regs = cpu.regs; if(regs.cop0.status.erl) { regs.SetPC64(regs.cop0.ErrorEPC); regs.cop0.status.erl = false; @@ -31,7 +36,8 @@ void eret(n64::Registers& regs) { } -void tlbr(n64::Registers& regs) { +void tlbr(Dynarec& cpu) { + Registers& regs = cpu.regs; u8 Index = regs.cop0.index & 0b111111; if (Index >= 32) { Util::panic("TLBR with TLB index {}", Index); @@ -48,7 +54,8 @@ void tlbr(n64::Registers& regs) { regs.cop0.pageMask.raw = entry.pageMask.raw; } -void tlbw(n64::Registers& regs, int index_) { +void tlbw(Dynarec& cpu, int index_) { + Registers& regs = cpu.regs; PageMask page_mask = regs.cop0.pageMask; u32 top = page_mask.mask & 0xAAA; page_mask.mask = top | (top >> 1); @@ -68,7 +75,8 @@ void tlbw(n64::Registers& regs, int index_) { regs.cop0.tlb[index_].initialized = true; } -void tlbp(n64::Registers& regs) { +void tlbp(Dynarec& cpu) { + Registers& regs = cpu.regs; int match = -1; TLBEntry* entry = TLBTryMatch(regs, regs.cop0.entryHi.raw, &match); if(entry && match >= 0) { diff --git a/src/backend/core/dynarec/cop/cop0instructions.hpp b/src/backend/core/dynarec/cop/cop0instructions.hpp index a43661a3..1789905d 100644 --- a/src/backend/core/dynarec/cop/cop0instructions.hpp +++ b/src/backend/core/dynarec/cop/cop0instructions.hpp @@ -1,13 +1,13 @@ #pragma once #include -namespace n64::JIT { -void mtc0(n64::Registers&, u32); -void dmtc0(n64::Registers&, u32); -void mfc0(n64::Registers&, u32); -void dmfc0(n64::Registers&, u32); -void eret(n64::Registers&); -void tlbr(n64::Registers&); -void tlbw(n64::Registers&, int); -void tlbp(n64::Registers&); +namespace n64 { +void mtc0(Dynarec&, u32); +void dmtc0(Dynarec&, u32); +void mfc0(Dynarec&, u32); +void dmfc0(Dynarec&, u32); +void eret(Dynarec&); +void tlbr(Dynarec&); +void tlbw(Dynarec&, int); +void tlbp(Dynarec&); } \ No newline at end of file diff --git a/src/backend/core/dynarec/cop/cop1decode.cpp b/src/backend/core/dynarec/cop/cop1decode.cpp index 10db3816..1b56964d 100644 --- a/src/backend/core/dynarec/cop/cop1decode.cpp +++ b/src/backend/core/dynarec/cop/cop1decode.cpp @@ -2,8 +2,8 @@ #include #include -namespace n64::JIT { -bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { +namespace n64 { +bool cop1Decode(Registers& regs, Dynarec& cpu, u32 instr) { Xbyak::CodeGenerator& code = cpu.code; u8 mask_sub = (instr >> 21) & 0x1F; diff --git a/src/backend/core/dynarec/cop/cop1decode.hpp b/src/backend/core/dynarec/cop/cop1decode.hpp index b13255e5..c9df0efd 100644 --- a/src/backend/core/dynarec/cop/cop1decode.hpp +++ b/src/backend/core/dynarec/cop/cop1decode.hpp @@ -1,6 +1,6 @@ #pragma once #include -namespace n64::JIT { -bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu); +namespace n64 { +bool cop1Decode(Registers&, Dynarec& cpu, u32 instr); } \ No newline at end of file diff --git a/src/backend/core/dynarec/cop/cop1instructions.cpp b/src/backend/core/dynarec/cop/cop1instructions.cpp index 5c27af92..674e9b44 100644 --- a/src/backend/core/dynarec/cop/cop1instructions.cpp +++ b/src/backend/core/dynarec/cop/cop1instructions.cpp @@ -4,7 +4,7 @@ #include #include -namespace n64::JIT { +namespace n64 { inline int PushRoundingMode(const FCR31& fcr31) { int og = fegetround(); switch(fcr31.rounding_mode) { @@ -29,67 +29,78 @@ inline int PushRoundingMode(const FCR31& fcr31) { } \ } while(0) -void absd(n64::Registers& regs, u32 instr) { - double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); +void absd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), std::abs(fs)); } -void abss(n64::Registers& regs, u32 instr) { - float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); +void abss(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), std::abs(fs)); } -void absw(n64::Registers& regs, u32 instr) { +void absw(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; s32 fs = regs.cop1.GetReg(regs.cop0, FS(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), std::abs(fs)); } -void absl(n64::Registers& regs, u32 instr) { +void absl(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; s64 fs = regs.cop1.GetReg(regs.cop0, FS(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), std::abs(fs)); } -void adds(n64::Registers& regs, u32 instr) { - float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); - float ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); +void adds(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); + auto ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); checknanregs(fs, ft); float result = fs + ft; regs.cop1.SetCop1Reg(regs.cop0, FD(instr), result); } -void addd(n64::Registers& regs, u32 instr) { - double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); - double ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); +void addd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); + auto ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); checknanregs(fs, ft); double result = fs + ft; regs.cop1.SetCop1Reg(regs.cop0, FD(instr), result); } -void ceills(n64::Registers& regs, u32 instr) { - float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); +void ceills(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s64 result = std::ceil(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void ceilws(n64::Registers& regs, u32 instr) { - float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); +void ceilws(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s32 result = std::ceil(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void ceilld(n64::Registers& regs, u32 instr) { - double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); +void ceilld(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s64 result = std::ceil(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void ceilwd(n64::Registers& regs, u32 instr) { - double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); +void ceilwd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; + auto fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s32 result = std::ceil(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void cfc1(n64::Registers& regs, u32 instr) { +void cfc1(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; u8 fd = RD(instr); s32 val = 0; switch(fd) { @@ -100,7 +111,8 @@ void cfc1(n64::Registers& regs, u32 instr) { regs.gpr[RT(instr)] = val; } -void ctc1(n64::Registers& regs, u32 instr) { +void ctc1(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; u8 fs = FS(instr); u32 val = regs.gpr[RT(instr)]; switch(fs) { @@ -113,7 +125,8 @@ void ctc1(n64::Registers& regs, u32 instr) { } } -void cvtds(n64::Registers& regs, u32 instr) { +void cvtds(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -124,7 +137,8 @@ void cvtds(n64::Registers& regs, u32 instr) { ); } -void cvtsd(n64::Registers& regs, u32 instr) { +void cvtsd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -135,7 +149,8 @@ void cvtsd(n64::Registers& regs, u32 instr) { ); } -void cvtwd(n64::Registers& regs, u32 instr) { +void cvtwd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg( regs.cop0, FD(instr), @@ -146,7 +161,8 @@ void cvtwd(n64::Registers& regs, u32 instr) { ); } -void cvtws(n64::Registers& regs, u32 instr) { +void cvtws(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg( regs.cop0, FD(instr), @@ -157,7 +173,8 @@ void cvtws(n64::Registers& regs, u32 instr) { ); } -void cvtls(n64::Registers& regs, u32 instr) { +void cvtls(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg( regs.cop0, FD(instr), @@ -168,7 +185,8 @@ void cvtls(n64::Registers& regs, u32 instr) { ); } -void cvtsl(n64::Registers& regs, u32 instr) { +void cvtsl(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -179,7 +197,8 @@ void cvtsl(n64::Registers& regs, u32 instr) { ); } -void cvtdw(n64::Registers& regs, u32 instr) { +void cvtdw(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -190,7 +209,8 @@ void cvtdw(n64::Registers& regs, u32 instr) { ); } -void cvtsw(n64::Registers& regs, u32 instr) { +void cvtsw(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -201,7 +221,8 @@ void cvtsw(n64::Registers& regs, u32 instr) { ); } -void cvtdl(n64::Registers& regs, u32 instr) { +void cvtdl(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -212,7 +233,8 @@ void cvtdl(n64::Registers& regs, u32 instr) { ); } -void cvtld(n64::Registers& regs, u32 instr) { +void cvtld(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg( regs.cop0, FD(instr), @@ -224,7 +246,8 @@ void cvtld(n64::Registers& regs, u32 instr) { } template -inline bool CalculateCondition(n64::Registers& regs, T fs, T ft, CompConds cond) { +inline bool CalculateCondition(Dynarec& cpu, T fs, T ft, CompConds cond) { + Registers& regs = cpu.regs; switch(cond) { case F: return false; case UN: return std::isnan(fs) || std::isnan(ft); @@ -242,82 +265,94 @@ inline bool CalculateCondition(n64::Registers& regs, T fs, T ft, CompConds cond) return false; } - return CalculateCondition(regs, fs, ft, static_cast(cond - 8)); + return CalculateCondition(cpu, fs, ft, static_cast(cond - 8)); } } template -void ccond(n64::Registers& regs, u32 instr, CompConds cond) { +void ccond(Dynarec& cpu, u32 instr, CompConds cond) { + Registers& regs = cpu.regs; T fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); T ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); - regs.cop1.fcr31.compare = CalculateCondition(regs, fs, ft, cond); + regs.cop1.fcr31.compare = CalculateCondition(cpu, fs, ft, cond); } -template void ccond(n64::Registers& regs, u32 instr, CompConds cond); -template void ccond(n64::Registers& regs, u32 instr, CompConds cond); +template void ccond(Dynarec& cpu, u32 instr, CompConds cond); +template void ccond(Dynarec& cpu, u32 instr, CompConds cond); -void divs(Registers ®s, u32 instr) { +void divs(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); float ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), fs / ft); } -void divd(Registers ®s, u32 instr) { +void divd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); double ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), fs / ft); } -void muls(Registers ®s, u32 instr) { +void muls(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); float ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), fs * ft); } -void muld(n64::Registers& regs, u32 instr) { +void muld(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); double ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), fs * ft); } -void mulw(Registers ®s, u32 instr) { +void mulw(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; u32 fs = regs.cop1.GetReg(regs.cop0, FS(instr)); u32 ft = regs.cop1.GetReg(regs.cop0, FT(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), fs * ft); } -void mull(Registers ®s, u32 instr) { +void mull(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; u64 fs = regs.cop1.GetReg(regs.cop0, FS(instr)); u64 ft = regs.cop1.GetReg(regs.cop0, FT(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), fs * ft); } -void subs(Registers ®s, u32 instr) { +void subs(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); float ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), fs - ft); } -void subd(Registers ®s, u32 instr) { +void subd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); double ft = regs.cop1.GetCop1Reg(regs.cop0, FT(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), fs - ft); } -void subw(Registers ®s, u32 instr) { +void subw(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; u32 fs = regs.cop1.GetReg(regs.cop0, FS(instr)); u32 ft = regs.cop1.GetReg(regs.cop0, FT(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), fs - ft); } -void subl(Registers ®s, u32 instr) { +void subl(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; u64 fs = regs.cop1.GetReg(regs.cop0, FS(instr)); u64 ft = regs.cop1.GetReg(regs.cop0, FT(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), fs - ft); } -void movs(n64::Registers& regs, u32 instr) { +void movs(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -328,7 +363,8 @@ void movs(n64::Registers& regs, u32 instr) { ); } -void movd(n64::Registers& regs, u32 instr) { +void movd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -339,7 +375,8 @@ void movd(n64::Registers& regs, u32 instr) { ); } -void movw(n64::Registers& regs, u32 instr) { +void movw(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg( regs.cop0, FD(instr), @@ -350,7 +387,8 @@ void movw(n64::Registers& regs, u32 instr) { ); } -void movl(n64::Registers& regs, u32 instr) { +void movl(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg( regs.cop0, FD(instr), @@ -361,7 +399,8 @@ void movl(n64::Registers& regs, u32 instr) { ); } -void negs(Registers ®s, u32 instr) { +void negs(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -372,7 +411,8 @@ void negs(Registers ®s, u32 instr) { ); } -void negd(Registers ®s, u32 instr) { +void negd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetCop1Reg( regs.cop0, FD(instr), @@ -383,65 +423,77 @@ void negd(Registers ®s, u32 instr) { ); } -void sqrts(Registers ®s, u32 instr) { +void sqrts(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), std::sqrt(fs)); } -void sqrtd(Registers ®s, u32 instr) { +void sqrtd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetCop1Reg(regs.cop0, FD(instr), std::sqrt(fs)); } -void roundls(n64::Registers& regs, u32 instr) { +void roundls(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); PUSHROUNDINGMODE; regs.cop1.SetReg(regs.cop0, FD(instr), (s32)std::nearbyint(fs)); POPROUNDINGMODE; } -void roundld(n64::Registers& regs, u32 instr) { +void roundld(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); PUSHROUNDINGMODE; regs.cop1.SetReg(regs.cop0, FD(instr), (s64)std::nearbyint(fs)); POPROUNDINGMODE; } -void roundws(n64::Registers& regs, u32 instr) { +void roundws(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); PUSHROUNDINGMODE; regs.cop1.SetReg(regs.cop0, FD(instr), (s32)std::nearbyint(fs)); POPROUNDINGMODE; } -void roundwd(n64::Registers& regs, u32 instr) { +void roundwd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); PUSHROUNDINGMODE; regs.cop1.SetReg(regs.cop0, FD(instr), (s32)std::nearbyint(fs)); POPROUNDINGMODE; } -void floorls(n64::Registers& regs, u32 instr) { +void floorls(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), (s64)std::floor(fs)); } -void floorld(n64::Registers& regs, u32 instr) { +void floorld(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), (s64)std::floor(fs)); } -void floorws(n64::Registers& regs, u32 instr) { +void floorws(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), (s64)std::floor(fs)); } -void floorwd(n64::Registers& regs, u32 instr) { +void floorwd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); regs.cop1.SetReg(regs.cop0, FD(instr), (s64)std::floor(fs)); } -void lwc1(n64::Registers& regs, Mem& mem, u32 instr) { +void lwc1(Dynarec& cpu, u32 instr) { + Mem& mem = cpu.mem; + Registers& regs = cpu.regs; if(!regs.cop0.status.cu1) { FireException(regs, ExceptionCode::CoprocessorUnusable, 1, true); return; @@ -459,7 +511,9 @@ void lwc1(n64::Registers& regs, Mem& mem, u32 instr) { } } -void swc1(n64::Registers& regs, Mem& mem, u32 instr) { +void swc1(Dynarec& cpu, u32 instr) { + Mem& mem = cpu.mem; + Registers& regs = cpu.regs; if(!regs.cop0.status.cu1) { FireException(regs, ExceptionCode::CoprocessorUnusable, 1, true); return; @@ -476,7 +530,9 @@ void swc1(n64::Registers& regs, Mem& mem, u32 instr) { } } -void ldc1(n64::Registers& regs, Mem& mem, u32 instr) { +void ldc1(Dynarec& cpu, u32 instr) { + Mem& mem = cpu.mem; + Registers& regs = cpu.regs; if(!regs.cop0.status.cu1) { FireException(regs, ExceptionCode::CoprocessorUnusable, 1, true); return; @@ -494,7 +550,9 @@ void ldc1(n64::Registers& regs, Mem& mem, u32 instr) { } } -void sdc1(n64::Registers& regs, Mem& mem, u32 instr) { +void sdc1(Dynarec& cpu, u32 instr) { + Mem& mem = cpu.mem; + Registers& regs = cpu.regs; if(!regs.cop0.status.cu1) { FireException(regs, ExceptionCode::CoprocessorUnusable, 1, true); return; @@ -511,43 +569,51 @@ void sdc1(n64::Registers& regs, Mem& mem, u32 instr) { } } -void truncws(n64::Registers& regs, u32 instr) { +void truncws(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s32 result = (s32)std::trunc(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void truncwd(n64::Registers& regs, u32 instr) { +void truncwd(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s32 result = (s32)std::trunc(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void truncls(n64::Registers& regs, u32 instr) { +void truncls(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; float fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s64 result = (s64)std::trunc(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void truncld(n64::Registers& regs, u32 instr) { +void truncld(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; double fs = regs.cop1.GetCop1Reg(regs.cop0, FS(instr)); s64 result = (s64)std::trunc(fs); regs.cop1.SetReg(regs.cop0, FD(instr), result); } -void mfc1(n64::Registers& regs, u32 instr) { +void mfc1(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.gpr[RT(instr)] = (s32)regs.cop1.GetReg(regs.cop0, FS(instr)); } -void dmfc1(n64::Registers& regs, u32 instr) { +void dmfc1(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.gpr[RT(instr)] = (s64)regs.cop1.GetReg(regs.cop0, FS(instr)); } -void mtc1(n64::Registers& regs, u32 instr) { +void mtc1(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg(regs.cop0, FS(instr), regs.gpr[RT(instr)]); } -void dmtc1(n64::Registers& regs, u32 instr) { +void dmtc1(Dynarec& cpu, u32 instr) { + Registers& regs = cpu.regs; regs.cop1.SetReg(regs.cop0, FS(instr), regs.gpr[RT(instr)]); } } \ No newline at end of file diff --git a/src/backend/core/dynarec/cop/cop1instructions.hpp b/src/backend/core/dynarec/cop/cop1instructions.hpp index 40d2c95f..d281bebe 100644 --- a/src/backend/core/dynarec/cop/cop1instructions.hpp +++ b/src/backend/core/dynarec/cop/cop1instructions.hpp @@ -2,67 +2,67 @@ #include #include -namespace n64::JIT { -void absd(n64::Registers&, u32 instr); -void abss(n64::Registers&, u32 instr); -void absw(n64::Registers&, u32 instr); -void absl(n64::Registers&, u32 instr); -void adds(n64::Registers&, u32 instr); -void addd(n64::Registers&, u32 instr); -void subs(n64::Registers&, u32 instr); -void subd(n64::Registers&, u32 instr); -void subw(n64::Registers&, u32 instr); -void subl(n64::Registers&, u32 instr); -void ceills(n64::Registers&, u32 instr); -void ceilws(n64::Registers&, u32 instr); -void ceilld(n64::Registers&, u32 instr); -void ceilwd(n64::Registers&, u32 instr); -void cfc1(n64::Registers&, u32 instr); -void ctc1(n64::Registers&, u32 instr); -void roundls(n64::Registers&, u32 instr); -void roundld(n64::Registers&, u32 instr); -void roundws(n64::Registers&, u32 instr); -void roundwd(n64::Registers&, u32 instr); -void floorls(n64::Registers&, u32 instr); -void floorld(n64::Registers&, u32 instr); -void floorws(n64::Registers&, u32 instr); -void floorwd(n64::Registers&, u32 instr); -void cvtls(n64::Registers&, u32 instr); -void cvtws(n64::Registers&, u32 instr); -void cvtds(n64::Registers&, u32 instr); -void cvtsw(n64::Registers&, u32 instr); -void cvtdw(n64::Registers&, u32 instr); -void cvtsd(n64::Registers&, u32 instr); -void cvtwd(n64::Registers&, u32 instr); -void cvtld(n64::Registers&, u32 instr); -void cvtdl(n64::Registers&, u32 instr); -void cvtsl(n64::Registers&, u32 instr); +namespace n64 { +void absd(Dynarec&, u32 instr); +void abss(Dynarec&, u32 instr); +void absw(Dynarec&, u32 instr); +void absl(Dynarec&, u32 instr); +void adds(Dynarec&, u32 instr); +void addd(Dynarec&, u32 instr); +void subs(Dynarec&, u32 instr); +void subd(Dynarec&, u32 instr); +void subw(Dynarec&, u32 instr); +void subl(Dynarec&, u32 instr); +void ceills(Dynarec&, u32 instr); +void ceilws(Dynarec&, u32 instr); +void ceilld(Dynarec&, u32 instr); +void ceilwd(Dynarec&, u32 instr); +void cfc1(Dynarec&, u32 instr); +void ctc1(Dynarec&, u32 instr); +void roundls(Dynarec&, u32 instr); +void roundld(Dynarec&, u32 instr); +void roundws(Dynarec&, u32 instr); +void roundwd(Dynarec&, u32 instr); +void floorls(Dynarec&, u32 instr); +void floorld(Dynarec&, u32 instr); +void floorws(Dynarec&, u32 instr); +void floorwd(Dynarec&, u32 instr); +void cvtls(Dynarec&, u32 instr); +void cvtws(Dynarec&, u32 instr); +void cvtds(Dynarec&, u32 instr); +void cvtsw(Dynarec&, u32 instr); +void cvtdw(Dynarec&, u32 instr); +void cvtsd(Dynarec&, u32 instr); +void cvtwd(Dynarec&, u32 instr); +void cvtld(Dynarec&, u32 instr); +void cvtdl(Dynarec&, u32 instr); +void cvtsl(Dynarec&, u32 instr); template -void ccond(n64::Registers&, u32 instr, CompConds); -void divs(n64::Registers&, u32 instr); -void divd(n64::Registers&, u32 instr); -void muls(n64::Registers&, u32 instr); -void muld(n64::Registers&, u32 instr); -void mulw(n64::Registers&, u32 instr); -void mull(n64::Registers&, u32 instr); -void movs(n64::Registers&, u32 instr); -void movd(n64::Registers&, u32 instr); -void movw(n64::Registers&, u32 instr); -void movl(n64::Registers&, u32 instr); -void negs(n64::Registers&, u32 instr); -void negd(n64::Registers&, u32 instr); -void sqrts(n64::Registers&, u32 instr); -void sqrtd(n64::Registers&, u32 instr); -void lwc1(n64::Registers&, Mem&, u32 instr); -void swc1(n64::Registers&, Mem&, u32 instr); -void ldc1(n64::Registers&, Mem&, u32 instr); -void mfc1(n64::Registers&, u32 instr); -void dmfc1(n64::Registers&, u32 instr); -void mtc1(n64::Registers&, u32 instr); -void dmtc1(n64::Registers&, u32 instr); -void sdc1(n64::Registers&, Mem&, u32 instr); -void truncws(n64::Registers&, u32 instr); -void truncwd(n64::Registers&, u32 instr); -void truncls(n64::Registers&, u32 instr); -void truncld(n64::Registers&, u32 instr); +void ccond(Dynarec&, u32 instr, CompConds); +void divs(Dynarec&, u32 instr); +void divd(Dynarec&, u32 instr); +void muls(Dynarec&, u32 instr); +void muld(Dynarec&, u32 instr); +void mulw(Dynarec&, u32 instr); +void mull(Dynarec&, u32 instr); +void movs(Dynarec&, u32 instr); +void movd(Dynarec&, u32 instr); +void movw(Dynarec&, u32 instr); +void movl(Dynarec&, u32 instr); +void negs(Dynarec&, u32 instr); +void negd(Dynarec&, u32 instr); +void sqrts(Dynarec&, u32 instr); +void sqrtd(Dynarec&, u32 instr); +void lwc1(Dynarec&, u32 instr); +void swc1(Dynarec&, u32 instr); +void ldc1(Dynarec&, u32 instr); +void mfc1(Dynarec&, u32 instr); +void dmfc1(Dynarec&, u32 instr); +void mtc1(Dynarec&, u32 instr); +void dmtc1(Dynarec&, u32 instr); +void sdc1(Dynarec&, u32 instr); +void truncws(Dynarec&, u32 instr); +void truncwd(Dynarec&, u32 instr); +void truncls(Dynarec&, u32 instr); +void truncld(Dynarec&, u32 instr); } \ No newline at end of file diff --git a/src/backend/core/dynarec/decode.cpp b/src/backend/core/dynarec/decode.cpp index 4327aaea..619a799a 100644 --- a/src/backend/core/dynarec/decode.cpp +++ b/src/backend/core/dynarec/decode.cpp @@ -3,7 +3,7 @@ #include #include -namespace n64::JIT { +namespace n64 { void Dynarec::cop2Decode(u32 instr) { code.mov(rdi, (u64)this); code.mov(rsi, (u64)®s); @@ -560,8 +560,8 @@ bool Dynarec::Exec(Mem& mem, u32 instr) { code.mov(rax, (u64)lui); code.call(rax); break; - case 0x10: cop0Decode(regs, instr, *this); break; - case 0x11: res = cop1Decode(regs, instr, *this); break; + case 0x10: cop0Decode(regs, *this, instr); break; + case 0x11: res = cop1Decode(regs, *this, instr); break; case 0x12: cop2Decode(instr); break; case 0x14: code.mov(rsi, instr); diff --git a/src/backend/core/dynarec/instructions.cpp b/src/backend/core/dynarec/instructions.cpp index e0afa442..031a5cdf 100644 --- a/src/backend/core/dynarec/instructions.cpp +++ b/src/backend/core/dynarec/instructions.cpp @@ -5,8 +5,9 @@ #define check_signed_overflow(op1, op2, res) (((~((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1) #define check_signed_underflow(op1, op2, res) (((((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1) -namespace n64::JIT { -void add(Registers& regs, u32 instr) { +namespace n64 { +void add(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u32 rs = (s32)regs.gpr[RS(instr)]; u32 rt = (s32)regs.gpr[RT(instr)]; u32 result = rs + rt; @@ -19,7 +20,8 @@ void add(Registers& regs, u32 instr) { } } -void addu(Registers& regs, u32 instr) { +void addu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s32 rs = (s32)regs.gpr[RS(instr)]; s32 rt = (s32)regs.gpr[RT(instr)]; @@ -28,7 +30,8 @@ void addu(Registers& regs, u32 instr) { } } -void addi(Registers& regs, u32 instr) { +void addi(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u32 rs = regs.gpr[RS(instr)]; u32 imm = s32(s16(instr)); u32 result = rs + imm; @@ -39,14 +42,16 @@ void addi(Registers& regs, u32 instr) { } } -void addiu(Registers& regs, u32 instr) { +void addiu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s32 rs = (s32)regs.gpr[RS(instr)]; s16 imm = (s16)(instr); s32 result = rs + imm; regs.gpr[RT(instr)] = result; } -void dadd(Registers& regs, u32 instr) { +void dadd(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u64 rs = regs.gpr[RS(instr)]; u64 rt = regs.gpr[RT(instr)]; u64 result = rt + rs; @@ -59,7 +64,8 @@ void dadd(Registers& regs, u32 instr) { } } -void daddu(Registers& regs, u32 instr) { +void daddu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s64 rs = regs.gpr[RS(instr)]; s64 rt = regs.gpr[RT(instr)]; @@ -67,7 +73,8 @@ void daddu(Registers& regs, u32 instr) { } } -void daddi(Registers& regs, u32 instr) { +void daddi(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u64 imm = s64(s16(instr)); u64 rs = regs.gpr[RS(instr)]; u64 result = imm + rs; @@ -78,13 +85,15 @@ void daddi(Registers& regs, u32 instr) { } } -void daddiu(Registers& regs, u32 instr) { +void daddiu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s16 imm = (s16)(instr); s64 rs = regs.gpr[RS(instr)]; regs.gpr[RT(instr)] = rs + imm; } -void div(Registers& regs, u32 instr) { +void div(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 dividend = (s32)regs.gpr[RS(instr)]; s64 divisor = (s32)regs.gpr[RT(instr)]; @@ -103,7 +112,8 @@ void div(Registers& regs, u32 instr) { } } -void divu(Registers& regs, u32 instr) { +void divu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u32 dividend = regs.gpr[RS(instr)]; u32 divisor = regs.gpr[RT(instr)]; if(divisor == 0) { @@ -117,7 +127,8 @@ void divu(Registers& regs, u32 instr) { } } -void ddiv(Registers& regs, u32 instr) { +void ddiv(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 dividend = regs.gpr[RS(instr)]; s64 divisor = regs.gpr[RT(instr)]; if (dividend == 0x8000000000000000 && divisor == 0xFFFFFFFFFFFFFFFF) { @@ -138,7 +149,8 @@ void ddiv(Registers& regs, u32 instr) { } } -void ddivu(Registers& regs, u32 instr) { +void ddivu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u64 dividend = regs.gpr[RS(instr)]; u64 divisor = regs.gpr[RT(instr)]; if(divisor == 0) { @@ -152,14 +164,16 @@ void ddivu(Registers& regs, u32 instr) { } } -void branch(Registers& regs, bool cond, s64 address) { +void branch(Dynarec& dyn, bool cond, s64 address) { + Registers& regs = dyn.regs; regs.delaySlot = true; if (cond) { regs.nextPC = address; } } -void branch_likely(Registers& regs, bool cond, s64 address) { +void branch_likely(Dynarec& dyn, bool cond, s64 address) { + Registers& regs = dyn.regs; regs.delaySlot = true; if (cond) { regs.nextPC = address; @@ -168,39 +182,46 @@ void branch_likely(Registers& regs, bool cond, s64 address) { } } -void b(Registers& regs, u32 instr, bool cond) { +void b(Dynarec& dyn, u32 instr, bool cond) { + Registers& regs = dyn.regs; s64 offset = (s64)se_imm(instr) << 2; s64 address = regs.pc + offset; - branch(regs, cond, address); + branch(dyn, cond, address); } -void blink(Registers& regs, u32 instr, bool cond) { +void blink(Dynarec& dyn, u32 instr, bool cond) { + Registers& regs = dyn.regs; regs.gpr[31] = regs.nextPC; s64 offset = (s64)se_imm(instr) << 2; s64 address = regs.pc + offset; - branch(regs, cond, address); + branch(dyn, cond, address); } -void bl(Registers& regs, u32 instr, bool cond) { +void bl(Dynarec& dyn, u32 instr, bool cond) { + Registers& regs = dyn.regs; s64 offset = (s64)se_imm(instr) << 2; s64 address = regs.pc + offset; - branch_likely(regs, cond, address); + branch_likely(dyn, cond, address); } -void bllink(Registers& regs, u32 instr, bool cond) { +void bllink(Dynarec& dyn, u32 instr, bool cond) { + Registers& regs = dyn.regs; regs.gpr[31] = regs.nextPC; s64 offset = (s64)se_imm(instr) << 2; s64 address = regs.pc + offset; - branch_likely(regs, cond, address); + branch_likely(dyn, cond, address); } -void lui(Registers& regs, u32 instr) { +void lui(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 val = (s16)instr; val <<= 16; regs.gpr[RT(instr)] = val; } -void lb(Registers& regs, Mem& mem, u32 instr) { +void lb(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { @@ -211,7 +232,9 @@ void lb(Registers& regs, Mem& mem, u32 instr) { } } -void lh(Registers& regs, Mem& mem, u32 instr) { +void lh(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b1) > 0) { HandleTLBException(regs, address); @@ -228,7 +251,9 @@ void lh(Registers& regs, Mem& mem, u32 instr) { } } -void lw(Registers& regs, Mem& mem, u32 instr) { +void lw(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s16 offset = instr; u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(address, 0b11)) { @@ -246,7 +271,9 @@ void lw(Registers& regs, Mem& mem, u32 instr) { } } -void ll(Registers& regs, Mem& mem, u32 instr) { +void ll(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 physical; if (!MapVAddr(regs, LOAD, address, physical)) { @@ -265,7 +292,9 @@ void ll(Registers& regs, Mem& mem, u32 instr) { regs.cop0.LLAddr = physical >> 4; } -void lwl(Registers& regs, Mem& mem, u32 instr) { +void lwl(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { @@ -280,7 +309,9 @@ void lwl(Registers& regs, Mem& mem, u32 instr) { } } -void lwr(Registers& regs, Mem& mem, u32 instr) { +void lwr(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { @@ -295,7 +326,9 @@ void lwr(Registers& regs, Mem& mem, u32 instr) { } } -void ld(Registers& regs, Mem& mem, u32 instr) { +void ld(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(address, 0b111)) { HandleTLBException(regs, address); @@ -307,7 +340,9 @@ void ld(Registers& regs, Mem& mem, u32 instr) { regs.gpr[RT(instr)] = value; } -void lld(Registers& regs, Mem& mem, u32 instr) { +void lld(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; if (!regs.cop0.is_64bit_addressing && !regs.cop0.kernel_mode) { FireException(regs, ExceptionCode::ReservedInstruction, 0, true); return; @@ -329,7 +364,9 @@ void lld(Registers& regs, Mem& mem, u32 instr) { } } -void ldl(Registers& regs, Mem& mem, u32 instr) { +void ldl(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if (!MapVAddr(regs, LOAD, address, paddr)) { @@ -344,7 +381,9 @@ void ldl(Registers& regs, Mem& mem, u32 instr) { } } -void ldr(Registers& regs, Mem& mem, u32 instr) { +void ldr(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { @@ -359,13 +398,17 @@ void ldr(Registers& regs, Mem& mem, u32 instr) { } } -void lbu(Registers& regs, Mem& mem, u32 instr) { +void lbu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u8 value = mem.Read8(regs, address); regs.gpr[RT(instr)] = value; } -void lhu(Registers& regs, Mem& mem, u32 instr) { +void lhu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(address, 0b1)) { HandleTLBException(regs, address); @@ -377,7 +420,9 @@ void lhu(Registers& regs, Mem& mem, u32 instr) { regs.gpr[RT(instr)] = value; } -void lwu(Registers& regs, Mem& mem, u32 instr) { +void lwu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(address, 0b11)) { HandleTLBException(regs, address); @@ -389,12 +434,16 @@ void lwu(Registers& regs, Mem& mem, u32 instr) { regs.gpr[RT(instr)] = value; } -void sb(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void sb(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u32 address = regs.gpr[RS(instr)] + (s16)instr; mem.Write8(regs, dyn, address, regs.gpr[RT(instr)]); } -void sc(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void sc(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b11) > 0) { @@ -417,7 +466,9 @@ void sc(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } } -void scd(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void scd(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(address, 0b111)) { HandleTLBException(regs, address); @@ -433,7 +484,9 @@ void scd(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { regs.cop0.llbit = false; } -void sh(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void sh(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(address, 0b1)) { HandleTLBException(regs, address); @@ -450,7 +503,9 @@ void sh(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } } -void sw(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void sw(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s16 offset = instr; u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(address, 0b11)) { @@ -468,7 +523,9 @@ void sw(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } } -void sd(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void sd(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(address, 0b11)) { HandleTLBException(regs, address); @@ -486,7 +543,9 @@ void sd(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } -void sdl(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void sdl(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -501,7 +560,9 @@ void sdl(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } } -void sdr(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void sdr(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -516,7 +577,9 @@ void sdr(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } } -void swl(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void swl(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -531,7 +594,9 @@ void swl(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } } -void swr(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { +void swr(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + Mem& mem = dyn.mem; u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -546,86 +611,101 @@ void swr(Registers& regs, Mem& mem, Dynarec& dyn, u32 instr) { } } -void ori(Registers& regs, u32 instr) { +void ori(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 imm = (u16)instr; s64 result = imm | regs.gpr[RS(instr)]; regs.gpr[RT(instr)] = result; } -void or_(Registers& regs, u32 instr) { +void or_(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = regs.gpr[RS(instr)] | regs.gpr[RT(instr)]; } } -void nor(Registers& regs, u32 instr) { +void nor(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = ~(regs.gpr[RS(instr)] | regs.gpr[RT(instr)]); } } -void j(Registers& regs, u32 instr) { +void j(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u64 target = (instr & 0x3ffffff) << 2; u64 address = ((regs.pc - 4) & ~0xfffffff) | target; - branch(regs, true, address); + branch(dyn, true, address); } -void jal(Registers& regs, u32 instr) { +void jal(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; regs.gpr[31] = regs.nextPC; - j(regs, instr); + j(dyn, instr); } -void jalr(Registers& regs, u32 instr) { - branch(regs, true, regs.gpr[RS(instr)]); +void jalr(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; + branch(dyn, true, regs.gpr[RS(instr)]); if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = regs.pc + 4; } } -void slti(Registers& regs, u32 instr) { +void slti(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; regs.gpr[RT(instr)] = regs.gpr[RS(instr)] < se_imm(instr); } -void sltiu(Registers& regs, u32 instr) { +void sltiu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; regs.gpr[RT(instr)] = (u64)regs.gpr[RS(instr)] < se_imm(instr); } -void slt(Registers& regs, u32 instr) { +void slt(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = regs.gpr[RS(instr)] < regs.gpr[RT(instr)]; } } -void sltu(Registers& regs, u32 instr) { +void sltu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = (u64) regs.gpr[RS(instr)] < (u64) regs.gpr[RT(instr)]; } } -void xori(Registers& regs, u32 instr) { +void xori(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 imm = (u16)instr; regs.gpr[RT(instr)] = regs.gpr[RS(instr)] ^ imm; } -void xor_(Registers& regs, u32 instr) { +void xor_(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = regs.gpr[RT(instr)] ^ regs.gpr[RS(instr)]; } } -void andi(Registers& regs, u32 instr) { +void andi(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 imm = (u16)instr; regs.gpr[RT(instr)] = regs.gpr[RS(instr)] & imm; } -void and_(Registers& regs, u32 instr) { +void and_(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = regs.gpr[RS(instr)] & regs.gpr[RT(instr)]; } } -void sll(Registers& regs, u32 instr) { +void sll(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u8 sa = ((instr >> 6) & 0x1f); s32 result = regs.gpr[RT(instr)] << sa; @@ -633,7 +713,8 @@ void sll(Registers& regs, u32 instr) { } } -void sllv(Registers& regs, u32 instr) { +void sllv(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u8 sa = (regs.gpr[RS(instr)]) & 0x1F; u32 rt = regs.gpr[RT(instr)]; @@ -642,7 +723,8 @@ void sllv(Registers& regs, u32 instr) { } } -void dsll32(Registers& regs, u32 instr) { +void dsll32(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u8 sa = ((instr >> 6) & 0x1f); s64 result = regs.gpr[RT(instr)] << (sa + 32); @@ -650,7 +732,8 @@ void dsll32(Registers& regs, u32 instr) { } } -void dsll(Registers& regs, u32 instr) { +void dsll(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u8 sa = ((instr >> 6) & 0x1f); s64 result = regs.gpr[RT(instr)] << sa; @@ -658,7 +741,8 @@ void dsll(Registers& regs, u32 instr) { } } -void dsllv(Registers& regs, u32 instr) { +void dsllv(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s64 sa = regs.gpr[RS(instr)] & 63; s64 result = regs.gpr[RT(instr)] << sa; @@ -666,7 +750,8 @@ void dsllv(Registers& regs, u32 instr) { } } -void srl(Registers& regs, u32 instr) { +void srl(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u32 rt = regs.gpr[RT(instr)]; u8 sa = ((instr >> 6) & 0x1f); @@ -675,7 +760,8 @@ void srl(Registers& regs, u32 instr) { } } -void srlv(Registers& regs, u32 instr) { +void srlv(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u8 sa = (regs.gpr[RS(instr)] & 0x1F); u32 rt = regs.gpr[RT(instr)]; @@ -684,7 +770,8 @@ void srlv(Registers& regs, u32 instr) { } } -void dsrl(Registers& regs, u32 instr) { +void dsrl(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u64 rt = regs.gpr[RT(instr)]; u8 sa = ((instr >> 6) & 0x1f); @@ -693,7 +780,8 @@ void dsrl(Registers& regs, u32 instr) { } } -void dsrlv(Registers& regs, u32 instr) { +void dsrlv(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u8 amount = (regs.gpr[RS(instr)] & 63); u64 rt = regs.gpr[RT(instr)]; @@ -702,7 +790,8 @@ void dsrlv(Registers& regs, u32 instr) { } } -void dsrl32(Registers& regs, u32 instr) { +void dsrl32(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u64 rt = regs.gpr[RT(instr)]; u8 sa = ((instr >> 6) & 0x1f); @@ -711,7 +800,8 @@ void dsrl32(Registers& regs, u32 instr) { } } -void sra(Registers& regs, u32 instr) { +void sra(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s64 rt = regs.gpr[RT(instr)]; u8 sa = ((instr >> 6) & 0x1f); @@ -720,7 +810,8 @@ void sra(Registers& regs, u32 instr) { } } -void srav(Registers& regs, u32 instr) { +void srav(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s64 rt = regs.gpr[RT(instr)]; s64 rs = regs.gpr[RS(instr)]; @@ -730,7 +821,8 @@ void srav(Registers& regs, u32 instr) { } } -void dsra(Registers& regs, u32 instr) { +void dsra(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s64 rt = regs.gpr[RT(instr)]; u8 sa = ((instr >> 6) & 0x1f); @@ -739,7 +831,8 @@ void dsra(Registers& regs, u32 instr) { } } -void dsrav(Registers& regs, u32 instr) { +void dsrav(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s64 rt = regs.gpr[RT(instr)]; s64 rs = regs.gpr[RS(instr)]; @@ -749,7 +842,8 @@ void dsrav(Registers& regs, u32 instr) { } } -void dsra32(Registers& regs, u32 instr) { +void dsra32(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { s64 rt = regs.gpr[RT(instr)]; u8 sa = ((instr >> 6) & 0x1f); @@ -758,17 +852,19 @@ void dsra32(Registers& regs, u32 instr) { } } -void jr(Registers& regs, u32 instr) { +void jr(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 address = regs.gpr[RS(instr)]; if (check_address_error(address, 0b11)) { HandleTLBException(regs, address); FireException(regs, ExceptionCode::DataBusError, 0, true); } - branch(regs, true, address); + branch(dyn, true, address); } -void dsub(Registers& regs, u32 instr) { +void dsub(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 rt = regs.gpr[RT(instr)]; s64 rs = regs.gpr[RS(instr)]; s64 result = rs - rt; @@ -781,7 +877,8 @@ void dsub(Registers& regs, u32 instr) { } } -void dsubu(Registers& regs, u32 instr) { +void dsubu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u64 rt = regs.gpr[RT(instr)]; u64 rs = regs.gpr[RS(instr)]; @@ -790,7 +887,8 @@ void dsubu(Registers& regs, u32 instr) { } } -void sub(Registers& regs, u32 instr) { +void sub(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s32 rt = regs.gpr[RT(instr)]; s32 rs = regs.gpr[RS(instr)]; s32 result = rs - rt; @@ -803,7 +901,8 @@ void sub(Registers& regs, u32 instr) { } } -void subu(Registers& regs, u32 instr) { +void subu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { u32 rt = regs.gpr[RT(instr)]; u32 rs = regs.gpr[RS(instr)]; @@ -812,7 +911,8 @@ void subu(Registers& regs, u32 instr) { } } -void dmultu(Registers& regs, u32 instr) { +void dmultu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u64 rt = regs.gpr[RT(instr)]; u64 rs = regs.gpr[RS(instr)]; u128 result = (u128)rt * (u128)rs; @@ -820,7 +920,8 @@ void dmultu(Registers& regs, u32 instr) { regs.hi = (s64)(result >> 64); } -void dmult(Registers& regs, u32 instr) { +void dmult(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s64 rt = regs.gpr[RT(instr)]; s64 rs = regs.gpr[RS(instr)]; s128 result = (s128)rt * (s128)rs; @@ -828,7 +929,8 @@ void dmult(Registers& regs, u32 instr) { regs.hi = result >> 64; } -void multu(Registers& regs, u32 instr) { +void multu(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; u32 rt = regs.gpr[RT(instr)]; u32 rs = regs.gpr[RS(instr)]; u64 result = (u64)rt * (u64)rs; @@ -836,7 +938,8 @@ void multu(Registers& regs, u32 instr) { regs.hi = (s64)((s32)(result >> 32)); } -void mult(Registers& regs, u32 instr) { +void mult(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s32 rt = regs.gpr[RT(instr)]; s32 rs = regs.gpr[RS(instr)]; s64 result = (s64)rt * (s64)rs; @@ -844,46 +947,55 @@ void mult(Registers& regs, u32 instr) { regs.hi = (s64)((s32)(result >> 32)); } -void mflo(Registers& regs, u32 instr) { +void mflo(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = regs.lo; } } -void mfhi(Registers& regs, u32 instr) { +void mfhi(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; if(likely(RD(instr) != 0)) { regs.gpr[RD(instr)] = regs.hi; } } -void mtlo(Registers& regs, u32 instr) { +void mtlo(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; regs.lo = regs.gpr[RS(instr)]; } -void mthi(Registers& regs, u32 instr) { +void mthi(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; regs.hi = regs.gpr[RS(instr)]; } -void trap(Registers& regs, bool cond) { +void trap(Dynarec& dyn, bool cond) { + Registers& regs = dyn.regs; if(cond) { FireException(regs, ExceptionCode::Trap, 0, true); } } -void mtc2(Dynarec& dyn, Registers& regs, u32 instr) { +void mtc2(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; dyn.cop2Latch = regs.gpr[RT(instr)]; } -void mfc2(Dynarec& dyn, Registers& regs, u32 instr) { +void mfc2(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; s32 value = dyn.cop2Latch; regs.gpr[RT(instr)] = value; } -void dmtc2(Dynarec& dyn, Registers& regs, u32 instr) { +void dmtc2(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; dyn.cop2Latch = regs.gpr[RT(instr)]; } -void dmfc2(Dynarec& dyn, Registers& regs, u32 instr) { +void dmfc2(Dynarec& dyn, u32 instr) { + Registers& regs = dyn.regs; regs.gpr[RT(instr)] = dyn.cop2Latch; } diff --git a/src/backend/core/dynarec/instructions.hpp b/src/backend/core/dynarec/instructions.hpp index 9829900e..d32eb155 100644 --- a/src/backend/core/dynarec/instructions.hpp +++ b/src/backend/core/dynarec/instructions.hpp @@ -1,94 +1,94 @@ #pragma once #include -namespace n64::JIT { -void add(Registers&, u32); -void addu(Registers&, u32); -void addi(Registers&, u32); -void addiu(Registers&, u32); -void andi(Registers&, u32); -void and_(Registers&, u32); -void branch(Registers&, bool, s64); -void branch_likely(Registers&, bool, s64); -void b(Registers&, u32, bool); -void blink(Registers&, u32, bool); -void bl(Registers&, u32, bool); -void bllink(Registers&, u32, bool); -void dadd(Registers&, u32); -void daddu(Registers&, u32); -void daddi(Registers&, u32); -void daddiu(Registers&, u32); -void ddiv(Registers&, u32); -void ddivu(Registers&, u32); -void div(Registers&, u32); -void divu(Registers&, u32); -void dmult(Registers&, u32); -void dmultu(Registers&, u32); -void dsll(Registers&, u32); -void dsllv(Registers&, u32); -void dsll32(Registers&, u32); -void dsra(Registers&, u32); -void dsrav(Registers&, u32); -void dsra32(Registers&, u32); -void dsrl(Registers&, u32); -void dsrlv(Registers&, u32); -void dsrl32(Registers&, u32); -void dsub(Registers&, u32); -void dsubu(Registers&, u32); -void j(Registers&, u32); -void jr(Registers&, u32); -void jal(Registers&, u32); -void jalr(Registers&, u32); -void lui(Registers&, u32); -void lbu(Registers&, Mem&, u32); -void lb(Registers&, Mem&, u32); -void ld(Registers&, Mem&, u32); -void ldl(Registers&, Mem&, u32); -void ldr(Registers&, Mem&, u32); -void lh(Registers&, Mem&, u32); -void lhu(Registers&, Mem&, u32); -void ll(Registers&, Mem&, u32); -void lld(Registers&, Mem&, u32); -void lw(Registers&, Mem&, u32); -void lwl(Registers&, Mem&, u32); -void lwu(Registers&, Mem&, u32); -void lwr(Registers&, Mem&, u32); -void mfhi(Registers&, u32); -void mflo(Registers&, u32); -void mult(Registers&, u32); -void multu(Registers&, u32); -void mthi(Registers&, u32); -void mtlo(Registers&, u32); -void nor(Registers&, u32); -void sb(Registers&, Mem&, Dynarec&, u32); -void sc(Registers&, Mem&, Dynarec&, u32); -void scd(Registers&, Mem&, Dynarec&, u32); -void sd(Registers&, Mem&, Dynarec&, u32); -void sdl(Registers&, Mem&, Dynarec&, u32); -void sdr(Registers&, Mem&, Dynarec&, u32); -void sh(Registers&, Mem&, Dynarec&, u32); -void sw(Registers&, Mem&, Dynarec&, u32); -void swl(Registers&, Mem&, Dynarec&, u32); -void swr(Registers&, Mem&, Dynarec&, u32); -void slti(Registers&, u32); -void sltiu(Registers&, u32); -void slt(Registers&, u32); -void sltu(Registers&, u32); -void sll(Registers&, u32); -void sllv(Registers&, u32); -void sub(Registers&, u32); -void subu(Registers&, u32); -void sra(Registers&, u32); -void srav(Registers&, u32); -void srl(Registers&, u32); -void srlv(Registers&, u32); -void trap(Registers&, bool); -void or_(Registers&, u32); -void ori(Registers&, u32); -void xor_(Registers&, u32); -void xori(Registers&, u32); -void mtc2(Dynarec& dyn, Registers&, u32); -void mfc2(Dynarec& dyn, Registers&, u32); -void dmtc2(Dynarec& dyn, Registers&, u32); -void dmfc2(Dynarec& dyn, Registers&, u32); +namespace n64 { +void add(Dynarec&, u32); +void addu(Dynarec&, u32); +void addi(Dynarec&, u32); +void addiu(Dynarec&, u32); +void andi(Dynarec&, u32); +void and_(Dynarec&, u32); +void branch(Dynarec&, bool, s64); +void branch_likely(Dynarec&, bool, s64); +void b(Dynarec&, u32, bool); +void blink(Dynarec&, u32, bool); +void bl(Dynarec&, u32, bool); +void bllink(Dynarec&, u32, bool); +void dadd(Dynarec&, u32); +void daddu(Dynarec&, u32); +void daddi(Dynarec&, u32); +void daddiu(Dynarec&, u32); +void ddiv(Dynarec&, u32); +void ddivu(Dynarec&, u32); +void div(Dynarec&, u32); +void divu(Dynarec&, u32); +void dmult(Dynarec&, u32); +void dmultu(Dynarec&, u32); +void dsll(Dynarec&, u32); +void dsllv(Dynarec&, u32); +void dsll32(Dynarec&, u32); +void dsra(Dynarec&, u32); +void dsrav(Dynarec&, u32); +void dsra32(Dynarec&, u32); +void dsrl(Dynarec&, u32); +void dsrlv(Dynarec&, u32); +void dsrl32(Dynarec&, u32); +void dsub(Dynarec&, u32); +void dsubu(Dynarec&, u32); +void j(Dynarec&, u32); +void jr(Dynarec&, u32); +void jal(Dynarec&, u32); +void jalr(Dynarec&, u32); +void lui(Dynarec&, u32); +void lbu(Dynarec&, u32); +void lb(Dynarec&, u32); +void ld(Dynarec&, u32); +void ldl(Dynarec&, u32); +void ldr(Dynarec&, u32); +void lh(Dynarec&, u32); +void lhu(Dynarec&, u32); +void ll(Dynarec&, u32); +void lld(Dynarec&, u32); +void lw(Dynarec&, u32); +void lwl(Dynarec&, u32); +void lwu(Dynarec&, u32); +void lwr(Dynarec&, u32); +void mfhi(Dynarec&, u32); +void mflo(Dynarec&, u32); +void mult(Dynarec&, u32); +void multu(Dynarec&, u32); +void mthi(Dynarec&, u32); +void mtlo(Dynarec&, u32); +void nor(Dynarec&, u32); +void sb(Dynarec&, u32); +void sc(Dynarec&, u32); +void scd(Dynarec&, u32); +void sd(Dynarec&, u32); +void sdl(Dynarec&, u32); +void sdr(Dynarec&, u32); +void sh(Dynarec&, u32); +void sw(Dynarec&, u32); +void swl(Dynarec&, u32); +void swr(Dynarec&, u32); +void slti(Dynarec&, u32); +void sltiu(Dynarec&, u32); +void slt(Dynarec&, u32); +void sltu(Dynarec&, u32); +void sll(Dynarec&, u32); +void sllv(Dynarec&, u32); +void sub(Dynarec&, u32); +void subu(Dynarec&, u32); +void sra(Dynarec&, u32); +void srav(Dynarec&, u32); +void srl(Dynarec&, u32); +void srlv(Dynarec&, u32); +void trap(Dynarec&, bool); +void or_(Dynarec&, u32); +void ori(Dynarec&, u32); +void xor_(Dynarec&, u32); +void xori(Dynarec&, u32); +void mtc2(Dynarec&, u32); +void mfc2(Dynarec&, u32); +void dmtc2(Dynarec&, u32); +void dmfc2(Dynarec&, u32); } \ No newline at end of file diff --git a/src/backend/core/interpreter/decode.cpp b/src/backend/core/interpreter/decode.cpp index 08a3cf8b..c5e78fe4 100644 --- a/src/backend/core/interpreter/decode.cpp +++ b/src/backend/core/interpreter/decode.cpp @@ -107,7 +107,7 @@ void Interpreter::cop2Decode(u32 instr) { } } -void Interpreter::Exec(Mem& mem, u32 instr) { +void Interpreter::Exec(u32 instr) { u8 mask = (instr >> 26) & 0x3f; // 00rr_rccc switch(mask) { // TODO: named constants for clearer code @@ -139,35 +139,35 @@ void Interpreter::Exec(Mem& mem, u32 instr) { case 0x17: bl(instr, regs.gpr[RS(instr)] > 0); break; case 0x18: daddi(instr); break; case 0x19: daddiu(instr); break; - case 0x1A: ldl(mem, instr); break; - case 0x1B: ldr(mem, instr); break; + case 0x1A: ldl(instr); break; + case 0x1B: ldr(instr); break; case 0x1F: FireException(regs, ExceptionCode::ReservedInstruction, 0, true); break; - case 0x20: lb(mem, instr); break; - case 0x21: lh(mem, instr); break; - case 0x22: lwl(mem, instr); break; - case 0x23: lw(mem, instr); break; - case 0x24: lbu(mem, instr); break; - case 0x25: lhu(mem, instr); break; - case 0x26: lwr(mem, instr); break; - case 0x27: lwu(mem, instr); break; - case 0x28: sb(mem, instr); break; - case 0x29: sh(mem, instr); break; - case 0x2A: swl(mem, instr); break; - case 0x2B: sw(mem, instr); break; - case 0x2C: sdl(mem, instr); break; - case 0x2D: sdr(mem, instr); break; - case 0x2E: swr(mem, instr); break; + case 0x20: lb(instr); break; + case 0x21: lh(instr); break; + case 0x22: lwl(instr); break; + case 0x23: lw(instr); break; + case 0x24: lbu(instr); break; + case 0x25: lhu(instr); break; + case 0x26: lwr(instr); break; + case 0x27: lwu(instr); break; + case 0x28: sb(instr); break; + case 0x29: sh(instr); break; + case 0x2A: swl(instr); break; + case 0x2B: sw(instr); break; + case 0x2C: sdl(instr); break; + case 0x2D: sdr(instr); break; + case 0x2E: swr(instr); break; case 0x2F: break; // CACHE - case 0x30: ll(mem, instr); break; + case 0x30: ll(instr); break; case 0x31: regs.cop1.lwc1(regs, mem, instr); break; - case 0x34: lld(mem, instr); break; + case 0x34: lld(instr); break; case 0x35: regs.cop1.ldc1(regs, mem, instr); break; - case 0x37: ld(mem, instr); break; - case 0x38: sc(mem, instr); break; + case 0x37: ld(instr); break; + case 0x38: sc(instr); break; case 0x39: regs.cop1.swc1(regs, mem, instr); break; - case 0x3C: scd(mem, instr); break; + case 0x3C: scd(instr); break; case 0x3D: regs.cop1.sdc1(regs, mem, instr); break; - case 0x3F: sd(mem, instr); break; + case 0x3F: sd(instr); break; default: Util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})\n", mask, instr, (u64)regs.oldPC); } diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index 6ff68364..6c902b73 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -203,7 +203,7 @@ void Interpreter::lui(u32 instr) { regs.gpr[RT(instr)] = val; } -void Interpreter::lb(Mem& mem, u32 instr) { +void Interpreter::lb(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { @@ -214,7 +214,7 @@ void Interpreter::lb(Mem& mem, u32 instr) { } } -void Interpreter::lh(Mem& mem, u32 instr) { +void Interpreter::lh(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b1) > 0) { HandleTLBException(regs, address); @@ -231,7 +231,7 @@ void Interpreter::lh(Mem& mem, u32 instr) { } } -void Interpreter::lw(Mem& mem, u32 instr) { +void Interpreter::lw(u32 instr) { s16 offset = instr; u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { @@ -249,7 +249,7 @@ void Interpreter::lw(Mem& mem, u32 instr) { } } -void Interpreter::ll(Mem& mem, u32 instr) { +void Interpreter::ll(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 physical; if (!MapVAddr(regs, LOAD, address, physical)) { @@ -268,7 +268,7 @@ void Interpreter::ll(Mem& mem, u32 instr) { regs.cop0.LLAddr = physical >> 4; } -void Interpreter::lwl(Mem& mem, u32 instr) { +void Interpreter::lwl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { @@ -283,7 +283,7 @@ void Interpreter::lwl(Mem& mem, u32 instr) { } } -void Interpreter::lwr(Mem& mem, u32 instr) { +void Interpreter::lwr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { @@ -298,7 +298,7 @@ void Interpreter::lwr(Mem& mem, u32 instr) { } } -void Interpreter::ld(Mem& mem, u32 instr) { +void Interpreter::ld(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b111, address)) { HandleTLBException(regs, address); @@ -316,7 +316,7 @@ void Interpreter::ld(Mem& mem, u32 instr) { } } -void Interpreter::lld(Mem& mem, u32 instr) { +void Interpreter::lld(u32 instr) { if (!regs.cop0.is_64bit_addressing && !regs.cop0.kernel_mode) { FireException(regs, ExceptionCode::ReservedInstruction, 0, true); return; @@ -338,7 +338,7 @@ void Interpreter::lld(Mem& mem, u32 instr) { } } -void Interpreter::ldl(Mem& mem, u32 instr) { +void Interpreter::ldl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; if (!MapVAddr(regs, LOAD, address, paddr)) { @@ -353,7 +353,7 @@ void Interpreter::ldl(Mem& mem, u32 instr) { } } -void Interpreter::ldr(Mem& mem, u32 instr) { +void Interpreter::ldr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { @@ -368,7 +368,7 @@ void Interpreter::ldr(Mem& mem, u32 instr) { } } -void Interpreter::lbu(Mem& mem, u32 instr) { +void Interpreter::lbu(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { @@ -380,7 +380,7 @@ void Interpreter::lbu(Mem& mem, u32 instr) { } } -void Interpreter::lhu(Mem& mem, u32 instr) { +void Interpreter::lhu(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b1) > 0) { HandleTLBException(regs, address); @@ -397,7 +397,7 @@ void Interpreter::lhu(Mem& mem, u32 instr) { } } -void Interpreter::lwu(Mem& mem, u32 instr) { +void Interpreter::lwu(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b11) > 0) { HandleTLBException(regs, address); @@ -415,7 +415,7 @@ void Interpreter::lwu(Mem& mem, u32 instr) { } } -void Interpreter::sb(Mem& mem, u32 instr) { +void Interpreter::sb(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -426,7 +426,7 @@ void Interpreter::sb(Mem& mem, u32 instr) { } } -void Interpreter::sc(Mem& mem, u32 instr) { +void Interpreter::sc(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b11) > 0) { @@ -449,7 +449,7 @@ void Interpreter::sc(Mem& mem, u32 instr) { } } -void Interpreter::scd(Mem& mem, u32 instr) { +void Interpreter::scd(u32 instr) { if (!regs.cop0.is_64bit_addressing && !regs.cop0.kernel_mode) { FireException(regs, ExceptionCode::ReservedInstruction, 0, true); return; @@ -477,7 +477,7 @@ void Interpreter::scd(Mem& mem, u32 instr) { } } -void Interpreter::sh(Mem& mem, u32 instr) { +void Interpreter::sh(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; u32 physical; @@ -489,7 +489,7 @@ void Interpreter::sh(Mem& mem, u32 instr) { } } -void Interpreter::sw(Mem& mem, u32 instr) { +void Interpreter::sw(u32 instr) { s16 offset = instr; u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { @@ -507,7 +507,7 @@ void Interpreter::sw(Mem& mem, u32 instr) { } } -void Interpreter::sd(Mem& mem, u32 instr) { +void Interpreter::sd(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b111, address)) { HandleTLBException(regs, address); @@ -524,7 +524,7 @@ void Interpreter::sd(Mem& mem, u32 instr) { } } -void Interpreter::sdl(Mem& mem, u32 instr) { +void Interpreter::sdl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -539,7 +539,7 @@ void Interpreter::sdl(Mem& mem, u32 instr) { } } -void Interpreter::sdr(Mem& mem, u32 instr) { +void Interpreter::sdr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -554,7 +554,7 @@ void Interpreter::sdr(Mem& mem, u32 instr) { } } -void Interpreter::swl(Mem& mem, u32 instr) { +void Interpreter::swl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { @@ -569,7 +569,7 @@ void Interpreter::swl(Mem& mem, u32 instr) { } } -void Interpreter::swr(Mem& mem, u32 instr) { +void Interpreter::swr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { diff --git a/src/frontend/App.cpp b/src/frontend/App.cpp index 704b8196..77465dd4 100644 --- a/src/frontend/App.cpp +++ b/src/frontend/App.cpp @@ -9,7 +9,7 @@ App::App() : window(core) { void App::Run() { SDL_EventState(SDL_DROPFILE, SDL_ENABLE); - n64::SI& si = core.mem.mmio.si; + n64::SI& si = core.cpu->mem.mmio.si; while (!core.done) { core.Run(window, window.settings.GetVolumeL(), window.settings.GetVolumeL()); diff --git a/src/frontend/imgui/Settings.cpp b/src/frontend/imgui/Settings.cpp index 6b6bfaf4..cff54278 100644 --- a/src/frontend/imgui/Settings.cpp +++ b/src/frontend/imgui/Settings.cpp @@ -65,10 +65,10 @@ Settings::Settings(n64::Core& core) { switch(core.cpuType) { case n64::CpuType::Interpreter: - core.cpuInterp = new n64::Interpreter; + core.cpu = std::make_unique(); break; case n64::CpuType::Dynarec: - core.cpuDynarec = new n64::JIT::Dynarec; + core.cpu = std::make_unique(); break; case n64::CpuType::NONE: Util::panic("BRUH\n"); diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index f66dc0f1..5365c180 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -12,7 +12,7 @@ namespace fs = std::filesystem; Window::Window(n64::Core& core) : settings(core) { InitSDL(); - InitParallelRDP(core.mem.GetRDRAM(), window); + InitParallelRDP(core.cpu->mem.GetRDRAM(), window); InitImgui(); NFD::Init(); } @@ -199,13 +199,13 @@ void Window::RenderMainMenuBar(n64::Core &core) { } } if (ImGui::MenuItem("Dump RDRAM")) { - core.mem.DumpRDRAM(); + core.cpu->mem.DumpRDRAM(); } if (ImGui::MenuItem("Dump IMEM")) { - core.mem.DumpIMEM(); + core.cpu->mem.DumpIMEM(); } if (ImGui::MenuItem("Dump DMEM")) { - core.mem.DumpDMEM(); + core.cpu->mem.DumpDMEM(); } if (ImGui::MenuItem("Exit")) { core.done = true; @@ -250,8 +250,8 @@ void Window::Render(n64::Core& core) { static u32 lastFrame = 0; if(!core.pause && lastFrame < ticks - 1000) { lastFrame = ticks; - windowTitle += fmt::format(" | {:02d} VI/s", core.mem.mmio.vi.swaps); - core.mem.mmio.vi.swaps = 0; + windowTitle += fmt::format(" | {:02d} VI/s", core.cpu->mem.mmio.vi.swaps); + core.cpu->mem.mmio.vi.swaps = 0; SDL_SetWindowTitle(window, windowTitle.c_str()); windowTitle = shadowWindowTitle; }