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