spu disasm: Show interrupts status modifiers on indirect branches

That's how the assembler represents it as well.
This commit is contained in:
Eladash 2019-10-15 09:33:39 +03:00 committed by Ivan
parent 7ca76ae5a8
commit 80b4ac23e5
2 changed files with 30 additions and 8 deletions

View file

@ -83,6 +83,17 @@ private:
return spu_branch_target(dump_pc, imm);
}
static const char* BrIndirectSuffix(u32 de)
{
switch (de)
{
case 0b01: return "e";
case 0b10: return "d";
//case 0b11: return "(undef)";
default: return "";
}
}
private:
std::string& FixOp(std::string& op)
{
@ -134,6 +145,16 @@ private:
Write(fmt::format("%s %s,%s,%s,%s", FixOp(op).c_str(), a1, a2, a3, a4));
}
using field_de_t = decltype(spu_opcode_t{}.de);
void DisAsm(std::string op, field_de_t de, const char* a1)
{
Write(fmt::format("%s%s %s", FixOp(op).c_str(), BrIndirectSuffix(de), a1));
}
void DisAsm(std::string op, field_de_t de, const char* a1, const char* a2)
{
Write(fmt::format("%s%s %s", FixOp(op).c_str(), BrIndirectSuffix(de), a1, a2));
}
public:
u32 disasm(u32 pc) override;
@ -288,19 +309,19 @@ public:
}
void BIZ(spu_opcode_t op)
{
DisAsm("biz", spu_reg_name[op.rt], spu_reg_name[op.ra]);
DisAsm("biz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]);
}
void BINZ(spu_opcode_t op)
{
DisAsm("binz", spu_reg_name[op.rt], spu_reg_name[op.ra]);
DisAsm("binz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]);
}
void BIHZ(spu_opcode_t op)
{
DisAsm("bihz", spu_reg_name[op.rt], spu_reg_name[op.ra]);
DisAsm("bihz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]);
}
void BIHNZ(spu_opcode_t op)
{
DisAsm("bihnz", spu_reg_name[op.rt], spu_reg_name[op.ra]);
DisAsm("bihnz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]);
}
void STOPD(spu_opcode_t op)
{
@ -312,19 +333,19 @@ public:
}
void BI(spu_opcode_t op)
{
DisAsm("bi", spu_reg_name[op.ra]);
DisAsm("bi", op.de, spu_reg_name[op.ra]);
}
void BISL(spu_opcode_t op)
{
DisAsm("bisl", spu_reg_name[op.rt], spu_reg_name[op.ra]);
DisAsm("bisl", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]);
}
void IRET(spu_opcode_t op)
{
DisAsm("iret", spu_reg_name[op.ra]);
DisAsm("iret", op.de, spu_reg_name[op.ra]);
}
void BISLED(spu_opcode_t op)
{
DisAsm("bisled", spu_reg_name[op.rt], spu_reg_name[op.ra]);
DisAsm("bisled", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]);
}
void HBR(spu_opcode_t op)
{

View file

@ -13,6 +13,7 @@ union spu_opcode_t
bf_t<u32, 21, 7> rt4; // 4..10, for 4-op instructions
bf_t<u32, 18, 1> e; // 13, "enable interrupts" bit
bf_t<u32, 19, 1> d; // 12, "disable interrupts" bit
bf_t<u32, 18, 2> de; // 12..13 combined 'e' and 'd' bits
bf_t<u32, 20, 1> c; // 11, "C" bit for SYNC instruction
bf_t<s32, 23, 2> r0h; // 7..8, signed
bf_t<s32, 14, 2> roh; // 16..17, signed