more work
This commit is contained in:
@@ -81,12 +81,23 @@ private:
|
||||
void andi(u32);
|
||||
void and_(u32);
|
||||
void emitCondition(const std::string&, BranchCond);
|
||||
void branch(Xbyak::Operand, Xbyak::Operand, s64, BranchCond);
|
||||
void branch_likely(Xbyak::Operand, Xbyak::Operand, s64, BranchCond);
|
||||
void b(u32, Xbyak::Operand, Xbyak::Operand, BranchCond);
|
||||
void blink(u32, Xbyak::Operand, Xbyak::Operand, BranchCond);
|
||||
void bl(u32, Xbyak::Operand, Xbyak::Operand, BranchCond);
|
||||
void bllink(u32, Xbyak::Operand, Xbyak::Operand, BranchCond);
|
||||
template <class T>
|
||||
void branch(const Xbyak::Operand&, const T&, s64, BranchCond);
|
||||
|
||||
template <class T>
|
||||
void branch_likely(const Xbyak::Operand&, const T&, s64, BranchCond);
|
||||
|
||||
template <class T>
|
||||
void b(u32, const Xbyak::Operand&, const T&, BranchCond);
|
||||
|
||||
template <class T>
|
||||
void blink(u32, const Xbyak::Operand&, const T&, BranchCond);
|
||||
|
||||
template <class T>
|
||||
void bl(u32, const Xbyak::Operand&, const T&, BranchCond);
|
||||
|
||||
template <class T>
|
||||
void bllink(u32, const Xbyak::Operand&, const T&, BranchCond);
|
||||
void dadd(u32);
|
||||
void daddu(u32);
|
||||
void daddi(u32);
|
||||
|
||||
@@ -71,20 +71,44 @@ void JIT::regimm(u32 instr) {
|
||||
u8 mask = ((instr >> 16) & 0x1F);
|
||||
// 000r_rccc
|
||||
switch (mask) { // TODO: named constants for clearer code
|
||||
case 0x00: b(instr, regs.gpr[RS(instr)] < 0); break;
|
||||
case 0x01: b(instr, regs.gpr[RS(instr)] >= 0); break;
|
||||
case 0x02: bl(instr, regs.gpr[RS(instr)] < 0); break;
|
||||
case 0x03: bl(instr, regs.gpr[RS(instr)] >= 0); break;
|
||||
case 0x00: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
b(instr, rax, 0, LT);
|
||||
} break;
|
||||
case 0x01: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
b(instr, rax, 0, GE);
|
||||
} break;
|
||||
case 0x02: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
bl(instr, rax, 0, LT);
|
||||
} break;
|
||||
case 0x03: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
bl(instr, rax, 0, GE);
|
||||
} break;
|
||||
case 0x08: trap(regs.gpr[RS(instr)] >= s64(s16(instr))); break;
|
||||
case 0x09: trap(u64(regs.gpr[RS(instr)]) >= u64(s64(s16(instr)))); break;
|
||||
case 0x0A: trap(regs.gpr[RS(instr)] < s64(s16(instr))); break;
|
||||
case 0x0B: trap(u64(regs.gpr[RS(instr)]) < u64(s64(s16(instr)))); break;
|
||||
case 0x0C: trap(regs.gpr[RS(instr)] == s64(s16(instr))); break;
|
||||
case 0x0E: trap(regs.gpr[RS(instr)] != s64(s16(instr))); break;
|
||||
case 0x10: blink(instr, regs.gpr[RS(instr)] < 0); break;
|
||||
case 0x11: blink(instr, regs.gpr[RS(instr)] >= 0); break;
|
||||
case 0x12: bllink(instr, regs.gpr[RS(instr)] < 0); break;
|
||||
case 0x13: bllink(instr, regs.gpr[RS(instr)] >= 0); break;
|
||||
case 0x10: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
blink(instr, rax, 0, LT);
|
||||
} break;
|
||||
case 0x11: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
blink(instr, rax, 0, GE);
|
||||
} break;
|
||||
case 0x12: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
bllink(instr, rax, 0, LT);
|
||||
} break;
|
||||
case 0x13: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
bllink(instr, rax, 0, GE);
|
||||
} break;
|
||||
default:
|
||||
Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC);
|
||||
}
|
||||
@@ -115,13 +139,24 @@ void JIT::Emit(u32 instr) {
|
||||
case 0x01: regimm(instr); break;
|
||||
case 0x02: j(instr); break;
|
||||
case 0x03: jal(instr); break;
|
||||
case 0x04: b(instr, regs.gpr[RS(instr)] == regs.gpr[RT(instr)]); break;
|
||||
case 0x05: {
|
||||
//fmt::print("RS: {:016X}, RT: {:016X}", (u64)regs.gpr[RS(instr)], (u64)regs.gpr[RT(instr)]);
|
||||
b(instr, regs.gpr[RS(instr)] != regs.gpr[RT(instr)]);
|
||||
case 0x04: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
mov(rcx, GPR(RT(instr)));
|
||||
b(instr, rax, rcx, EQ);
|
||||
} break;
|
||||
case 0x05: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
mov(rcx, GPR(RT(instr)));
|
||||
b(instr, rax, rcx, NE);
|
||||
} break;
|
||||
case 0x06: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
b(instr, rax, 0, LE);
|
||||
} break;
|
||||
case 0x07: {
|
||||
mov(rax, GPR(RS(instr)));
|
||||
b(instr, rax, 0, GT);
|
||||
} break;
|
||||
case 0x06: b(instr, regs.gpr[RS(instr)] <= 0); break;
|
||||
case 0x07: b(instr, regs.gpr[RS(instr)] > 0); break;
|
||||
case 0x08: addi(instr); break;
|
||||
case 0x09: addiu(instr); break;
|
||||
case 0x0A: slti(instr); break;
|
||||
|
||||
@@ -166,7 +166,8 @@ void JIT::emitCondition(const std::string& name, BranchCond cond) {
|
||||
}
|
||||
}
|
||||
|
||||
void JIT::branch(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, BranchCond cond) {
|
||||
template <class T>
|
||||
void JIT::branch(const Xbyak::Operand& op1, const T& op2, s64 offset, BranchCond cond) {
|
||||
cmp(op1, op2);
|
||||
emitCondition("false", cond);
|
||||
|
||||
@@ -177,7 +178,10 @@ void JIT::branch(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, BranchCond
|
||||
L("false");
|
||||
}
|
||||
|
||||
void JIT::branch_likely(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, BranchCond cond) {
|
||||
template void JIT::branch<Xbyak::Operand>(const Xbyak::Operand& op1, const Xbyak::Operand& op2, s64 offset, BranchCond cond);
|
||||
template void JIT::branch<int>(const Xbyak::Operand& op1, const int& op2, s64 offset, BranchCond cond);
|
||||
|
||||
void JIT::branch_likely(const Xbyak::Operand& op1, const Xbyak::Operand& op2, s64 offset, BranchCond cond) {
|
||||
mov(rax, qword[rdi + offsetof(Registers, pc)]);
|
||||
cmp(op1, op2);
|
||||
emitCondition("false", cond);
|
||||
@@ -196,13 +200,13 @@ void JIT::branch_likely(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, Bran
|
||||
L("exit");
|
||||
}
|
||||
|
||||
void JIT::b(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) {
|
||||
void JIT::b(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) {
|
||||
s16 imm = instr;
|
||||
s64 offset = u64((s64)imm) << 2;
|
||||
branch(op1, op2, offset, cond);
|
||||
}
|
||||
|
||||
void JIT::blink(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) {
|
||||
void JIT::blink(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) {
|
||||
s16 imm = instr;
|
||||
s64 offset = u64((s64)imm) << 2;
|
||||
mov(rcx, qword[rdi + offsetof(Registers, nextPC)]);
|
||||
@@ -210,13 +214,13 @@ void JIT::blink(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond co
|
||||
branch(op1, op2, offset, cond);
|
||||
}
|
||||
|
||||
void JIT::bl(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) {
|
||||
void JIT::bl(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) {
|
||||
s16 imm = instr;
|
||||
s64 offset = u64((s64)imm) << 2;
|
||||
branch_likely(op1, op2, offset, cond);
|
||||
}
|
||||
|
||||
void JIT::bllink(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) {
|
||||
void JIT::bllink(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) {
|
||||
mov(rcx, qword[rdi + offsetof(Registers, nextPC)]);
|
||||
mov(GPR(31), rcx);
|
||||
s16 imm = instr;
|
||||
|
||||
Reference in New Issue
Block a user