From fb3146744f218d188c58a7342d4aed0ef02c60f9 Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 27 Dec 2023 10:30:59 +0100 Subject: [PATCH] improve branch, doesn't need extra add in IR --- src/backend/core/JIT.hpp | 2 +- src/backend/core/JIT/IR.cpp | 47 ++++++++++++++++++++++----- src/backend/core/JIT/IR.hpp | 10 ++++-- src/backend/core/JIT/instructions.cpp | 41 +++++++++++------------ 4 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index 50497fda..fdbca9dc 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -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); diff --git a/src/backend/core/JIT/IR.cpp b/src/backend/core/JIT/IR.cpp index 513e29c9..6ec205b9 100644 --- a/src/backend/core/JIT/IR.cpp +++ b/src/backend/core/JIT/IR.cpp @@ -59,11 +59,13 @@ template <> struct fmt::formatter : formatter { 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 : formatter { } } + 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 : formatter { 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 : formatter { } } + 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 bc, Operand op2) - : op(op), bDest(bDest), op1(op1), branchCond(bc), op2(op2) {} +Entry::Entry(Opcode op, Operand bOffs, Operand op1, std::optional 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) {} diff --git a/src/backend/core/JIT/IR.hpp b/src/backend/core/JIT/IR.hpp index b0dea0ec..77408a00 100644 --- a/src/backend/core/JIT/IR.hpp +++ b/src/backend/core/JIT/IR.hpp @@ -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 index_or_imm = std::nullopt; Operand() = default; @@ -70,12 +74,12 @@ struct Entry { std::optional branchCond = std::nullopt; std::optional 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 bc, Operand op2); - Entry(Opcode op, Operand bDest); + Entry(Opcode op, Operand bOffs, Operand op1, std::optional bc, Operand op2); + Entry(Opcode op, Operand bOffs); Entry(Opcode op, Operand dst, Operand op1, Operand op2, Shift s); }; diff --git a/src/backend/core/JIT/instructions.cpp b/src/backend/core/JIT/instructions.cpp index 6c49eda2..96c93f80 100644 --- a/src/backend/core/JIT/instructions.cpp +++ b/src/backend/core/JIT/instructions.cpp @@ -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); }