more work

This commit is contained in:
SimoneN64
2023-08-19 16:12:51 +02:00
parent c8a9b7951b
commit 1a338de8b9
3 changed files with 76 additions and 26 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;