diff options
| author | 2026-03-06 02:59:05 +1100 | |
|---|---|---|
| committer | 2026-03-06 02:59:05 +1100 | |
| commit | fee23037375166275937e15caf0b45f5de1cb3c7 (patch) | |
| tree | 9253e31804ecd5833999e7411ca38d9a3daa65be /src | |
| parent | e2dbc608c38558ee078d675c08fc91e9726beee0 (diff) | |
More stuff mostly related to recompiling CPUs:
cpu/drcbearm64.cpp: Don't set the rounding mode on SETFMOD if it hasn't
changed.
cpu/e132xs.cpp: Skip more unnecessary flag calculations, use
pre-calculated PC for updating G0 in memory when possible, better
analysis of pre-calculated PC values when delay slots are involved.
cpu/sh: Cleaned up register dependency analysis logging, fixed an
instruction analysis bug.
cpu/sharc: Disassemble unimplemented instructions executed in recompiled
code, include tag in more fatal errors, use throw syntax to make it
cleared it's an early out.
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/cpu/drcbearm64.cpp | 17 | ||||
| -rw-r--r-- | src/devices/cpu/e132xs/e132xsdrc.cpp | 20 | ||||
| -rw-r--r-- | src/devices/cpu/e132xs/e132xsdrc_ops.hxx | 134 | ||||
| -rw-r--r-- | src/devices/cpu/e132xs/e1fe.cpp | 62 | ||||
| -rw-r--r-- | src/devices/cpu/e132xs/e1fe.h | 11 | ||||
| -rw-r--r-- | src/devices/cpu/powerpc/ppcdrc.cpp | 13 | ||||
| -rw-r--r-- | src/devices/cpu/sh/sh.cpp | 93 | ||||
| -rw-r--r-- | src/devices/cpu/sh/sh.h | 3 | ||||
| -rw-r--r-- | src/devices/cpu/sh/sh_fe.cpp | 60 | ||||
| -rw-r--r-- | src/devices/cpu/sh/sh_fe.h | 32 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharc.cpp | 15 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharc.h | 4 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharc_dasm.cpp (renamed from src/devices/cpu/sharc/sharcdsm.cpp) | 95 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharc_dasm.h (renamed from src/devices/cpu/sharc/sharcdsm.h) | 80 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharcdrc.cpp | 9 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharcfe.cpp | 12 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharcops.hxx | 66 | ||||
| -rw-r--r-- | src/tools/unidasm.cpp | 2 |
18 files changed, 417 insertions, 311 deletions
diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp index 8e8f40052b0..2a9507cde10 100644 --- a/src/devices/cpu/drcbearm64.cpp +++ b/src/devices/cpu/drcbearm64.cpp @@ -1863,7 +1863,7 @@ void drcbe_arm64::op_handle(a64::Assembler &a, const uml::instruction &inst) a.bind(handle); // emit a jump around the stack adjust in case code falls through here - Label skip = a.new_label(); + Label const skip = a.new_label(); a.b(skip); // register the current pointer for the handle @@ -2319,9 +2319,9 @@ void drcbe_arm64::op_setfmod(a64::Assembler &a, const uml::instruction &inst) assert_no_flags(inst); be_parameter srcp(*this, inst.param(0), PTYPE_MRI); - const a64::Gp scratch = select_register(TEMP_REG1, inst.size()); + a64::Gp const scratch = select_register(TEMP_REG1, inst.size()); - emit_ldrb_mem(a, TEMP_REG2.w(), &m_near.nominal_fmod); + emit_ldrb_mem(a, TEMP_REG2.w(), &m_state.fmod); if (srcp.is_immediate()) { @@ -2329,20 +2329,29 @@ void drcbe_arm64::op_setfmod(a64::Assembler &a, const uml::instruction &inst) } else { - const a64::Gp src = srcp.select_register(scratch, inst.size()); + a64::Gp const src = srcp.select_register(scratch, inst.size()); mov_reg_param(a, inst.size(), src, srcp); a.and_(scratch, src, 3); } + Label const skip = a.new_label(); + a.cmp(TEMP_REG2.w(), scratch.w()); + a.b_eq(skip); + + emit_ldrb_mem(a, TEMP_REG2.w(), &m_near.nominal_fmod); emit_strb_mem(a, scratch.w(), &m_state.fmod); + a.cmp(TEMP_REG2.w(), scratch.w()); a.cset(TEMP_REG2.w(), a64::CondCode::kNE); emit_strb_mem(a, TEMP_REG2.w(), &m_near.fmod_changed); + a.mrs(TEMP_REG2, a64::Predicate::SysReg::kFPCR); a.sub(scratch.w(), scratch.w(), 1); a.bfi(TEMP_REG2, scratch.x(), 22, 2); a.msr(a64::Predicate::SysReg::kFPCR, TEMP_REG2); + + a.bind(skip); } void drcbe_arm64::op_getfmod(a64::Assembler &a, const uml::instruction &inst) diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp index b045b129cbe..b2b12bc1506 100644 --- a/src/devices/cpu/e132xs/e132xsdrc.cpp +++ b/src/devices/cpu/e132xs/e132xsdrc.cpp @@ -388,18 +388,20 @@ void hyperstone_device::log_descriptions(const opcode_desc *desc_list, unsigned else m_disassembler.disassemble_one(buffer, desc_list->pc, desc_list->opptr); buffer.put('\0'); - m_drcuml->log_printf("%-40s", &buffer.vec()[0]); + m_drcuml->log_printf( + (desc_list->regin.any() || desc_list->regout.any()) ? "%-40s" : "%s", + &buffer.vec()[0]); // output register dependencies buffer.clear(); buffer.seekp(0); - if (!desc_list->regin.none()) + if (desc_list->regin.any()) { desc_list->log_registers_used(buffer); - if (!desc_list->regout.none()) + if (desc_list->regout.any()) buffer << ' '; } - if (!desc_list->regout.none()) + if (desc_list->regout.any()) desc_list->log_registers_modified(buffer); buffer.put('\0'); m_drcuml->log_printf("%s\n", &buffer.vec()[0]); @@ -919,7 +921,10 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi UML_TEST(block, mem(&m_core->delay_slot), ~uint32_t(0)); UML_JMPc(block, uml::COND_NZ, set_delay_pc); - UML_ADD(block, DRC_PC, DRC_PC, desc->length); + if (desc->pc_value_unknown()) + UML_ADD(block, DRC_PC, DRC_PC, desc->length); + else + UML_MOV(block, DRC_PC, desc->pc_value()); UML_MOV(block, mem(&m_core->delay_slot_taken), 0); UML_JMP(block, done); @@ -931,7 +936,10 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi } else { - UML_ADD(block, DRC_PC, DRC_PC, desc->length); + if (desc->pc_value_unknown()) + UML_ADD(block, DRC_PC, DRC_PC, desc->length); + else + UML_MOV(block, DRC_PC, desc->pc_value()); UML_MOV(block, mem(&m_core->delay_slot_taken), 0); } diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx index 9f2d42b3ece..f1244440bde 100644 --- a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx +++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx @@ -665,8 +665,10 @@ inline void hyperstone_device::generate_logic_op(drcuml_block &block, compiler_s const uint32_t dst_code = (op & 0xf0) >> 4; const uint32_t src_code = op & 0xf; + const bool need_cond = (!DstGlobal || (dst_code != SR_REGISTER)) && (!DO_ELIDE_CONDITION_CALC || desc->z_calc_required()); - UML_MOV(block, I2, DRC_SR); + if (!SrcGlobal || !DstGlobal || need_cond) + UML_MOV(block, I2, DRC_SR); if (!SrcGlobal || !DstGlobal) UML_BFXU(block, I3, I2, FP_SHIFT, 7); @@ -684,9 +686,12 @@ inline void hyperstone_device::generate_logic_op(drcuml_block &block, compiler_s body(dst, src); - UML_SETc(block, uml::COND_Z, I1); - UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); - UML_MOV(block, DRC_SR, I2); + if (need_cond) + { + UML_SETc(block, uml::COND_Z, I1); + UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); + UML_MOV(block, DRC_SR, I2); + } if (!DstGlobal || (dst_code <= SR_REGISTER)) generate_set_dst(block, compiler, desc, DstGlobal, dst_code, dst, uml::I3, false); @@ -699,7 +704,10 @@ inline void hyperstone_device::generate_logic_op_imm(drcuml_block &block, compil // body should update dst and set Z flag // body must not clobber I2 or I3 - UML_MOV(block, I2, DRC_SR); + const bool need_cond = (!DstGlobal || (dst_code != SR_REGISTER)) && (!DO_ELIDE_CONDITION_CALC || desc->z_calc_required()); + + if (!DstGlobal || need_cond) + UML_MOV(block, I2, DRC_SR); if (!DstGlobal) UML_BFXU(block, I3, I2, FP_SHIFT, 7); @@ -714,9 +722,12 @@ inline void hyperstone_device::generate_logic_op_imm(drcuml_block &block, compil body(uml::mem(&m_core->global_regs[dst_code])); } - UML_SETc(block, uml::COND_Z, I1); - UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); - UML_MOV(block, DRC_SR, I2); + if (need_cond) + { + UML_SETc(block, uml::COND_Z, I1); + UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); + UML_MOV(block, DRC_SR, I2); + } if (!DstGlobal || (dst_code <= SR_REGISTER)) generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, false); @@ -1076,12 +1087,27 @@ void hyperstone_device::generate_divsu(drcuml_block &block, compiler_state &comp else UML_DDIVU(block, I2, I4, I1, I0); - UML_AND(block, I3, DRC_SR, ~(V_MASK | Z_MASK | N_MASK)); - UML_TEST(block, I2, ~uint32_t(0)); - UML_SETc(block, uml::COND_Z, I0); - UML_SHL(block, I0, I0, Z_SHIFT); - UML_ROLINS(block, I0, I2, N_SHIFT + 1, N_MASK); - UML_OR(block, DRC_SR, I3, I0); + if (!DO_ELIDE_CONDITION_CALC || desc->z_calc_required() || desc->n_calc_required()) + { + UML_AND(block, I3, DRC_SR, ~(V_MASK | Z_MASK | N_MASK)); + if (!DO_ELIDE_CONDITION_CALC || desc->z_calc_required()) + { + UML_TEST(block, I2, ~uint32_t(0)); + UML_SETc(block, uml::COND_Z, I0); + UML_SHL(block, I0, I0, Z_SHIFT); + if (!DO_ELIDE_CONDITION_CALC || desc->n_calc_required()) + UML_ROLINS(block, I0, I2, N_SHIFT + 1, N_MASK); + } + else if (desc->n_calc_required()) + { + UML_ROLAND(block, I0, I2, N_SHIFT + 1, N_MASK); + } + UML_OR(block, DRC_SR, I3, I0); + } + else if (desc->v_calc_required()) + { + UML_AND(block, DRC_SR, DRC_SR, ~(V_MASK | Z_MASK | N_MASK)); + } if (DstGlobal) { @@ -1097,6 +1123,7 @@ void hyperstone_device::generate_divsu(drcuml_block &block, compiler_state &comp UML_JMP(block, done); UML_LABEL(block, no_result); + UML_OR(block, DRC_SR, DRC_SR, V_MASK); generate_raise_exception(block, compiler, desc, TRAPNO_RANGE_ERROR); UML_LABEL(block, done); @@ -1160,17 +1187,22 @@ void hyperstone_device::generate_mask(drcuml_block &block, compiler_state &compi const uint32_t src_code = op & 0xf; const uint32_t dst_code = (op & 0xf0) >> 4; const uint32_t src = desc->imm; + const bool need_cond = (!DstGlobal || (dst_code != SR_REGISTER)) && (!DO_ELIDE_CONDITION_CALC || desc->z_calc_required()); - UML_MOV(block, I2, DRC_SR); + if (!SrcGlobal || !DstGlobal || need_cond) + UML_MOV(block, I2, DRC_SR); if (!SrcGlobal || !DstGlobal) UML_BFXU(block, I3, I2, FP_SHIFT, 7); generate_load_operand(block, compiler, SrcGlobal, src_code, uml::I0, uml::I0); UML_AND(block, I0, I0, src); - UML_SETc(block, uml::COND_Z, I1); - UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); - UML_MOV(block, DRC_SR, I2); + if (need_cond) + { + UML_SETc(block, uml::COND_Z, I1); + UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); + UML_MOV(block, DRC_SR, I2); + } generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, true); } @@ -1185,22 +1217,25 @@ void hyperstone_device::generate_sum(drcuml_block &block, compiler_state &compil const uint32_t src_code = op & 0xf; const uint32_t dst_code = (op & 0xf0) >> 4; const uint32_t src = desc->imm; + const bool need_cond = (!DstGlobal || (dst_code != SR_REGISTER)) && (!DO_ELIDE_CONDITION_CALC || desc->condition_calc_required()); - UML_MOV(block, I2, DRC_SR); + if (!SrcGlobal || !DstGlobal || need_cond) + UML_MOV(block, I2, DRC_SR); if (!SrcGlobal || !DstGlobal) UML_BFXU(block, I3, I2, FP_SHIFT, 7); if (SrcGlobal && (src_code == PC_REGISTER) && (desc->in_delay_slot() || !compiler.check_delay())) { const uint64_t result = uint64_t(compiler.pc()) + src; - const uint32_t flags = - (BIT(result, 32) << C_SHIFT) | - (!uint32_t(result) ? Z_MASK : 0) | - (BIT(result, 31) << N_SHIFT) | - (BIT((compiler.pc() ^ result) & (src ^ result), 31) << V_SHIFT); - if (!DO_ELIDE_CONDITION_CALC || desc->condition_calc_required()) + if (need_cond) { + const uint32_t flags = + (BIT(result, 32) << C_SHIFT) | + (!uint32_t(result) ? Z_MASK : 0) | + (BIT(result, 31) << N_SHIFT) | + (BIT((compiler.pc() ^ result) & (src ^ result), 31) << V_SHIFT); + UML_ROLINS(block, I2, flags, 0, V_MASK | N_MASK | Z_MASK | C_MASK); UML_MOV(block, DRC_SR, I2); } @@ -1213,7 +1248,7 @@ void hyperstone_device::generate_sum(drcuml_block &block, compiler_state &compil UML_ADD(block, I0, I0, src); - if (!DO_ELIDE_CONDITION_CALC || desc->condition_calc_required()) + if (need_cond) { generate_update_flags_addsub(block, compiler, desc, uml::I2); UML_MOV(block, DRC_SR, I2); @@ -1272,6 +1307,9 @@ void hyperstone_device::generate_cmp(drcuml_block &block, compiler_state &compil { UML_MOV(block, I7, mem(&m_core->clock_cycles_1)); + if (DO_ELIDE_CONDITION_CALC && !desc->condition_calc_required()) + return; + const uint16_t op = desc->opptr[0]; const uint32_t src_code = op & 0xf; const uint32_t dst_code = (op & 0xf0) >> 4; @@ -1285,11 +1323,8 @@ void hyperstone_device::generate_cmp(drcuml_block &block, compiler_state &compil UML_CMP(block, I0, I1); - if (!DO_ELIDE_CONDITION_CALC || desc->condition_calc_required()) - { - generate_update_flags_cmp(block, compiler, desc, uml::I2); - UML_MOV(block, DRC_SR, I2); - } + generate_update_flags_cmp(block, compiler, desc, uml::I2); + UML_MOV(block, DRC_SR, I2); } template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal> @@ -1300,12 +1335,13 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil const uint16_t op = desc->opptr[0]; const uint32_t src_code = op & 0xf; const uint32_t dst_code = (op & 0xf0) >> 4; + const bool check_h = desc->check_h() || desc->is_branch_target(); UML_MOV(block, I2, DRC_SR); if (!SrcGlobal || !DstGlobal) UML_BFXU(block, I3, I2, FP_SHIFT, 7); - if (DstGlobal && compiler.user_mode()) + if (DstGlobal && check_h && compiler.user_mode()) { const int no_exception = compiler.next_label(); UML_TEST(block, I2, H_MASK); @@ -1318,7 +1354,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil if (SrcGlobal) { - if (!DstGlobal || compiler.supervisor_mode()) + if (check_h && (!DstGlobal || compiler.supervisor_mode())) { const int highglobal = compiler.next_label(); const int done = compiler.next_label(); @@ -1360,7 +1396,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil if (DstGlobal) { - if (compiler.supervisor_mode()) + if (check_h && compiler.supervisor_mode()) { const int highglobal = compiler.next_label(); const int done = compiler.next_label(); @@ -1549,6 +1585,9 @@ void hyperstone_device::generate_cmpb(drcuml_block &block, compiler_state &compi { UML_MOV(block, I7, mem(&m_core->clock_cycles_1)); + if (DO_ELIDE_CONDITION_CALC && !desc->z_calc_required()) + return; + const uint16_t op = desc->opptr[0]; const uint32_t src_code = op & 0xf; const uint32_t dst_code = (op & 0xf0) >> 4; @@ -1852,9 +1891,12 @@ void hyperstone_device::generate_not(drcuml_block &block, compiler_state &compil generate_load_operand(block, compiler, SrcGlobal, src_code, uml::I0, uml::I0); UML_XOR(block, I0, I0, ~uint32_t(0)); - UML_SETc(block, uml::COND_Z, I1); - UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); - UML_MOV(block, DRC_SR, I2); + if (!DO_ELIDE_CONDITION_CALC || desc->z_calc_required()) + { + UML_SETc(block, uml::COND_Z, I1); + UML_ROLINS(block, I2, I1, Z_SHIFT, Z_MASK); + UML_MOV(block, DRC_SR, I2); + } generate_set_dst(block, compiler, desc, DstGlobal, dst_code, uml::I0, uml::I3, true); } @@ -1865,6 +1907,9 @@ void hyperstone_device::generate_cmpi(drcuml_block &block, compiler_state &compi { UML_MOV(block, I7, mem(&m_core->clock_cycles_1)); + if (DO_ELIDE_CONDITION_CALC && !desc->condition_calc_required()) + return; + const uint16_t op = desc->opptr[0]; const uint32_t dst_code = (op & 0xf0) >> 4; const uint32_t src = ImmLong ? desc->imm : (op & 0x0f); @@ -1877,11 +1922,8 @@ void hyperstone_device::generate_cmpi(drcuml_block &block, compiler_state &compi UML_CMP(block, I0, src); - if (!DO_ELIDE_CONDITION_CALC || desc->condition_calc_required()) - { - generate_update_flags_cmp(block, compiler, desc, uml::I2); - UML_MOV(block, DRC_SR, I2); - } + generate_update_flags_cmp(block, compiler, desc, uml::I2); + UML_MOV(block, DRC_SR, I2); } @@ -1893,10 +1935,11 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi const uint16_t op = desc->opptr[0]; const uint32_t dst_code = (op & 0xf0) >> 4; const uint32_t src = ImmLong ? desc->imm : (op & 0x0f); + const bool check_h = desc->check_h() || desc->is_branch_target(); UML_MOV(block, I2, DRC_SR); - if (DstGlobal && compiler.user_mode()) + if (check_h && DstGlobal && compiler.user_mode()) { const int no_exception = compiler.next_label(); UML_TEST(block, I2, H_MASK); @@ -1913,7 +1956,7 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi if (DstGlobal) { - if (compiler.supervisor_mode()) + if (check_h && compiler.supervisor_mode()) { const int highglobal = compiler.next_label(); const int done = compiler.next_label(); @@ -2048,6 +2091,9 @@ void hyperstone_device::generate_cmpbi(drcuml_block &block, compiler_state &comp { UML_MOV(block, I7, mem(&m_core->clock_cycles_1)); + if (DO_ELIDE_CONDITION_CALC && !desc->z_calc_required()) + return; + const uint16_t op = desc->opptr[0]; const uint32_t dst_code = (op & 0xf0) >> 4; const uint32_t n = ((op & 0x100) >> 4) | (op & 0x0f); diff --git a/src/devices/cpu/e132xs/e1fe.cpp b/src/devices/cpu/e132xs/e1fe.cpp index 55859b96750..7a397185317 100644 --- a/src/devices/cpu/e132xs/e1fe.cpp +++ b/src/devices/cpu/e132xs/e1fe.cpp @@ -439,10 +439,10 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_z_modified(); if (desc.dst_is_pc()) { - if (!desc.src_is_pc()) + if (!desc.src_is_pc() || desc.pc_value_unknown()) desc.targetpc = BRANCH_TARGET_DYNAMIC; else - desc.targetpc = (desc.pc + desc.length) & desc.imm; + desc.targetpc = desc.pc_value() & desc.imm; desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -472,10 +472,10 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_cznv_modified(); // sum if (desc.dst_is_pc()) { - if (!desc.src_is_pc()) + if (!desc.src_is_pc() || desc.pc_value_unknown()) desc.targetpc = BRANCH_TARGET_DYNAMIC; else - desc.targetpc = ((desc.pc + desc.length) + desc.imm) & ~uint32_t(1); + desc.targetpc = (desc.pc_value() + desc.imm) & ~uint32_t(1); desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -529,11 +529,11 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_g_modified(desc.dst_code + 16); if (desc.dst_code == PC_REGISTER) { - if (!desc.src_is_pc()) + if (!desc.src_is_pc() || desc.pc_value_unknown()) desc.targetpc = BRANCH_TARGET_DYNAMIC; else - desc.targetpc = desc.pc + desc.length; - desc.set_is_conditional_branch(); // technically it won't branch if H is clear + desc.targetpc = desc.pc_value(); + desc.set_is_conditional_branch(); // technically it won't branch if H is set desc.set_end_sequence(); } else if (desc.dst_code == 5) // TPR_REGISTER & 0xf @@ -576,10 +576,12 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc { if (!desc.src_is_pc()) desc.targetpc = BRANCH_TARGET_DYNAMIC; - else if ((op & 0xf800) == 0x2800) - desc.targetpc = (desc.pc + desc.length) << 1; // add, adds - else + else if ((op & 0xf800) == 0x4800) desc.targetpc = 0; // sub, subs + else if (!desc.pc_value_unknown()) + desc.targetpc = desc.pc_value() << 1; // add, adds + else + desc.targetpc = BRANCH_TARGET_DYNAMIC; desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -620,8 +622,10 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.targetpc = BRANCH_TARGET_DYNAMIC; else if ((op & 0xf400) == 0x3400) desc.targetpc = 0; // andn, xor + else if (!desc.pc_value_unknown()) + desc.targetpc = desc.pc_value(); // or, and else - desc.targetpc = desc.pc + desc.length; // or, and + desc.targetpc = BRANCH_TARGET_DYNAMIC; desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -648,10 +652,10 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_g_modified(desc.dst_code); if (desc.dst_code == PC_REGISTER) { - if (!desc.src_is_sr() || ((op & 0xfc00) == 0x4000)) + if (!desc.src_is_sr() || desc.pc_value_unknown() || ((op & 0xfc00) == 0x4000)) desc.targetpc = BRANCH_TARGET_DYNAMIC; else - desc.targetpc = desc.pc + desc.length; + desc.targetpc = desc.pc_value(); desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -684,12 +688,12 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_g_modified(desc.dst_code); if (desc.dst_code == PC_REGISTER) { - if (!desc.src_is_pc()) + if (!desc.src_is_pc() || desc.pc_value_unknown()) desc.targetpc = BRANCH_TARGET_DYNAMIC; else if ((op & 0xfc00) == 0x4400) - desc.targetpc = ~(desc.pc + desc.length) & ~uint32_t(1); // not + desc.targetpc = ~desc.pc_value() & ~uint32_t(1); // not else - desc.targetpc = uint32_t(-int32_t(desc.pc + desc.length)) & ~uint32_t(1); // neg, negs + desc.targetpc = uint32_t(-int32_t(desc.pc_value())) & ~uint32_t(1); // neg, negs desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -768,7 +772,10 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_g_modified(desc.dst_code); if (desc.dst_code == PC_REGISTER) { - desc.targetpc = (desc.pc + desc.length + desc.imm) & ~uint32_t(1); + if (desc.pc_value_unknown()) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else + desc.targetpc = (desc.pc_value() + desc.imm) & ~uint32_t(1); desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -789,12 +796,14 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_g_modified(desc.dst_code); if (desc.dst_code == PC_REGISTER) { - if (!(op & 0x0800)) - desc.targetpc = (desc.pc + desc.length) & ~desc.imm; // andni + if (desc.pc_value_unknown()) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else if (!(op & 0x0800)) + desc.targetpc = desc.pc_value() & ~desc.imm; // andni else if (!(op & 0x0400)) - desc.targetpc = ((desc.pc + desc.length) | desc.imm) & ~uint32_t(1); // ori + desc.targetpc = (desc.pc_value() | desc.imm) & ~uint32_t(1); // ori else - desc.targetpc = ((desc.pc + desc.length) ^ desc.imm) & ~uint32_t(1); // xori + desc.targetpc = (desc.pc_value() ^ desc.imm) & ~uint32_t(1); // xori desc.set_is_unconditional_branch(); desc.set_end_sequence(); } @@ -1075,7 +1084,10 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc if ((op & 0x0f00) != 0x0c00) desc.set_is_conditional_branch(); desc.delayslots = (op & 0x1000) ? 0 : 1; - desc.targetpc = desc.pc + desc.length + desc.imm; + if (desc.pc_value_unknown()) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else + desc.targetpc = desc.pc_value() + desc.imm; break; case 0xed: // frame desc.set_can_cause_exception(); @@ -1094,10 +1106,10 @@ bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc desc.set_g_used(desc.src_code); desc.set_g_used(PC_REGISTER); desc.set_g_used(SR_REGISTER); - if (desc.src_is_pc()) - desc.targetpc = (desc.pc + desc.length + desc.imm) & ~uint32_t(1); - else if (desc.src_is_sr()) + if (desc.src_is_sr()) desc.targetpc = desc.imm & ~uint32_t(1); + else if (desc.src_is_pc() && !desc.pc_value_unknown()) + desc.targetpc = (desc.pc_value() + desc.imm) & ~uint32_t(1); else desc.targetpc = BRANCH_TARGET_DYNAMIC; desc.set_is_unconditional_branch(); diff --git a/src/devices/cpu/e132xs/e1fe.h b/src/devices/cpu/e132xs/e1fe.h index 97354a950f2..d1a00c018d9 100644 --- a/src/devices/cpu/e132xs/e1fe.h +++ b/src/devices/cpu/e132xs/e1fe.h @@ -129,6 +129,17 @@ public: return in_delay_slot() ? branch->pc : pc; } + // pc_value - value of PC when used for arithmetic + uint32_t pc_value() const + { + return in_delay_slot() ? branch->targetpc : (pc + length); + } + + bool pc_value_unknown() const + { + return in_delay_slot() && (branch->targetpc == BRANCH_TARGET_DYNAMIC); + } + void reset(offs_t curpc, bool in_delay_slot) { static_assert(REG_COUNT <= 40); diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index ee0c9b664bc..66a99cc2bda 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -3914,8 +3914,9 @@ void ppc_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32 if (m_drcuml->logging()) { std::ostringstream stream; + stream.imbue(std::locale::classic()); m_dasm.dasm_one(stream, pc, op); - block.append_comment("%08X: %s", pc, stream.str()); // comment + block.append_comment("%08X: %s", pc, std::move(stream).str()); } } @@ -3950,18 +3951,20 @@ void ppc_device::log_opcode_desc(const opcode_desc *desclist, int indent) else m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr); buffer.put('\0'); - m_drcuml->log_printf("%-30s", &buffer.vec()[0]); + m_drcuml->log_printf( + (desclist->regin.any() || desclist->regout.any()) ? "%-30s" : "%s", + &buffer.vec()[0]); // output register dependencies buffer.clear(); buffer.seekp(0); - if (!desclist->regin.none()) + if (desclist->regin.any()) { desclist->log_registers_used(buffer); - if (!desclist->regout.none()) + if (desclist->regout.any()) buffer << ' '; } - if (!desclist->regout.none()) + if (desclist->regout.any()) desclist->log_registers_modified(buffer); buffer.put('\0'); m_drcuml->log_printf("%s\n", &buffer.vec()[0]); diff --git a/src/devices/cpu/sh/sh.cpp b/src/devices/cpu/sh/sh.cpp index 72945b2e364..99a674fd91f 100644 --- a/src/devices/cpu/sh/sh.cpp +++ b/src/devices/cpu/sh/sh.cpp @@ -2033,75 +2033,6 @@ void sh_common_execution::save_fast_iregs(drcuml_block &block) /*------------------------------------------------- - log_register_list - log a list of GPR registers --------------------------------------------------*/ - -void sh_common_execution::log_register_list(const char *string, const std::bitset<32> ®list, const std::bitset<32> *regnostarlist) -{ - int count = 0; - - /* skip if nothing */ - if (reglist.none()) - return; - - m_drcuml->log_printf("[%s:", string); - - for (int regnum = 0; regnum < 16; regnum++) - { - if (reglist[opcode_desc::REG_R0 + regnum]) - { - m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); - if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_R0 + regnum]) - m_drcuml->log_printf("*"); - } - } - - if (reglist[opcode_desc::REG_PR]) - { - m_drcuml->log_printf("%spr", (count++ == 0) ? "" : ","); - if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_PR]) - m_drcuml->log_printf("*"); - } - - if (reglist[opcode_desc::REG_SR]) - { - m_drcuml->log_printf("%ssr", (count++ == 0) ? "" : ","); - if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_SR]) - m_drcuml->log_printf("*"); - } - - if (reglist[opcode_desc::REG_MACL]) - { - m_drcuml->log_printf("%smacl", (count++ == 0) ? "" : ","); - if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_MACL]) - m_drcuml->log_printf("*"); - } - - if (reglist[opcode_desc::REG_MACH]) - { - m_drcuml->log_printf("%smach", (count++ == 0) ? "" : ","); - if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_MACH]) - m_drcuml->log_printf("*"); - } - - if (reglist[opcode_desc::REG_GBR]) - { - m_drcuml->log_printf("%sgbr", (count++ == 0) ? "" : ","); - if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_GBR]) - m_drcuml->log_printf("*"); - } - - if (reglist[opcode_desc::REG_VBR]) - { - m_drcuml->log_printf("%svbr", (count++ == 0) ? "" : ","); - if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_VBR]) - m_drcuml->log_printf("*"); - } - - m_drcuml->log_printf("] "); -} - -/*------------------------------------------------- log_opcode_desc - log a list of descriptions -------------------------------------------------*/ @@ -2124,20 +2055,32 @@ void sh_common_execution::log_opcode_desc(const opcode_desc *desclist, int inden buffer.put('\0'); m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: ", desclist->pc, desclist->physpc, desclist->targetpc, &buffer.vec()[0]); - /* disassemle the current instruction and output it to the log */ + /* disassemble the current instruction and output it to the log */ buffer.clear(); buffer.seekp(0); + util::stream_format(buffer, "%*s", 4 * indent, ""); if (desclist->virtual_noop()) buffer << "<virtual nop>"; else sh2d.dasm_one(buffer, desclist->pc, desclist->opptr); buffer.put('\0'); - m_drcuml->log_printf("%-36s", &buffer.vec()[0]); + m_drcuml->log_printf( + (desclist->regin.any() || desclist->regout.any()) ? "%-36s" : "%s", + &buffer.vec()[0]); - /* output register states */ - log_register_list("use", desclist->regin, nullptr); - log_register_list("mod", desclist->regout, &desclist->regreq); - m_drcuml->log_printf("\n"); + /* output register dependencies */ + buffer.clear(); + buffer.seekp(0); + if (desclist->regin.any()) + { + desclist->log_registers_used(buffer); + if (desclist->regout.any()) + buffer << ' '; + } + if (desclist->regout.any()) + desclist->log_registers_modified(buffer); + buffer.put('\0'); + m_drcuml->log_printf("%s\n", &buffer.vec()[0]); /* if we have a delay slot, output it recursively */ if (desclist->delay.first() != nullptr) diff --git a/src/devices/cpu/sh/sh.h b/src/devices/cpu/sh/sh.h index c06fbeddf10..fbf5e2a93f8 100644 --- a/src/devices/cpu/sh/sh.h +++ b/src/devices/cpu/sh/sh.h @@ -8,8 +8,6 @@ #include "cpu/drcuml.h" -#include <bitset> - /*************************************************************************** DEBUGGING @@ -443,7 +441,6 @@ public: void alloc_handle(uml::code_handle *&handleptr, const char *name); void load_fast_iregs(drcuml_block &block); void save_fast_iregs(drcuml_block &block); - void log_register_list(const char *string, const std::bitset<32> ®list, const std::bitset<32> *regnostarlist); void log_opcode_desc(const opcode_desc *desclist, int indent); void log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op); void generate_delay_slot(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t ovrpc); diff --git a/src/devices/cpu/sh/sh_fe.cpp b/src/devices/cpu/sh/sh_fe.cpp index 0716231aef7..a557109f7b7 100644 --- a/src/devices/cpu/sh/sh_fe.cpp +++ b/src/devices/cpu/sh/sh_fe.cpp @@ -63,6 +63,62 @@ void sh_common_execution::opcode_desc::log_flags(std::ostream &stream) const } +/*------------------------------------------------- + log_register_list - log a list of registers +-------------------------------------------------*/ + +void sh_common_execution::opcode_desc::log_registers_used(std::ostream &stream) const +{ + stream << "[use:"; + log_register_list(stream, regin, nullptr); + stream << ']'; +} + +void sh_common_execution::opcode_desc::log_registers_modified(std::ostream &stream) const +{ + stream << "[mod:"; + log_register_list(stream, regout, ®req); + stream << ']'; +} + +void sh_common_execution::opcode_desc::log_register_list(std::ostream &stream, const regmask ®list, const regmask *regnostarlist) +{ + int count = 0; + + for (int regnum = 0; regnum < 16; regnum++) + { + if (reglist[REG_R0 + regnum]) + { + if (count++) + stream << ','; + stream << 'r' << regnum; + if (regnostarlist && !(*regnostarlist)[REG_R0 + regnum]) + stream << '*'; + } + } + + const auto log_bit = + [&stream, &count, ®list, ®nostarlist] (size_t bit, const char *name) + { + if (reglist[bit]) + { + if (count++) + stream << ','; + stream << name; + if (regnostarlist && !(*regnostarlist)[bit]) + stream << '*'; + } + }; + + log_bit(REG_PR, "pr"); + log_bit(REG_SR, "sr"); + log_bit(REG_MACL, "macl"); + log_bit(REG_MACH, "mach"); + log_bit(REG_GBR, "gbr"); + log_bit(REG_VBR, "vbr"); +} + + /*************************************************************************** INSTRUCTION PARSERS @@ -313,7 +369,7 @@ bool sh_common_execution::frontend::describe_group_6(opcode_desc &desc, const op case 5: // MOVWP(Rm, Rn); case 6: // MOVLP(Rm, Rn); desc.set_r_used(REG_M); - desc.set_r_used(REG_N); + desc.set_r_modified(REG_M); desc.set_r_modified(REG_N); desc.set_reads_memory(); return true; @@ -631,7 +687,7 @@ bool sh_common_execution::frontend::describe_group_0(opcode_desc &desc, const op bool sh_common_execution::frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) { - switch (opcode & 0x3F) + switch (opcode & 0x3f) { case 0x00: // SHLL(Rn); case 0x01: // SHLR(Rn); diff --git a/src/devices/cpu/sh/sh_fe.h b/src/devices/cpu/sh/sh_fe.h index ba63138e3eb..266dc4f2821 100644 --- a/src/devices/cpu/sh/sh_fe.h +++ b/src/devices/cpu/sh/sh_fe.h @@ -23,20 +23,6 @@ class sh_common_execution::opcode_desc : public opcode_desc_base<opcode_desc, 32> { public: - enum - { - REG_R0 = 0, - - REG_PR = REG_R0 + 16, - REG_SR, - REG_MACL, - REG_MACH, - REG_GBR, - REG_VBR, - - REG_COUNT - }; - offs_t physpc; // physical PC of this opcode uint16_t opptr; // copy of opcode @@ -87,8 +73,26 @@ public: } void log_flags(std::ostream &stream) const; + void log_registers_used(std::ostream &stream) const; + void log_registers_modified(std::ostream &stream) const; private: + enum + { + REG_R0 = 0, + + REG_PR = REG_R0 + 16, + REG_SR, + REG_MACL, + REG_MACH, + REG_GBR, + REG_VBR, + + REG_COUNT + }; + + static void log_register_list(std::ostream &stream, const regmask ®list, const regmask *regnostarlist); + bool m_reads_memory; bool m_writes_memory; bool m_can_expose_external_int; diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp index a7466fd012f..0b11008ed99 100644 --- a/src/devices/cpu/sharc/sharc.cpp +++ b/src/devices/cpu/sharc/sharc.cpp @@ -8,7 +8,7 @@ #include "emu.h" #include "sharc.h" -#include "sharcdsm.h" +#include "sharc_dasm.h" #include "sharcfe.h" #include "sharcinternal.ipp" @@ -18,6 +18,8 @@ #include <algorithm> #include <cstdio> +#include <locale> +#include <sstream> //#define VERBOSE 1 #include "logmacro.h" @@ -67,6 +69,17 @@ enum DEFINE_DEVICE_TYPE(ADSP21062, adsp21062_device, "adsp21062", "Analog Devices ADSP21062 \"SHARC\"") DEFINE_DEVICE_TYPE(ADSP21060, adsp21060_device, "adsp21060", "Analog Devices ADSP21060 \"SHARC\"") + +std::string adsp21062_device::disassemble_one(uint32_t pc, uint64_t opcode) +{ + // expensive - don't use this frequently + std::ostringstream stream; + stream.imbue(std::locale::classic()); + sharc_disassembler().disassemble_one(stream, pc, opcode); + return std::move(stream).str(); +} + + void adsp21062_device::pgm_2m(address_map &map) { map(0x20000, 0x24fff).mirror(0x18000).rw(FUNC(adsp21062_device::pm_r<1>), FUNC(adsp21062_device::pm_w<1>)); diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h index 0094437238f..0e685452a5f 100644 --- a/src/devices/cpu/sharc/sharc.h +++ b/src/devices/cpu/sharc/sharc.h @@ -300,6 +300,9 @@ private: bool m_input_update_pending; bool m_enable_drc; + static std::string disassemble_one(uint32_t pc, uint64_t opcode); + void build_opcode_table(); + TIMER_CALLBACK_MEMBER(sharc_iop_delayed_write_callback); TIMER_CALLBACK_MEMBER(sharc_dma_callback); TIMER_CALLBACK_MEMBER(sharc_update_inputs); @@ -434,7 +437,6 @@ private: inline void compute_fmul_fmax(int fm, int fxm, int fym, int fa, int fxa, int fya); inline void compute_fmul_fmin(int fm, int fxm, int fym, int fa, int fxa, int fya); inline void compute_fmul_dual_fadd_fsub(int fm, int fxm, int fym, int fa, int fs, int fxa, int fya); - void build_opcode_table(); // internal compiler state struct compiler_state diff --git a/src/devices/cpu/sharc/sharcdsm.cpp b/src/devices/cpu/sharc/sharc_dasm.cpp index f215e8816b9..e316ab8162e 100644 --- a/src/devices/cpu/sharc/sharcdsm.cpp +++ b/src/devices/cpu/sharc/sharc_dasm.cpp @@ -7,12 +7,14 @@ */ #include "emu.h" -#include "sharcdsm.h" +#include "sharc_dasm.h" #include <stdexcept> -const char sharc_disassembler::ureg_names[256][16] = +namespace { + +const char ureg_names[256][16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", @@ -48,12 +50,12 @@ const char sharc_disassembler::ureg_names[256][16] = "???", "???", "???", "???", "???", "???", "???", "???" }; -const char sharc_disassembler::bopnames[8][8] = +const char bopnames[8][8] = { "SET", "CLEAR", "TOGGLE", "???", "TEST", "XOR", "???", "???" }; -const char sharc_disassembler::condition_codes_if[32][32] = +const char condition_codes_if[32][32] = { "EQ", "LT", "LE", "AC", "AV", "MV", "MS", "SV", @@ -65,7 +67,7 @@ const char sharc_disassembler::condition_codes_if[32][32] = "NOT FLAG3_IN", "NOT TF", "NBM", "" }; -const char sharc_disassembler::condition_codes_do[32][32] = +const char condition_codes_do[32][32] = { "EQ", "LT", "LE", "AC", "AV", "MV", "MS", "SV", @@ -77,7 +79,7 @@ const char sharc_disassembler::condition_codes_do[32][32] = "NOT FLAG3_IN", "NOT TF", "NBM", "FOREVER" }; -const char sharc_disassembler::mr_regnames[16][8] = +const char mr_regnames[16][8] = { "MR0F", "MR1F", "MR2F", "MR0B", "MR1B", "MR2B", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???" @@ -95,8 +97,10 @@ const char sharc_disassembler::mr_regnames[16][8] = #define GET_DAG2_L(x) (GET_UREG(0x30 | (8 + (x & 0x7)))) #define GET_DAG2_B(x) (GET_UREG(0x40 | (8 + (x & 0x7)))) +} // anonymous namespace + -void sharc_disassembler::compute(std::ostream &stream, uint32_t opcode) +void sharc_disassembler::compute(std::ostream &stream, uint32_t opcode) const { int op = (opcode >> 12) & 0xff; int cu = (opcode >> 20) & 0x3; @@ -347,7 +351,7 @@ void sharc_disassembler::compute(std::ostream &stream, uint32_t opcode) } } -void sharc_disassembler::get_if_condition(std::ostream &stream, int cond) +void sharc_disassembler::get_if_condition(std::ostream &stream, int cond) const { if (cond != 31) { @@ -355,7 +359,7 @@ void sharc_disassembler::get_if_condition(std::ostream &stream, int cond) } } -void sharc_disassembler::pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update) +void sharc_disassembler::pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update) const { if (update) // post-modify { @@ -410,7 +414,7 @@ void sharc_disassembler::pm_dm_ureg(std::ostream &stream, int g, int d, int i, i } } -void sharc_disassembler::pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update) +void sharc_disassembler::pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update) const { const char *sign = ""; if (data & 0x20) @@ -471,7 +475,7 @@ void sharc_disassembler::pm_dm_imm_dreg(std::ostream &stream, int g, int d, int } } -void sharc_disassembler::pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg) +void sharc_disassembler::pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg) const { if (d) { @@ -497,7 +501,7 @@ void sharc_disassembler::pm_dm_dreg(std::ostream &stream, int g, int d, int i, i } } -void sharc_disassembler::shiftop(std::ostream &stream, int shift, int data, int rn, int rx) +void sharc_disassembler::shiftop(std::ostream &stream, int shift, int data, int rn, int rx) const { int8_t data8 = data & 0xff; int bit6 = data & 0x3f; @@ -530,7 +534,7 @@ void sharc_disassembler::shiftop(std::ostream &stream, int shift, int data, int } } -uint32_t sharc_disassembler::dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int dmi = (opcode >> 41) & 0x7; int dmm = (opcode >> 38) & 0x7; @@ -566,7 +570,7 @@ uint32_t sharc_disassembler::dasm_compute_dreg_dmpm(std::ostream &stream, uint32 return 0; } -uint32_t sharc_disassembler::dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int cond = (opcode >> 33) & 0x1f; int comp = opcode & 0x7fffff; @@ -579,7 +583,7 @@ uint32_t sharc_disassembler::dasm_compute(std::ostream &stream, uint32_t pc, uin return 0; } -uint32_t sharc_disassembler::dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 32) & 0x1; @@ -600,7 +604,7 @@ uint32_t sharc_disassembler::dasm_compute_uregdmpm_regmod(std::ostream &stream, return 0; } -uint32_t sharc_disassembler::dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 40) & 0x1; @@ -621,7 +625,7 @@ uint32_t sharc_disassembler::dasm_compute_dregdmpm_immmod(std::ostream &stream, return 0; } -uint32_t sharc_disassembler::dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int cond = (opcode >> 31) & 0x1f; int uregs = (opcode >> 36) & 0xff; @@ -638,7 +642,7 @@ uint32_t sharc_disassembler::dasm_compute_ureg_ureg(std::ostream &stream, uint32 return 0; } -uint32_t sharc_disassembler::dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 32) & 0x1; @@ -658,7 +662,7 @@ uint32_t sharc_disassembler::dasm_immshift_dregdmpm(std::ostream &stream, uint32 return 0; } -uint32_t sharc_disassembler::dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int cond = (opcode >> 33) & 0x1f; int rn = (opcode >> 4) & 0xf; @@ -671,7 +675,7 @@ uint32_t sharc_disassembler::dasm_immshift_dregdmpm_nodata(std::ostream &stream, return 0; } -uint32_t sharc_disassembler::dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 38) & 0x7; @@ -689,7 +693,7 @@ uint32_t sharc_disassembler::dasm_compute_modify(std::ostream &stream, uint32_t return 0; } -uint32_t sharc_disassembler::dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int j = (opcode >> 26) & 0x1; int cond = (opcode >> 33) & 0x1f; @@ -730,7 +734,7 @@ uint32_t sharc_disassembler::dasm_direct_jump(std::ostream &stream, uint32_t pc, return flags; } -uint32_t sharc_disassembler::dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int b = (opcode >> 39) & 0x1; int j = (opcode >> 26) & 0x1; @@ -787,7 +791,7 @@ uint32_t sharc_disassembler::dasm_indirect_jump_compute(std::ostream &stream, ui return flags; } -uint32_t sharc_disassembler::dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int d = (opcode >> 44) & 0x1; int cond = (opcode >> 33) & 0x1f; @@ -829,7 +833,7 @@ uint32_t sharc_disassembler::dasm_indirect_jump_compute_dregdm(std::ostream &str return flags; } -uint32_t sharc_disassembler::dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int j = (opcode >> 26) & 0x1; int e = (opcode >> 25) & 0x1; @@ -874,7 +878,7 @@ uint32_t sharc_disassembler::dasm_rts_compute(std::ostream &stream, uint32_t pc, return flags; } -uint32_t sharc_disassembler::dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int data = (opcode >> 24) & 0xffff; int ureg = (opcode >> 32) & 0xff; @@ -893,7 +897,7 @@ uint32_t sharc_disassembler::dasm_do_until_counter(std::ostream &stream, uint32_ return 0; } -uint32_t sharc_disassembler::dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int term = (opcode >> 33) & 0x1f; uint32_t addr = opcode & 0xffffff; @@ -902,7 +906,7 @@ uint32_t sharc_disassembler::dasm_do_until(std::ostream &stream, uint32_t pc, ui return 0; } -uint32_t sharc_disassembler::dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int d = (opcode >> 40) & 0x1; int g = (opcode >> 41) & 0x1; @@ -934,7 +938,7 @@ uint32_t sharc_disassembler::dasm_immmove_uregdmpm(std::ostream &stream, uint32_ return 0; } -uint32_t sharc_disassembler::dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int d = (opcode >> 40) & 0x1; int g = (opcode >> 44) & 0x1; @@ -967,7 +971,7 @@ uint32_t sharc_disassembler::dasm_immmove_uregdmpm_indirect(std::ostream &stream return 0; } -uint32_t sharc_disassembler::dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int g = (opcode >> 37) & 0x1; int i = (opcode >> 41) & 0x7; @@ -985,7 +989,7 @@ uint32_t sharc_disassembler::dasm_immmove_immdata_dmpm(std::ostream &stream, uin return 0; } -uint32_t sharc_disassembler::dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int ureg = (opcode >> 32) & 0xff; uint32_t data = opcode & 0xffffffff; @@ -994,7 +998,7 @@ uint32_t sharc_disassembler::dasm_immmove_immdata_ureg(std::ostream &stream, uin return 0; } -uint32_t sharc_disassembler::dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int bop = (opcode >> 37) & 0x7; int sreg = (opcode >> 32) & 0xf; @@ -1007,7 +1011,7 @@ uint32_t sharc_disassembler::dasm_sysreg_bitop(std::ostream &stream, uint32_t pc return 0; } -uint32_t sharc_disassembler::dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int g = (opcode >> 38) & 0x1; int i = (opcode >> 32) & 0x7; @@ -1038,7 +1042,7 @@ uint32_t sharc_disassembler::dasm_ireg_modify(std::ostream &stream, uint32_t pc, return 0; } -uint32_t sharc_disassembler::dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode) const { int bits = (opcode >> 33) & 0x7f; int lpu = (opcode >> 39) & 0x1; @@ -1104,7 +1108,7 @@ uint32_t sharc_disassembler::dasm_misc(std::ostream &stream, uint32_t pc, uint64 return 0; } -uint32_t sharc_disassembler::dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode) const { if (opcode & 0x8000000000U) { @@ -1117,7 +1121,7 @@ uint32_t sharc_disassembler::dasm_idlenop(std::ostream &stream, uint32_t pc, uin return 0; } -uint32_t sharc_disassembler::dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode) const { /* TODO */ if (opcode & 0x10000000000U) /* RFRAME */ @@ -1131,7 +1135,7 @@ uint32_t sharc_disassembler::dasm_cjump_rframe(std::ostream &stream, uint32_t pc return 0; } -uint32_t sharc_disassembler::dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode) const { util::stream_format(stream, "?"); return 0; @@ -1208,19 +1212,16 @@ const sharc_disassembler::SHARC_DASM_OP sharc_disassembler::sharc_dasm_ops[] = sharc_disassembler::sharc_disassembler() { - int i, j; - int num_ops = sizeof(sharc_dasm_ops) / sizeof(SHARC_DASM_OP); - - for (i=0; i < 256; i++) + for (int i = 0; i < 256; i++) { sharcdasm_table[i] = &sharc_disassembler::dasm_invalid; } - for (i=0; i < 256; i++) + for (int i = 0; i < 256; i++) { - uint16_t op = i << 8; + const uint16_t op = i << 8; - for (j=0; j < num_ops; j++) + for (int j = 0; j < std::size(sharc_dasm_ops); j++) { if ((sharc_dasm_ops[j].op_mask & op) == sharc_dasm_ops[j].op_bits) { @@ -1239,8 +1240,12 @@ sharc_disassembler::sharc_disassembler() offs_t sharc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u64 opcode = opcodes.r64(pc); - int op = (opcode >> 40) & 0xff; + return disassemble_one(stream, pc, opcodes.r64(pc)); +} + +offs_t sharc_disassembler::disassemble_one(std::ostream &stream, offs_t pc, uint64_t opcode) const +{ + const int op = (opcode >> 40) & 0xff; return 1 | (this->*sharcdasm_table[op])(stream, pc, opcode) | SUPPORTED; } diff --git a/src/devices/cpu/sharc/sharcdsm.h b/src/devices/cpu/sharc/sharc_dasm.h index f752a133d6a..f2e92633ccf 100644 --- a/src/devices/cpu/sharc/sharcdsm.h +++ b/src/devices/cpu/sharc/sharc_dasm.h @@ -1,8 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Ville Linde - -#ifndef MAME_CPU_SHARC_SHARCDSM_H -#define MAME_CPU_SHARC_SHARCDSM_H +#ifndef MAME_CPU_SHARC_SHARC_DASM_H +#define MAME_CPU_SHARC_SHARC_DASM_H #pragma once @@ -15,54 +14,53 @@ public: virtual u32 opcode_alignment() const override; virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + offs_t disassemble_one(std::ostream &stream, offs_t pc, uint64_t opcode) const; + private: + using dasm_func = uint32_t (sharc_disassembler::*)(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + struct SHARC_DASM_OP { uint32_t op_mask; uint32_t op_bits; - uint32_t (sharc_disassembler::*handler)(std::ostream &, uint32_t, uint64_t); + dasm_func handler; }; - static const char ureg_names[256][16]; - static const char bopnames[8][8]; - static const char condition_codes_if[32][32]; - static const char condition_codes_do[32][32]; - static const char mr_regnames[16][8]; static const SHARC_DASM_OP sharc_dasm_ops[]; - uint32_t (sharc_disassembler::*sharcdasm_table[256])(std::ostream &, uint32_t, uint64_t); + dasm_func sharcdasm_table[256]; - void compute(std::ostream &stream, uint32_t opcode); - void get_if_condition(std::ostream &stream, int cond); - void pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update); - void pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update); - void pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg); - void shiftop(std::ostream &stream, int shift, int data, int rn, int rx); + void compute(std::ostream &stream, uint32_t opcode) const; + void get_if_condition(std::ostream &stream, int cond) const; + void pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update) const; + void pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update) const; + void pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg) const; + void shiftop(std::ostream &stream, int shift, int data, int rn, int rx) const; - uint32_t dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode); - uint32_t dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode) const; + uint32_t dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode) const; }; -#endif +#endif // MAME_CPU_SHARC_SHARC_DASM_H diff --git a/src/devices/cpu/sharc/sharcdrc.cpp b/src/devices/cpu/sharc/sharcdrc.cpp index f3ecdfe3b1a..d4b288458af 100644 --- a/src/devices/cpu/sharc/sharcdrc.cpp +++ b/src/devices/cpu/sharc/sharcdrc.cpp @@ -136,19 +136,22 @@ void adsp21062_device::cfunc_update_flag_out(void *param) void adsp21062_device::cfunc_unimplemented(void *param) { auto &sharc = *reinterpret_cast<adsp21062_device *>(param); - throw emu_fatalerror("%s: PC=%08X: Unimplemented op %012X", sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64); + throw emu_fatalerror("%s: PC=%08X: Unimplemented op %012X: %s", + sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64)); } void adsp21062_device::cfunc_unimplemented_compute(void *param) { auto &sharc = *reinterpret_cast<adsp21062_device *>(param); - throw emu_fatalerror("%s: PC=%08X: Unimplemented compute %012X", sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64); + throw emu_fatalerror("%s: PC=%08X: Unimplemented compute %012X: %s", + sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64)); } void adsp21062_device::cfunc_unimplemented_shiftimm(void *param) { auto &sharc = *reinterpret_cast<adsp21062_device *>(param); - throw emu_fatalerror("%s: PC=%08X: Unimplemented shiftimm %012X", sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64); + throw emu_fatalerror("%s: PC=%08X: Unimplemented shiftimm %012X: %s", + sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64)); } void adsp21062_device::cfunc_pcstack_overflow(void *param) diff --git a/src/devices/cpu/sharc/sharcfe.cpp b/src/devices/cpu/sharc/sharcfe.cpp index 4e601f398c6..52f0a115bc1 100644 --- a/src/devices/cpu/sharc/sharcfe.cpp +++ b/src/devices/cpu/sharc/sharcfe.cpp @@ -629,7 +629,7 @@ bool adsp21062_device::frontend::describe(opcode_desc &desc, const opcode_desc * break; default: - fatalerror("adsp21062_device::frontend::describe: unknown subop %02X in opcode %04X%08X", subop, (uint16_t)(opcode >> 32), (uint32_t)(opcode)); + fatalerror("adsp21062_device::frontend::describe: unknown subop %02X in opcode %012X", subop, opcode); return false; } break; @@ -1137,7 +1137,7 @@ bool adsp21062_device::frontend::describe_compute(opcode_desc &desc, uint64_t op break; default: - fatalerror("adsp21062_device::frontend::describe_compute: unknown multiop %02X in opcode %04X%08X at %08X", multiop, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc); + fatalerror("adsp21062_device::frontend::describe_compute: unknown multiop %02X in opcode %012X at %08X", multiop, opcode, desc.pc); return false; } } @@ -1244,7 +1244,7 @@ bool adsp21062_device::frontend::describe_compute(opcode_desc &desc, uint64_t op } default: - fatalerror("adsp21062_device::frontend::describe_compute: unknown ALU op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc); + fatalerror("adsp21062_device::frontend::describe_compute: unknown ALU op %02X in opcode %012X at %08X", operation, opcode, desc.pc); return false; } break; @@ -1528,7 +1528,7 @@ bool adsp21062_device::frontend::describe_compute(opcode_desc &desc, uint64_t op break; default: - fatalerror("adsp21062_device::frontend::describe_compute: unknown mult op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc); + fatalerror("adsp21062_device::frontend::describe_compute: unknown mult op %02X in opcode %012X at %08X", operation, opcode, desc.pc); } break; } @@ -1581,13 +1581,13 @@ bool adsp21062_device::frontend::describe_compute(opcode_desc &desc, uint64_t op break; default: - fatalerror("adsp21062_device::frontend::describe_compute: unknown shift op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc); + fatalerror("adsp21062_device::frontend::describe_compute: unknown shift op %02X in opcode %012X at %08X", operation, opcode, desc.pc); } break; } default: - fatalerror("adsp21062_device::frontend::describe_compute: unknown operation type in opcode %04X%08X at %08X", (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc); + fatalerror("adsp21062_device::frontend::describe_compute: unknown operation type in opcode %012X at %08X", opcode, desc.pc); return false; } } diff --git a/src/devices/cpu/sharc/sharcops.hxx b/src/devices/cpu/sharc/sharcops.hxx index 648ffdccefa..d82123eefc9 100644 --- a/src/devices/cpu/sharc/sharcops.hxx +++ b/src/devices/cpu/sharc/sharcops.hxx @@ -67,7 +67,7 @@ void adsp21062_device::add_systemreg_write_latency_effect(int sysreg, uint32_t d { if (m_core->systemreg_latency_cycles > 0) { - //fatalerror("SHARC: add_systemreg_write_latency_effect: already scheduled! (reg: %02X, data: %08X, PC: %08X)\n", systemreg_latency_reg, systemreg_latency_data, m_core->pc); + //throw emu_fatalerror("%s: add_systemreg_write_latency_effect: already scheduled! (reg: %02X, data: %08X, PC: %08X)", tag(), systemreg_latency_reg, systemreg_latency_data, m_core->pc); systemreg_write_latency_effect(); } @@ -91,15 +91,15 @@ void adsp21062_device::systemreg_write_latency_effect() if ((data & 0x1) != (oldreg & 0x1)) { - fatalerror("SHARC: systemreg_latency_op: enable I8 bit-reversing\n"); + throw emu_fatalerror("%s: systemreg_latency_op: enable I8 bit-reversing", tag()); } if ((data & 0x2) != (oldreg & 0x2)) { - fatalerror("SHARC: systemreg_latency_op: enable I0 bit-reversing\n"); + throw emu_fatalerror("%s: systemreg_latency_op: enable I0 bit-reversing", tag()); } if ((data & 0x4) != (oldreg & 0x4)) { - fatalerror("SHARC: systemreg_latency_op: enable MR alternate\n"); + throw emu_fatalerror("%s: systemreg_latency_op: enable MR alternate", tag()); } if ((data & 0x8) != (oldreg & 0x8)) /* Switch DAG1 7-4 */ @@ -196,7 +196,7 @@ void adsp21062_device::systemreg_write_latency_effect() } break; } - default: fatalerror("SHARC: systemreg_latency_op: unknown register %02X at %08X\n", m_core->systemreg_latency_reg, m_core->pc); + default: throw emu_fatalerror("%s: systemreg_latency_op: unknown register %02X at %08X\n", tag(), m_core->systemreg_latency_reg, m_core->pc); } m_core->systemreg_latency_reg = -1; @@ -271,7 +271,7 @@ uint32_t adsp21062_device::GET_UREG(int ureg) case 0x5: return m_core->pcstkp; /* PCSTKP */ case 0x7: return m_core->curlcntr; /* CURLCNTR */ case 0x8: return m_core->lcntr; /* LCNTR */ - default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: GET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } break; } @@ -298,7 +298,7 @@ uint32_t adsp21062_device::GET_UREG(int ureg) } case 0xd: return m_core->imask; /* IMASK */ case 0xe: return m_core->stky; /* STKY */ - default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: GET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } break; } @@ -311,12 +311,12 @@ uint32_t adsp21062_device::GET_UREG(int ureg) case 0xb: return uint32_t(m_core->px); /* PX */ case 0xc: return uint16_t(m_core->px); /* PX1 */ case 0xd: return uint32_t(m_core->px >> 16); /* PX2 */ - default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: GET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } break; } - default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: GET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } } @@ -396,7 +396,7 @@ void adsp21062_device::SET_UREG(int ureg, uint32_t data) if (prev < m_core->pcstkp) { if (m_core->pcstkp >= 31) - fatalerror("SHARC: PC Stack overflow!\n"); + throw emu_fatalerror("%s: PC Stack overflow!", tag()); m_core->pcstk = m_core->pcstack[m_core->pcstkp - 1]; @@ -430,7 +430,7 @@ void adsp21062_device::SET_UREG(int ureg, uint32_t data) m_core->lcntr = data; break; - default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: SET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } break; @@ -479,7 +479,7 @@ void adsp21062_device::SET_UREG(int ureg, uint32_t data) m_core->stky = (m_core->stky & (LSEM | LSOV | SSEM | SSOV | PCEM | PCFL)) | (data & ~(LSEM | LSOV | SSEM | SSOV | PCEM | PCFL)); break; - default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: SET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } break; @@ -488,11 +488,11 @@ void adsp21062_device::SET_UREG(int ureg, uint32_t data) { case 0xc: m_core->px &= 0xffffffffffff0000U; m_core->px |= (data & 0xffff); break; /* PX1 */ case 0xd: m_core->px &= 0x000000000000ffffU; m_core->px |= (uint64_t)data << 16; break; /* PX2 */ - default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: SET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } break; - default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc); + default: throw emu_fatalerror("%s: SET_UREG: unknown register %08X at %08X", tag(), ureg, m_core->pc); } } @@ -712,7 +712,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx break; } - default: fatalerror("SHARC: unimplemented shift operation %02X at %08X\n", shiftop, m_core->pc); + default: throw emu_fatalerror("SHARC: unimplemented shift operation %02X at %08X", tag(), shiftop, m_core->pc); } } @@ -815,8 +815,7 @@ void adsp21062_device::COMPUTE(uint32_t opcode) } default: - fatalerror("SHARC: compute: multi-function opcode %02X not implemented ! (%08X, %08X)\n", multiop, m_core->pc, opcode); - break; + throw emu_fatalerror("%s: compute: multi-function opcode %02X not implemented ! (%08X, %08X)", tag(), multiop, m_core->pc, opcode); } } else /* Single-function opcode */ @@ -884,7 +883,7 @@ void adsp21062_device::COMPUTE(uint32_t opcode) break; } - default: fatalerror("SHARC: compute: unimplemented ALU operation %02X (%08X, %08X)\n", op, m_core->pc, opcode); + default: throw emu_fatalerror("%s: compute: unimplemented ALU operation %02X (%08X, %08X)", tag(), op, m_core->pc, opcode); } break; } @@ -906,8 +905,7 @@ void adsp21062_device::COMPUTE(uint32_t opcode) case 0xb2: REG(rn) = compute_mrb_plus_mul_ssin(rx, ry); break; default: - fatalerror("SHARC: compute: multiplier operation %02X not implemented ! (%08X, %08X)\n", op, m_core->pc, opcode); - break; + throw emu_fatalerror("%s: compute: multiplier operation %02X not implemented ! (%08X, %08X)", tag(), op, m_core->pc, opcode); } break; } @@ -1078,13 +1076,13 @@ void adsp21062_device::COMPUTE(uint32_t opcode) } default: - fatalerror("SHARC: compute: shift operation %02X not implemented ! (%08X, %08X)\n", op >> 2, m_core->pc, opcode); + throw emu_fatalerror("%s: compute: shift operation %02X not implemented ! (%08X, %08X)", tag(), op >> 2, m_core->pc, opcode); } break; } default: - fatalerror("SHARC: compute: invalid single-function operation %02X\n", cu); + throw emu_fatalerror("%s: compute: invalid single-function operation %02X", tag(), cu); } } } @@ -1092,7 +1090,7 @@ void adsp21062_device::COMPUTE(uint32_t opcode) inline void adsp21062_device::PUSH_PC() { if (m_core->pcstkp >= 30) - fatalerror("SHARC: PC Stack overflow!\n"); + throw emu_fatalerror("%s: PC Stack overflow!", tag()); if (m_core->pcstkp > 0) m_core->pcstack[m_core->pcstkp - 1] = m_core->pcstk; @@ -1107,7 +1105,7 @@ inline void adsp21062_device::PUSH_PC() inline uint32_t adsp21062_device::POP_PC() { if (m_core->pcstkp == 0) - fatalerror("SHARC: PC Stack underflow!\n"); + throw emu_fatalerror("%s: PC Stack underflow!", tag()); uint32_t const result = m_core->pcstk; @@ -1139,7 +1137,7 @@ inline uint32_t adsp21062_device::TOP_PC() inline void adsp21062_device::PUSH_LOOP() { if (m_core->lstkp >= 6) - fatalerror("SHARC: Loop Stack overflow!\n"); + throw emu_fatalerror("%s: Loop Stack overflow!", tag()); if (m_core->lstkp > 0) { @@ -1162,7 +1160,7 @@ inline void adsp21062_device::PUSH_LOOP() inline void adsp21062_device::POP_LOOP() { if (m_core->lstkp == 0) - fatalerror("SHARC: Loop Stack underflow!\n"); + throw emu_fatalerror("%s: Loop Stack underflow!", tag()); m_core->lstkp--; @@ -1187,7 +1185,7 @@ inline void adsp21062_device::PUSH_STATUS_STACK() { m_core->status_stkp++; if (m_core->status_stkp >= 5) - fatalerror("SHARC: Status stack overflow!\n"); + throw emu_fatalerror("%s: Status stack overflow!", tag()); m_core->status_stack[m_core->status_stkp - 1].mode1 = GET_UREG(REG_MODE1); m_core->status_stack[m_core->status_stkp - 1].astat = GET_UREG(REG_ASTAT); @@ -1198,7 +1196,7 @@ inline void adsp21062_device::PUSH_STATUS_STACK() inline void adsp21062_device::POP_STATUS_STACK() { if (m_core->status_stkp <= 0) - fatalerror("SHARC: Status stack underflow!\n"); + throw emu_fatalerror("%s: Status stack underflow!", tag()); m_core->status_stkp--; @@ -2187,7 +2185,7 @@ void adsp21062_device::sharcop_rts() int const compute = op_get_compute(m_core->opcode); //if(lr) - // fatalerror("SHARC: rts: loop reentry not implemented!\n"); + // throw emu_fatalerror("%s: rts: loop reentry not implemented!", tag()); if (e) /* IF...ELSE */ { @@ -2524,8 +2522,7 @@ void adsp21062_device::sharcop_sysreg_bitop() break; } default: - fatalerror("SHARC: sysreg_bitop: invalid bitop %d\n", bop); - break; + throw emu_fatalerror("%s: sysreg_bitop: invalid bitop %d", tag(), bop); } SET_UREG(0x70 | sreg, src); @@ -2559,7 +2556,7 @@ void adsp21062_device::sharcop_modify() /* I register bit-reverse */ void adsp21062_device::sharcop_bit_reverse() { - fatalerror("SHARC: sharcop_bit_reverse unimplemented\n"); + throw emu_fatalerror("%s: sharcop_bit_reverse unimplemented", tag()); } /*****************************************************************************/ @@ -2578,12 +2575,10 @@ void adsp21062_device::sharcop_push_pop_stacks() } if (m_core->opcode & 0x002000000000U) { - //fatalerror("sharcop_push_pop_stacks: push sts not implemented\n"); PUSH_STATUS_STACK(); } if (m_core->opcode & 0x001000000000U) { - //fatalerror("sharcop_push_pop_stacks: pop sts not implemented\n"); POP_STATUS_STACK(); } if (m_core->opcode & 0x000800000000U) @@ -2622,5 +2617,6 @@ void adsp21062_device::sharcop_idle() void adsp21062_device::sharcop_unimplemented() { - fatalerror("SHARC: Unimplemented opcode %012X at %08X\n", m_core->opcode, m_core->pc); + throw emu_fatalerror("%s: Unimplemented opcode %012X at %08X: %s", + tag(), m_core->opcode, m_core->pc, disassemble_one(m_core->pc, m_core->opcode)); } diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index b479313119b..a6fd193ae05 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -169,7 +169,7 @@ using util::BIT; #include "cpu/scudsp/scudspdasm.h" #include "cpu/se3208/se3208dis.h" #include "cpu/sh/sh_dasm.h" -#include "cpu/sharc/sharcdsm.h" +#include "cpu/sharc/sharc_dasm.h" #include "cpu/sigma2/sigma2d.h" #include "cpu/sm510/sm510d.h" #include "cpu/sm8500/sm8500d.h" |
