[JIT]: Finally executing out of bootcode!
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
#include <core/Mem.hpp>
|
#include <core/Mem.hpp>
|
||||||
#include <core/registers/Registers.hpp>
|
#include <core/registers/Registers.hpp>
|
||||||
|
|
||||||
|
Scheduler scheduler;
|
||||||
|
|
||||||
void Scheduler::EnqueueRelative(const u64 t, const EventType type) { EnqueueAbsolute(t + ticks, type); }
|
void Scheduler::EnqueueRelative(const u64 t, const EventType type) { EnqueueAbsolute(t + ticks, type); }
|
||||||
|
|
||||||
void Scheduler::EnqueueAbsolute(const u64 t, const EventType type) { events.push({t, type}); }
|
void Scheduler::EnqueueAbsolute(const u64 t, const EventType type) { events.push({t, type}); }
|
||||||
|
|||||||
@@ -45,4 +45,4 @@ struct Scheduler {
|
|||||||
u8 index = 0;
|
u8 index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Scheduler scheduler;
|
extern Scheduler scheduler;
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ int JIT::Step() {
|
|||||||
bool branchWasLikely = false;
|
bool branchWasLikely = false;
|
||||||
bool blockEndsOnBranch = false;
|
bool blockEndsOnBranch = false;
|
||||||
|
|
||||||
code.sub(code.rsp, 56);
|
// code.int3();
|
||||||
|
code.sub(code.rsp, 8);
|
||||||
code.push(code.rbp);
|
code.push(code.rbp);
|
||||||
code.mov(code.rbp, reinterpret_cast<uintptr_t>(this)); // Load context pointer
|
code.mov(code.rbp, reinterpret_cast<uintptr_t>(this)); // Load context pointer
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ int JIT::Step() {
|
|||||||
|
|
||||||
if (instrInDelaySlot && branchWasLikely) {
|
if (instrInDelaySlot && branchWasLikely) {
|
||||||
branchWasLikely = false;
|
branchWasLikely = false;
|
||||||
code.L("not_taken");
|
code.L(branch_likely_not_taken);
|
||||||
code.mov(code.rax, blockPC);
|
code.mov(code.rax, blockPC);
|
||||||
code.mov(REG(qword, pc), code.rax);
|
code.mov(REG(qword, pc), code.rax);
|
||||||
}
|
}
|
||||||
@@ -123,11 +124,11 @@ int JIT::Step() {
|
|||||||
}
|
}
|
||||||
code.mov(code.rax, instructionsInBlock);
|
code.mov(code.rax, instructionsInBlock);
|
||||||
code.pop(code.rbp);
|
code.pop(code.rbp);
|
||||||
code.add(code.rsp, 56);
|
code.add(code.rsp, 8);
|
||||||
code.ret();
|
code.ret();
|
||||||
code.setProtectModeRE();
|
code.setProtectModeRE();
|
||||||
// const auto dump = code.getCode();
|
const auto dump = code.getCode();
|
||||||
// Util::WriteFileBinary(dump, code.getSize(), "jit.dump");
|
Util::WriteFileBinary(dump, code.getSize(), "jit.dump");
|
||||||
// Util::panic("");
|
// Util::panic("");
|
||||||
return block();
|
return block();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ private:
|
|||||||
friend struct Cop1;
|
friend struct Cop1;
|
||||||
friend struct Registers;
|
friend struct Registers;
|
||||||
using BlockFn = int (*)();
|
using BlockFn = int (*)();
|
||||||
|
Xbyak::Label branch_likely_not_taken;
|
||||||
|
|
||||||
std::vector<std::vector<BlockFn>> blockCache;
|
std::vector<std::vector<BlockFn>> blockCache;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -84,7 +85,9 @@ private:
|
|||||||
|
|
||||||
code.mov(code.rdi, thisPtr);
|
code.mov(code.rdi, thisPtr);
|
||||||
code.mov(code.rax, functionPtr);
|
code.mov(code.rax, functionPtr);
|
||||||
|
code.sub(code.rsp, 8);
|
||||||
code.call(code.rax);
|
code.call(code.rax);
|
||||||
|
code.add(code.rsp, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkipSlot();
|
void SkipSlot();
|
||||||
|
|||||||
@@ -162,50 +162,55 @@ void JIT::SkipSlot() { code.jmp("not_taken"); }
|
|||||||
void JIT::SkipSlotConstant() { blockPC += 4; }
|
void JIT::SkipSlotConstant() { blockPC += 4; }
|
||||||
|
|
||||||
void JIT::BranchTaken(const s64 offs) {
|
void JIT::BranchTaken(const s64 offs) {
|
||||||
code.mov(code.rax, REG(qword, pc));
|
code.mov(code.rax, blockPC + offs);
|
||||||
code.add(code.rax, offs);
|
|
||||||
code.mov(REG(qword, pc), code.rax);
|
code.mov(REG(qword, pc), code.rax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::BranchTaken(const Xbyak::Reg64 &offs) { code.add(REG(qword, pc), offs); }
|
void JIT::BranchTaken(const Xbyak::Reg64 &offs) {
|
||||||
|
code.add(offs, blockPC);
|
||||||
|
code.mov(REG(qword, pc), offs);
|
||||||
|
}
|
||||||
|
|
||||||
void JIT::BranchAbsTaken(const s64 addr) {
|
void JIT::BranchAbsTaken(const s64 addr) {
|
||||||
code.mov(code.rax, addr);
|
code.mov(code.rax, addr);
|
||||||
code.mov(REG(qword, pc), code.rax);
|
code.mov(REG(qword, pc), code.rax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::BranchAbsTaken(const Xbyak::Reg64 &addr) { code.mov(REG(qword, nextPC), addr); }
|
void JIT::BranchAbsTaken(const Xbyak::Reg64 &addr) { code.mov(REG(qword, pc), addr); }
|
||||||
|
|
||||||
#define branch(offs, cond) \
|
#define branch(offs, cond) \
|
||||||
do { \
|
do { \
|
||||||
code.j##cond("taken"); \
|
Xbyak::Label taken, not_taken; \
|
||||||
|
code.j##cond(taken); \
|
||||||
code.mov(code.rax, blockPC); \
|
code.mov(code.rax, blockPC); \
|
||||||
code.mov(REG(qword, pc), code.rax); \
|
code.mov(REG(qword, pc), code.rax); \
|
||||||
code.jmp("not_taken"); \
|
code.jmp(not_taken); \
|
||||||
code.L("taken"); \
|
code.L(taken); \
|
||||||
BranchTaken(offs); \
|
BranchTaken(offs); \
|
||||||
code.L("not_taken"); \
|
code.L(not_taken); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
#define branch_abs(addr, cond) \
|
#define branch_abs(addr, cond) \
|
||||||
do { \
|
do { \
|
||||||
code.j##cond("taken"); \
|
Xbyak::Label taken, not_taken; \
|
||||||
|
code.j##cond(taken); \
|
||||||
code.mov(code.rax, blockPC); \
|
code.mov(code.rax, blockPC); \
|
||||||
code.mov(REG(qword, pc), code.rax); \
|
code.mov(REG(qword, pc), code.rax); \
|
||||||
code.jmp("not_taken"); \
|
code.jmp(not_taken); \
|
||||||
code.L("taken"); \
|
code.L(taken); \
|
||||||
BranchAbsTaken(addr); \
|
BranchAbsTaken(addr); \
|
||||||
code.L("not_taken"); \
|
code.L(not_taken); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
#define branch_likely(offs, cond) \
|
#define branch_likely(offs, cond) \
|
||||||
do { \
|
do { \
|
||||||
code.j##cond("taken"); \
|
Xbyak::Label taken; \
|
||||||
|
code.j##cond(taken); \
|
||||||
SkipSlot(); \
|
SkipSlot(); \
|
||||||
code.jmp("not_taken"); \
|
code.jmp(branch_likely_not_taken); \
|
||||||
code.L("taken"); \
|
code.L(taken); \
|
||||||
BranchTaken(offs); \
|
BranchTaken(offs); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|||||||
Reference in New Issue
Block a user