From 471565297061e8ab46e22c18f00574d142446b33 Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Tue, 25 Jul 2023 10:53:23 +0200 Subject: [PATCH] Lay down initial JIT structure --- src/backend/Core.hpp | 1 + src/backend/core/BaseCPU.hpp | 7 +- src/backend/core/Interpreter.cpp | 5 -- src/backend/core/Interpreter.hpp | 7 +- src/backend/core/JIT.cpp | 47 +++++++++++++ src/backend/core/JIT.hpp | 117 +++++++++++++++++++++++++++++++ src/frontend/imgui/Settings.cpp | 2 +- 7 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 src/backend/core/JIT.cpp create mode 100644 src/backend/core/JIT.hpp diff --git a/src/backend/Core.hpp b/src/backend/Core.hpp index 8057aaf2..3ddba612 100644 --- a/src/backend/Core.hpp +++ b/src/backend/Core.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include diff --git a/src/backend/core/BaseCPU.hpp b/src/backend/core/BaseCPU.hpp index e836160f..0a41b959 100644 --- a/src/backend/core/BaseCPU.hpp +++ b/src/backend/core/BaseCPU.hpp @@ -6,7 +6,12 @@ namespace n64 { struct BaseCPU { virtual ~BaseCPU() = default; virtual int Step() {return 0;} - virtual void Reset() {} + virtual void Reset() { + regs.Reset(); + mem.Reset(); + } + virtual bool ShouldServiceInterrupt() {return false;} + virtual void CheckCompareInterrupt() {} Registers regs; Mem mem; }; diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 3612de3a..7cf74e85 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -1,11 +1,6 @@ #include namespace n64 { -void Interpreter::Reset() { - regs.Reset(); - mem.Reset(); -} - int Interpreter::Step() { CheckCompareInterrupt(); diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 8ba28b76..1ad122b0 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -1,7 +1,7 @@ #pragma once #include #include -#include "BaseCPU.hpp" +#include namespace n64 { struct Core; @@ -9,12 +9,11 @@ struct Interpreter : BaseCPU { Interpreter() = default; ~Interpreter() override = default; int Step() override; - void Reset() override; private: u64 cop2Latch{}; friend struct Cop1; - [[nodiscard]] FORCE_INLINE bool ShouldServiceInterrupt() const { + [[nodiscard]] FORCE_INLINE bool ShouldServiceInterrupt() override { bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; bool interrupts_enabled = regs.cop0.status.ie == 1; bool currently_handling_exception = regs.cop0.status.exl == 1; @@ -24,7 +23,7 @@ private: !currently_handling_exception && !currently_handling_error; } - FORCE_INLINE void CheckCompareInterrupt() { + FORCE_INLINE void CheckCompareInterrupt() override { regs.cop0.count++; regs.cop0.count &= 0x1FFFFFFFF; if(regs.cop0.count == (u64)regs.cop0.compare << 1) { diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp new file mode 100644 index 00000000..9d14c55a --- /dev/null +++ b/src/backend/core/JIT.cpp @@ -0,0 +1,47 @@ +#include + +namespace n64 { +using namespace Xbyak; +JIT::JIT() : CodeGenerator(0x80000) { } + +void JIT::Reset() { + reset(); + regs.Reset(); + mem.Reset(); +} + +bool JIT::ShouldServiceInterrupt() { + +} + +void JIT::CheckCompareInterrupt() { + +} + +int JIT::Step() { + CheckCompareInterrupt(); + + regs.prevDelaySlot = regs.delaySlot; + regs.delaySlot = false; + + u32 paddr = 0; + if(!MapVAddr(regs, LOAD, regs.pc, paddr)) { + HandleTLBException(regs, regs.pc); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, false); + return 0; + } + + u32 instruction = mem.Read32(regs, paddr); + + if(ShouldServiceInterrupt()) { + FireException(regs, ExceptionCode::Interrupt, 0, false); + return 0; + } + + regs.oldPC = regs.pc; + regs.pc = regs.nextPC; + regs.nextPC += 4; + + return 1; +} +} \ No newline at end of file diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp new file mode 100644 index 00000000..aa3bb935 --- /dev/null +++ b/src/backend/core/JIT.hpp @@ -0,0 +1,117 @@ +#pragma once +#include +#include +#include +#include + +namespace n64 { +using Fn = void(*)(); + +struct JIT : BaseCPU, Xbyak::CodeGenerator { + JIT(); + ~JIT() override = default; + int Step() override; + void Reset() override; +private: + bool ShouldServiceInterrupt() override; + void CheckCompareInterrupt() override; + + Fn* blocks[0x80000]{}; + + void cop2Decode(u32); + void special(u32); + void regimm(u32); + void add(u32); + void addu(u32); + void addi(u32); + void addiu(u32); + void andi(u32); + void and_(u32); + void branch(bool, s64); + void branch_likely(bool, s64); + void b(u32, bool); + void blink(u32, bool); + void bl(u32, bool); + void bllink(u32, bool); + void dadd(u32); + void daddu(u32); + void daddi(u32); + void daddiu(u32); + void ddiv(u32); + void ddivu(u32); + void div(u32); + void divu(u32); + void dmult(u32); + void dmultu(u32); + void dsll(u32); + void dsllv(u32); + void dsll32(u32); + void dsra(u32); + void dsrav(u32); + void dsra32(u32); + void dsrl(u32); + void dsrlv(u32); + void dsrl32(u32); + void dsub(u32); + void dsubu(u32); + void j(u32); + void jr(u32); + void jal(u32); + void jalr(u32); + void lui(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); + void multu(u32); + void mthi(u32); + void mtlo(u32); + void nor(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); + void sltu(u32); + void sll(u32); + void sllv(u32); + void sub(u32); + void subu(u32); + void sra(u32); + void srav(u32); + void srl(u32); + void srlv(u32); + void trap(bool); + void or_(u32); + void ori(u32); + void xor_(u32); + void xori(u32); + + void mtc2(u32); + void mfc2(u32); + void dmtc2(u32); + void dmfc2(u32); + void ctc2(u32); + void cfc2(u32); +}; +} \ No newline at end of file diff --git a/src/frontend/imgui/Settings.cpp b/src/frontend/imgui/Settings.cpp index b8ec46fd..8cba5c97 100644 --- a/src/frontend/imgui/Settings.cpp +++ b/src/frontend/imgui/Settings.cpp @@ -53,7 +53,7 @@ Settings::Settings(n64::Core& core) { } if(jit) { - Util::panic("JIT is unimplemented!"); + core.cpu = std::make_unique(); } else { core.cpu = std::make_unique(); }