improve branch, doesn't need extra add in IR
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
} 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) {}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user