diff options
Diffstat (limited to 'src/devices/cpu/powerpc/ppc_dasm.cpp')
-rw-r--r-- | src/devices/cpu/powerpc/ppc_dasm.cpp | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/src/devices/cpu/powerpc/ppc_dasm.cpp b/src/devices/cpu/powerpc/ppc_dasm.cpp index d43f00cbb21..85ed3914e3e 100644 --- a/src/devices/cpu/powerpc/ppc_dasm.cpp +++ b/src/devices/cpu/powerpc/ppc_dasm.cpp @@ -238,9 +238,9 @@ const powerpc_disassembler::IDESCR powerpc_disassembler::itab[] = { "oris", D_OP(25), M_RT|M_RA|M_UIMM, F_RA_RT_UIMM, 0, I_POWERPC }, { "oriu", D_OP(25), M_RT|M_RA|M_UIMM, F_RA_RT_UIMM, 0, I_POWER }, { "rac", D_OP(31)|D_XO(818), M_RT|M_RA|M_RB|M_RC, F_RT_RA_0_RB, FL_RC, I_POWER }, - { "rfi", D_OP(19)|D_XO(50), 0, F_NONE, 0, I_COMMON }, - { "rfci", D_OP(19)|D_XO(51), 0, F_NONE, 0, I_POWERPC }, - { "rfsvc", D_OP(19)|D_XO(82), M_LK, F_NONE, FL_LK, I_POWER }, + { "rfi", D_OP(19)|D_XO(50), 0, F_NONE, FL_SO, I_COMMON }, + { "rfci", D_OP(19)|D_XO(51), 0, F_NONE, FL_SO, I_POWERPC }, + { "rfsvc", D_OP(19)|D_XO(82), M_LK, F_NONE, FL_LK|FL_SO, I_POWER }, { "rlimi", D_OP(20), M_RT|M_RA|M_SH|M_MB|M_ME|M_RC, F_RA_RT_SH_MB_ME, FL_RC, I_POWER }, { "rlinm", D_OP(21), M_RT|M_RA|M_SH|M_MB|M_ME|M_RC, F_RA_RT_SH_MB_ME, FL_RC, I_POWER }, { "rlmi", D_OP(22), M_RT|M_RA|M_RB|M_MB|M_ME|M_RC, F_RA_RT_RB_MB_ME, FL_RC, I_POWER }, @@ -319,7 +319,7 @@ const powerpc_disassembler::IDESCR powerpc_disassembler::itab[] = { "subfic", D_OP(8), M_RT|M_RA|M_SIMM, F_RT_RA_SIMM, 0, I_POWERPC }, { "subfme", D_OP(31)|D_XO(232), M_RT|M_RA|M_OE|M_RC, F_RT_RA, FL_OE|FL_RC, I_POWERPC }, { "subfze", D_OP(31)|D_XO(200), M_RT|M_RA|M_OE|M_RC, F_RT_RA, FL_OE|FL_RC, I_POWERPC }, - { "svc", D_OP(17)|2, M_BD|M_AA|M_LK, F_NONE, FL_AA|FL_LK, I_POWER }, // TODO: operands + { "svc", D_OP(17)|2, M_BD|M_AA|M_LK, F_SC, FL_AA|FL_LK, I_POWER }, { "sync", D_OP(31)|D_XO(598), 0, F_NONE, 0, I_POWERPC }, { "t", D_OP(31)|D_XO(4), M_TO|M_RA|M_RB, F_TW, 0, I_POWER }, { "ti", D_OP(3), M_TO|M_RA|M_SIMM, F_TWI, 0, I_POWER }, @@ -559,8 +559,8 @@ std::string powerpc_disassembler::DecodeSigned16(uint32_t op, int do_unsigned) int16_t s; s = G_SIMM(op); - if (do_unsigned) // sign extend to unsigned 32-bits - return util::string_format("0x%04X", (uint32_t) s); + if (do_unsigned) + return util::string_format("0x%04X", (uint16_t) s); else // print as signed 16 bits { if (s < 0) @@ -593,7 +593,7 @@ uint32_t powerpc_disassembler::Mask(unsigned const mb, unsigned const me) * otherwise false to indicate disassembly should carry on as normal. */ -bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &signed16, std::string &mnem, std::string &oprs) +bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &signed16, std::string &mnem, std::string &oprs, offs_t &flags) { uint32_t value, disp; @@ -680,16 +680,20 @@ bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &si case 0x04: case 0x05: case 0x06: case 0x07: mnem += "b"; mnem += crnbit[G_BI(op) & 3]; + flags |= STEP_COND; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: mnem += "b"; mnem += crbit[G_BI(op) & 3]; + flags |= STEP_COND; break; case 0x10: case 0x11: case 0x18: case 0x19: mnem += "bdnz"; + flags |= STEP_COND; break; case 0x12: case 0x13: case 0x1a: case 0x1b: mnem += "bdz"; + flags |= STEP_COND; break; case 0x14: case 0x15: case 0x16: case 0x17: case 0x1c: case 0x1d: case 0x1e: case 0x1f: @@ -699,7 +703,11 @@ bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &si return false; } - if (op & M_LK) mnem += "l"; + if (op & M_LK) + { + mnem += "l"; + flags |= STEP_OVER; + } if (op & M_AA) mnem += "a"; if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0) @@ -714,16 +722,20 @@ bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &si case 0x04: case 0x05: case 0x06: case 0x07: mnem += "b"; mnem += crnbit[G_BI(op) & 3]; + flags |= STEP_COND; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: mnem += "b"; mnem += crbit[G_BI(op) & 3]; + flags |= STEP_COND; break; case 0x10: case 0x11: case 0x18: case 0x19: mnem += "bdnz"; + flags |= STEP_COND; break; case 0x12: case 0x13: case 0x1a: case 0x1b: mnem += "bdz"; + flags |= STEP_COND; break; case 0x14: case 0x15: case 0x16: case 0x17: case 0x1c: case 0x1d: case 0x1e: case 0x1f: @@ -733,8 +745,19 @@ bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &si return false; } - mnem += (G_XO(op) == 528) ? "ctr" : "lr"; - if (op & M_LK) mnem += "l"; + if (G_XO(op) == 528) + mnem += "ctr"; + else + { + mnem += "lr"; + if (!(op & M_LK)) + flags |= STEP_OUT; + } + if (op & M_LK) + { + mnem += "l"; + flags |= STEP_OVER; + } if (op & M_AA) mnem += "a"; if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0) @@ -777,7 +800,7 @@ offs_t powerpc_disassembler::dasm_one(std::ostream &stream, uint32_t pc, uint32_ * Try simplified forms first, then real instructions */ - if( Simplified(op, pc, signed16, mnem, oprs) ) { + if( Simplified(op, pc, signed16, mnem, oprs, flags) ) { util::stream_format(stream, "%s", mnem); for( j = mnem.size(); j < 10; j++ ) { util::stream_format(stream, " "); @@ -845,21 +868,19 @@ offs_t powerpc_disassembler::dasm_one(std::ostream &stream, uint32_t pc, uint32_ break; case F_LI: - disp = G_LI(op) * 4; - if (disp & 0x02000000) // sign extend - disp |= 0xfc000000; + disp = util::sext(G_LI(op) * 4, 26); oprs = util::string_format("0x%08X", disp + ((op & M_AA) ? 0 : pc)); break; case F_BCx: - disp = G_BD(op) * 4; - if (disp & 0x00008000) - disp |= 0xffff0000; + disp = util::sext(G_BD(op) * 4, 16); if (G_BO(op) & 0x10) // BI is ignored (don't print CR bit) oprs = util::string_format("0x%02X,%d,0x%08X", G_BO(op), G_BI(op), disp + ((op & M_AA) ? 0 : pc)); else // BI gives us the condition bit oprs = util::string_format("0x%02X,cr%d[%s],0x%08X", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3], disp + ((op & M_AA) ? 0 : pc)); + if ((G_BO(op) & 0x14) != 0x14) + flags |= STEP_COND; break; case F_BO_BI: @@ -867,6 +888,8 @@ offs_t powerpc_disassembler::dasm_one(std::ostream &stream, uint32_t pc, uint32_ oprs = util::string_format("0x%02X,%d", G_BO(op), G_BI(op)); else oprs = util::string_format("0x%02X,cr%d[%s]", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3]); + if ((G_BO(op) & 0x14) != 0x14) + flags |= STEP_COND; break; case F_CMP: @@ -1062,7 +1085,18 @@ offs_t powerpc_disassembler::dasm_one(std::ostream &stream, uint32_t pc, uint32_ oprs = util::string_format("%d,r%d,%s", G_TO(op), G_RA(op), signed16); break; + case F_SC: + if (op & M_AA) + oprs = util::string_format("0x%04X", (op & 0x0000fffc) >> 2); + else + oprs = util::string_format("%d,%d,%d", (op & 0x00000fe0) >> 5, (op & 0x0000f000) >> 12, (op & 0x0000001c) >> 2); + break; + case F_NONE: + if ((op >> 26) == 17) // SC (PowerPC) + flags |= STEP_OVER; + [[fallthrough]]; + default: break; } |