improve branch, doesn't need extra add in IR

This commit is contained in:
Simone
2023-12-27 10:30:59 +01:00
parent dacb76ca85
commit fb3146744f
4 changed files with 65 additions and 35 deletions

View File

@@ -137,7 +137,7 @@ private:
void addiu(u32);
void andi(u32);
void and_(u32);
Entry branch(u32);
Entry::Operand branch(u32);
void bltz(u32);
void bgez(u32);
void bltzl(u32);

View File

@@ -59,11 +59,13 @@ template <> struct fmt::formatter<Entry> : formatter<string_view> {
put_comma = true;
}
} else if(e.dst.isImm()) {
if(e.dst.type != Entry::Operand::NONE) {
std::string dst = fmt::format("0x{:0X}", e.dst.index_or_imm.value());
op += dst;
put_comma = true;
}
std::string dst = fmt::format("0x{:0X}", e.dst.index_or_imm.value());
op += dst;
put_comma = true;
} else if(e.dst.type == Entry::Operand::PC64) {
std::string dst = fmt::format("PC");
op += dst;
put_comma = true;
} else {
if(e.dst.type != Entry::Operand::NONE) {
std::string dst = fmt::format("(0x{:0X})", e.dst.index_or_imm.value());
@@ -72,6 +74,12 @@ template <> struct fmt::formatter<Entry> : formatter<string_view> {
}
}
if (e.bOffs.index_or_imm.has_value()) {
std::string dst = fmt::format("0x{:0X}", e.bOffs.index_or_imm.value());
op += dst;
put_comma = true;
}
if (e.op1.isReg()) {
if (e.op1.index_or_imm.has_value()) {
std::string op1 = fmt::format("R{}", e.op1.index_or_imm.value());
@@ -90,6 +98,13 @@ template <> struct fmt::formatter<Entry> : formatter<string_view> {
op += op1;
put_comma = true;
}
} else if (e.dst.type == Entry::Operand::PC64) {
std::string dst = fmt::format("PC");
if (put_comma) {
op += ", ";
}
op += dst;
put_comma = true;
} else {
if (e.op1.index_or_imm.has_value()) {
std::string op1 = fmt::format("(0x{:0X})", e.op1.index_or_imm.value());
@@ -101,6 +116,20 @@ template <> struct fmt::formatter<Entry> : formatter<string_view> {
}
}
if (e.branchCond.has_value()) {
put_comma = false;
op += " ";
switch (e.branchCond.value()) {
case Entry::AL: op += " "; break;
case Entry::EQ: op += "== "; break;
case Entry::NE: op += "!= "; break;
case Entry::LT: op += "< "; break;
case Entry::GT: op += "> "; break;
case Entry::LE: op += "<= "; break;
case Entry::GE: op += ">= "; break;
}
}
if (e.op2.isReg()) {
if (e.op2.index_or_imm.has_value()) {
std::string op2 = fmt::format("R{}", e.op2.index_or_imm.value());
@@ -130,11 +159,11 @@ Entry::Entry(Opcode op, Operand dst, Operand op1, Operand op2)
Entry::Entry(Opcode op, Operand op1, Operand op2)
: op(op), op1(op1), op2(op2) {}
Entry::Entry(Opcode op, Operand bDest, Operand op1, std::optional<BranchCond> bc, Operand op2)
: op(op), bDest(bDest), op1(op1), branchCond(bc), op2(op2) {}
Entry::Entry(Opcode op, Operand bOffs, Operand op1, std::optional<BranchCond> bc, Operand op2)
: op(op), bOffs(bOffs), op1(op1), branchCond(bc), op2(op2) {}
Entry::Entry(Opcode op, Operand bDest)
: op(op), bDest(bDest) {}
Entry::Entry(Opcode op, Operand bOffs)
: op(op), bOffs(bOffs) {}
Entry::Entry(Opcode op, Operand dst, Operand op1, Operand op2, Shift s)
: op(op), dst(dst), op1(op1), op2(op2), shift(s) {}

View File

@@ -51,6 +51,10 @@ struct Entry {
type == IMM_U64 || type == IMM_U32 || type == IMM_U5;
}
bool isMem() const {
return type == MEM_U8 || type == MEM_U16 || type == MEM_U32 || type == MEM_U64;
}
std::optional<u64> index_or_imm = std::nullopt;
Operand() = default;
@@ -70,12 +74,12 @@ struct Entry {
std::optional<BranchCond> branchCond = std::nullopt;
std::optional<Shift> shift = std::nullopt;
Operand bDest = Operand::NONE;
Operand bOffs = Operand::NONE;
Entry(Opcode op, Operand dst, Operand op1, Operand op2);
Entry(Opcode op, Operand op1, Operand op2);
Entry(Opcode op, Operand bDest, Operand op1, std::optional<BranchCond> bc, Operand op2);
Entry(Opcode op, Operand bDest);
Entry(Opcode op, Operand bOffs, Operand op1, std::optional<BranchCond> bc, Operand op2);
Entry(Opcode op, Operand bOffs);
Entry(Opcode op, Operand dst, Operand op1, Operand op2, Shift s);
};

View File

@@ -37,19 +37,16 @@ void JIT::dadd(u32 instr) {
ir.push(e);
}
Entry JIT::branch(u32 instr) {
auto dst = Entry::Operand{ Entry::Operand::IMM_S64, u64(s64(s16(instr))) << 2 };
auto pc = Entry::Operand{Entry::Operand::PC64};
Entry add_(Entry::ADD, dst, dst, pc);
ir.push(add_);
return add_;
Entry::Operand JIT::branch(u32 instr) {
auto addr = Entry::Operand{ Entry::Operand::IMM_S64, u64(s64(s16(instr))) << 2 };
return addr;
}
void JIT::bltz(u32 instr) {
auto dst = branch(instr);
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
Entry e(Entry::BRANCH, dst.GetDst(), op1, Entry::BranchCond::LT, op2);
Entry e(Entry::BRANCH, dst, op1, Entry::BranchCond::LT, op2);
ir.push(e);
}
@@ -57,7 +54,7 @@ void JIT::bgez(u32 instr) {
auto dst = branch(instr);
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
Entry e(Entry::BRANCH, dst.GetDst(), op1, Entry::BranchCond::GE, op2);
Entry e(Entry::BRANCH, dst, op1, Entry::BranchCond::GE, op2);
ir.push(e);
}
@@ -66,7 +63,7 @@ void JIT::bltzl(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::LT, op2);
Entry e(opc, dst, op1, Entry::BranchCond::LT, op2);
ir.push(e);
}
@@ -75,7 +72,7 @@ void JIT::bgezl(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::GE, op2);
Entry e(opc, dst, op1, Entry::BranchCond::GE, op2);
ir.push(e);
}
@@ -84,7 +81,7 @@ void JIT::bltzal(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LINK);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::LT, op2);
Entry e(opc, dst, op1, Entry::BranchCond::LT, op2);
ir.push(e);
}
@@ -93,7 +90,7 @@ void JIT::bgezal(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LINK);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::GE, op2);
Entry e(opc, dst, op1, Entry::BranchCond::GE, op2);
ir.push(e);
}
@@ -102,7 +99,7 @@ void JIT::bltzall(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LINK | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::LT, op2);
Entry e(opc, dst, op1, Entry::BranchCond::LT, op2);
ir.push(e);
}
@@ -111,7 +108,7 @@ void JIT::bgezall(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_U64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LINK | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::GE, op2);
Entry e(opc, dst, op1, Entry::BranchCond::GE, op2);
ir.push(e);
}
@@ -119,7 +116,7 @@ void JIT::beq(u32 instr) {
auto dst = branch(instr);
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::REG_S64, u8(RT(instr)) };
Entry e(Entry::BRANCH, dst.GetDst(), op1, Entry::BranchCond::EQ, op2);
Entry e(Entry::BRANCH, dst, op1, Entry::BranchCond::EQ, op2);
ir.push(e);
}
@@ -127,7 +124,7 @@ void JIT::bne(u32 instr) {
auto dst = branch(instr);
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::REG_S64, u8(RT(instr)) };
Entry e(Entry::BRANCH, dst.GetDst(), op1, Entry::BranchCond::NE, op2);
Entry e(Entry::BRANCH, dst, op1, Entry::BranchCond::NE, op2);
ir.push(e);
}
@@ -135,7 +132,7 @@ void JIT::blez(u32 instr) {
auto dst = branch(instr);
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_S64, 0 };
Entry e(Entry::BRANCH, dst.GetDst(), op1, Entry::BranchCond::LE, op2);
Entry e(Entry::BRANCH, dst, op1, Entry::BranchCond::LE, op2);
ir.push(e);
}
@@ -143,7 +140,7 @@ void JIT::bgtz(u32 instr) {
auto dst = branch(instr);
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_S64, 0 };
Entry e(Entry::BRANCH, dst.GetDst(), op1, Entry::BranchCond::GT, op2);
Entry e(Entry::BRANCH, dst, op1, Entry::BranchCond::GT, op2);
ir.push(e);
}
@@ -152,7 +149,7 @@ void JIT::beql(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::REG_S64, u8(RT(instr)) };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::EQ, op2);
Entry e(opc, dst, op1, Entry::BranchCond::EQ, op2);
ir.push(e);
}
@@ -161,7 +158,7 @@ void JIT::bnel(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::REG_S64, u8(RT(instr)) };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::NE, op2);
Entry e(opc, dst, op1, Entry::BranchCond::NE, op2);
ir.push(e);
}
@@ -170,7 +167,7 @@ void JIT::blezl(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_S64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::LE, op2);
Entry e(opc, dst, op1, Entry::BranchCond::LE, op2);
ir.push(e);
}
@@ -179,7 +176,7 @@ void JIT::bgtzl(u32 instr) {
auto op1 = Entry::Operand{ Entry::Operand::REG_S64, u8(RS(instr)) };
auto op2 = Entry::Operand{ Entry::Operand::IMM_S64, 0 };
auto opc = Entry::Opcode(u16(Entry::BRANCH) | Entry::LIKELY);
Entry e(opc, dst.GetDst(), op1, Entry::BranchCond::GT, op2);
Entry e(opc, dst, op1, Entry::BranchCond::GT, op2);
ir.push(e);
}