Lay down initial JIT structure
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#include <backend/core/Interpreter.hpp>
|
#include <backend/core/Interpreter.hpp>
|
||||||
|
#include <backend/core/JIT.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ namespace n64 {
|
|||||||
struct BaseCPU {
|
struct BaseCPU {
|
||||||
virtual ~BaseCPU() = default;
|
virtual ~BaseCPU() = default;
|
||||||
virtual int Step() {return 0;}
|
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;
|
Registers regs;
|
||||||
Mem mem;
|
Mem mem;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
void Interpreter::Reset() {
|
|
||||||
regs.Reset();
|
|
||||||
mem.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Interpreter::Step() {
|
int Interpreter::Step() {
|
||||||
CheckCompareInterrupt();
|
CheckCompareInterrupt();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Mem.hpp>
|
#include <Mem.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "BaseCPU.hpp"
|
#include <BaseCPU.hpp>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
struct Core;
|
struct Core;
|
||||||
@@ -9,12 +9,11 @@ struct Interpreter : BaseCPU {
|
|||||||
Interpreter() = default;
|
Interpreter() = default;
|
||||||
~Interpreter() override = default;
|
~Interpreter() override = default;
|
||||||
int Step() override;
|
int Step() override;
|
||||||
void Reset() override;
|
|
||||||
private:
|
private:
|
||||||
u64 cop2Latch{};
|
u64 cop2Latch{};
|
||||||
friend struct Cop1;
|
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_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0;
|
||||||
bool interrupts_enabled = regs.cop0.status.ie == 1;
|
bool interrupts_enabled = regs.cop0.status.ie == 1;
|
||||||
bool currently_handling_exception = regs.cop0.status.exl == 1;
|
bool currently_handling_exception = regs.cop0.status.exl == 1;
|
||||||
@@ -24,7 +23,7 @@ private:
|
|||||||
!currently_handling_exception && !currently_handling_error;
|
!currently_handling_exception && !currently_handling_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void CheckCompareInterrupt() {
|
FORCE_INLINE void CheckCompareInterrupt() override {
|
||||||
regs.cop0.count++;
|
regs.cop0.count++;
|
||||||
regs.cop0.count &= 0x1FFFFFFFF;
|
regs.cop0.count &= 0x1FFFFFFFF;
|
||||||
if(regs.cop0.count == (u64)regs.cop0.compare << 1) {
|
if(regs.cop0.count == (u64)regs.cop0.compare << 1) {
|
||||||
|
|||||||
47
src/backend/core/JIT.cpp
Normal file
47
src/backend/core/JIT.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include <JIT.hpp>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/backend/core/JIT.hpp
Normal file
117
src/backend/core/JIT.hpp
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Mem.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <BaseCPU.hpp>
|
||||||
|
#include <xbyak.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ Settings::Settings(n64::Core& core) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(jit) {
|
if(jit) {
|
||||||
Util::panic("JIT is unimplemented!");
|
core.cpu = std::make_unique<n64::JIT>();
|
||||||
} else {
|
} else {
|
||||||
core.cpu = std::make_unique<n64::Interpreter>();
|
core.cpu = std::make_unique<n64::Interpreter>();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user