improve dead code elimination and implement SLT

This commit is contained in:
Simone
2023-12-27 10:13:11 +01:00
parent 80c7e46a38
commit dacb76ca85
4 changed files with 44 additions and 35 deletions

View File

@@ -32,12 +32,15 @@ void JIT::CheckCompareInterrupt() {
Fn JIT::Recompile() {
bool stable = true;
bool old_stable = stable;
cycles = 0;
//prologue();
//mov(rbp, u64(this));
//mov(rdi, u64(this) + THIS_OFFSET(regs));
u64 pc = regs.pc;
while(stable) {
u64 pc = regs.pc + 0x3D0;
while(old_stable) {
old_stable = stable;
cycles++;
CheckCompareInterrupt();

View File

@@ -47,6 +47,7 @@ template <> struct fmt::formatter<Entry> : formatter<string_view> {
case Entry::JUMP: op = "JUMP"; break;
case Entry::MTC0: op = "MTC0"; break;
case Entry::MFC0: op = "MFC0"; break;
case Entry::SLT: op = "SLT"; break;
}
bool put_comma = false;
@@ -148,17 +149,20 @@ void IR::dead_code_elimination(std::vector<Entry>& code_) {
bool isOp2Reg = i.op2.isReg();
bool isDstReg = i.dst.isReg();
// check for operations like "add rx, rx, 0" or "add r0, anything"
if(isDstReg) {
if(i.zeroRendersItUseless() && i.dst.index_or_imm == 0) continue;
bool isDstR0 = i.dst.isReg() && i.dst.index_or_imm.has_value() && i.dst.index_or_imm.value() == 0;
bool areDstAndOp1Same = i.dst.isReg() && i.op1.isReg() && i.dst.index_or_imm.has_value() && i.op1.index_or_imm.has_value() && i.op1.index_or_imm.value() == i.dst.index_or_imm.value();
bool areDstAndOp2Same = i.dst.isReg() && i.op2.isReg() && i.dst.index_or_imm.has_value() && i.op2.index_or_imm.has_value() && i.op2.index_or_imm.value() == i.dst.index_or_imm.value();
if (isDstR0) continue;
if (i.canDoDCE()) {
if (areDstAndOp1Same) {
if (i.op2.isImm() && i.op2.index_or_imm.value() == 0) continue;
}
if(isOp1Reg) {
if(i.op1.index_or_imm == i.dst.index_or_imm
&& i.zeroRendersItUseless()) continue;
}
if(isOp2Reg) {
if(i.op2.index_or_imm == i.dst.index_or_imm
&& i.zeroRendersItUseless()) continue;
if (areDstAndOp2Same) {
if (i.op1.isImm() && i.op1.index_or_imm.value() == 0) continue;
}
}
}

View File

@@ -18,7 +18,8 @@ struct Entry {
};
enum Opcode : u16 {
MOV, ADD, SUB, UMUL, SMUL, DIV, AND, NOR, XOR, OR, SRL, SLL, SRA,
MOV, SLT, ADD, SUB, UMUL, SMUL, DIV, AND, NOR,
XOR, OR, SRL, SLL, SRA,
LOADS8, LOADS8_SHIFT, STORE8, STORE8_SHIFT,
LOADS16, LOADS16_SHIFT, STORE16, STORE16_SHIFT,
LOADS32, LOADS32_SHIFT, STORE32, STORE32_SHIFT,
@@ -45,8 +46,9 @@ struct Entry {
}
bool isImm() const {
return type == IMM_S64 || type == IMM_F32 || type == IMM_F64 || type == IMM_S32
|| type == IMM_U64 || type == IMM_U32 || type == IMM_U5;
return type == IMM_S64 || type == IMM_U16 || type == IMM_S16 ||
type == IMM_F32 || type == IMM_F64 || type == IMM_S32 ||
type == IMM_U64 || type == IMM_U32 || type == IMM_U5;
}
std::optional<u64> index_or_imm = std::nullopt;
@@ -56,7 +58,7 @@ struct Entry {
: type(t), index_or_imm(imm) {}
} dst, op1, op2;
bool zeroRendersItUseless() const {
bool canDoDCE() const {
return op == ADD || op == OR || op == SRL || op == SLL || op == SRA;
}

View File

@@ -476,35 +476,35 @@ void JIT::jalr(u32 instr) {
}
void JIT::slti(u32 instr) {
mov(rax, s64(s16(instr)));
mov(rcx, GPR(qword, RS(instr)));
cmp(rcx, rax);
setl(GPR(qword, RT(instr)));
Entry e(Entry::SLT,
{ Entry::Operand::REG_U5, RT(instr) },
{ Entry::Operand::REG_S64, RS(instr) },
{ Entry::Operand::IMM_S64, s64(s16(instr)) });
ir.push(e);
}
void JIT::sltiu(u32 instr) {
mov(rax, s64(s16(instr)));
mov(rcx, GPR(qword, RS(instr)));
cmp(rcx, rax);
setb(GPR(qword, RT(instr)));
Entry e(Entry::SLT,
{ Entry::Operand::REG_U5, RT(instr) },
{ Entry::Operand::REG_U64, RS(instr) },
{ Entry::Operand::IMM_U64, u64(s64(s16(instr))) });
ir.push(e);
}
void JIT::slt(u32 instr) {
if (RD(instr) != 0) [[likely]] {
mov(rax, GPR(qword, RS(instr)));
mov(rcx, GPR(qword, RT(instr)));
cmp(rax, rcx);
setl(GPR(qword, RD(instr)));
}
Entry e(Entry::SLT,
{ Entry::Operand::REG_U5, RD(instr) },
{ Entry::Operand::REG_S64, RS(instr) },
{ Entry::Operand::REG_S64, RT(instr) });
ir.push(e);
}
void JIT::sltu(u32 instr) {
if (RD(instr) != 0) [[likely]] {
mov(rax, GPR(qword, RS(instr)));
mov(rcx, GPR(qword, RT(instr)));
cmp(rax, rcx);
setb(GPR(qword, RD(instr)));
}
Entry e(Entry::SLT,
{ Entry::Operand::REG_U5, RD(instr) },
{ Entry::Operand::REG_U64, RS(instr) },
{ Entry::Operand::REG_U64, RT(instr) });
ir.push(e);
}
void JIT::xori(u32 instr) {