diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index c177d918d45..9c1b11fb383 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -734,7 +734,6 @@ void hyperstone_device::execute_trap(uint8_t trapno) void hyperstone_device::execute_int(uint32_t addr) { const uint8_t reg = GET_FP + GET_FL; - SET_ILC(m_instruction_length); const uint32_t oldSR = SR; SET_FL(2); @@ -1040,7 +1039,7 @@ void hyperstone_device::device_start() m_drcuml->symbol_add(&m_core->arg1, sizeof(uint32_t), "arg1"); /* initialize the front-end helper */ - m_drcfe = std::make_unique(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); + m_drcfe = std::make_unique(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); /* mark the cache dirty so it is updated on next execute */ m_cache_dirty = true; @@ -1498,12 +1497,6 @@ void hyperstone_device::execute_run() while (m_core->icount > 0) { -#if E132XS_LOG_INTERPRETER_REGS - dump_registers(); -#endif - - debugger_instruction_hook(PC); - if (--m_core->intblock <= 0) { m_core->intblock = 0; @@ -1513,6 +1506,12 @@ void hyperstone_device::execute_run() check_interrupts(); } +#if E132XS_LOG_INTERPRETER_REGS + dump_registers(); +#endif + + debugger_instruction_hook(PC); + OP = m_pr16(PC); PC += 2; diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index 5392f88f8e4..84ef7c6bba1 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -478,7 +478,7 @@ private: void static_generate_exception(drcuml_block &block, uml::code_label &label); void static_generate_interrupt_checks(drcuml_block &block, uml::code_label &label); void generate_interrupt_checks(drcuml_block &block, uml::code_label &labelnum, bool with_timer, int take_int, int take_timer); - void generate_branch(drcuml_block &block, uml::parameter mode, uml::parameter targetpc, const opcode_desc *desc); + void generate_branch(drcuml_block &block, compiler_state &compiler, uml::parameter mode, uml::parameter targetpc, const opcode_desc *desc); void generate_update_cycles(drcuml_block &block); void generate_checksum_block(drcuml_block &block, compiler_state &compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); void generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc); @@ -504,6 +504,7 @@ private: void generate_update_flags_addsub(drcuml_block &block, compiler_state &compiler, uml::parameter sr); void generate_update_flags_addsubc(drcuml_block &block, compiler_state &compiler, uml::parameter sr); void generate_update_flags_addsubs(drcuml_block &block, compiler_state &compiler, uml::parameter sr); + void generate_update_flags_cmp(drcuml_block &block, compiler_state &compiler, uml::parameter sr); template void generate_trap_exception_or_int(drcuml_block &block, uml::code_label &label, uml::parameter trapno); void generate_int(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t addr); diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp index 1684b4221b9..cb37985159a 100644 --- a/src/devices/cpu/e132xs/e132xsdrc.cpp +++ b/src/devices/cpu/e132xs/e132xsdrc.cpp @@ -219,9 +219,6 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc) /* loop until we get through all instruction sequences */ for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next()) { - const opcode_desc *curdesc; - uint32_t nextpc; - /* add a code log entry */ if (m_drcuml->logging()) block.append_comment("-------------------------"); @@ -263,12 +260,13 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc) UML_MOV(block, I7, 0); /* iterate over instructions in the sequence and compile them */ - for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) + for (const opcode_desc *curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) { generate_sequence_instruction(block, compiler, curdesc); generate_update_cycles(block); } + uint32_t nextpc; if (seqlast->flags & OPFLAG_RETURN_TO_START) /* if we need to return to the start, do it */ nextpc = pc; else /* otherwise we just go to the next instruction */ @@ -696,7 +694,7 @@ void hyperstone_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc, generate_branch ------------------------------------------------------------------*/ -void hyperstone_device::generate_branch(drcuml_block &block, uml::parameter mode, uml::parameter targetpc, const opcode_desc *desc) +void hyperstone_device::generate_branch(drcuml_block &block, compiler_state &compiler, uml::parameter mode, uml::parameter targetpc, const opcode_desc *desc) { // clobbers I0 and I1 if mode is BRANCH_TARGET_DYNAMIC @@ -705,17 +703,26 @@ void hyperstone_device::generate_branch(drcuml_block &block, uml::parameter mode generate_update_cycles(block); - // update the cycles and jump through the hash table to the target - const uml::parameter pc = (targetpc != BRANCH_TARGET_DYNAMIC) ? targetpc : DRC_PC; - const uml::parameter m = (mode != BRANCH_TARGET_DYNAMIC) ? mode : uml::I0; - if (mode == BRANCH_TARGET_DYNAMIC) + if (desc && (mode == compiler.m_mode) && (desc->flags & OPFLAG_INTRABLOCK_BRANCH)) { - UML_MOV(block, I0, DRC_SR); - UML_ROLAND(block, I1, I0, 32 - T_SHIFT + 1, 0x2); - UML_ROLAND(block, I0, I0, 32 - S_SHIFT, 0x1); - UML_OR(block, I0, I0, I1); + assert(desc->targetpc != BRANCH_TARGET_DYNAMIC); + + UML_JMP(block, desc->targetpc | 0x80000000); + } + else + { + // jump through the hash table to the target + const uml::parameter pc = (targetpc != BRANCH_TARGET_DYNAMIC) ? targetpc : DRC_PC; + const uml::parameter m = (mode != BRANCH_TARGET_DYNAMIC) ? mode : uml::I0; + if (mode == BRANCH_TARGET_DYNAMIC) + { + UML_MOV(block, I0, DRC_SR); + UML_ROLAND(block, I1, I0, 32 - T_SHIFT + 1, 0x2); + UML_ROLAND(block, I0, I0, 32 - S_SHIFT, 0x1); + UML_OR(block, I0, I0, I1); + } + UML_HASHJMP(block, m, pc, *m_nocode); } - UML_HASHJMP(block, m, pc, *m_nocode); } @@ -731,19 +738,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]); // set the PC map variable - const offs_t expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 3) : desc->pc; - UML_MAPVAR(block, MAPVAR_PC, expc); - -#if E132XS_LOG_DRC_REGS - UML_CALLC(block, &c_funcs::dump_registers, this); -#endif - - // if we are debugging, call the debugger - if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - { - //save_fast_iregs(block); - UML_DEBUG(block, desc->pc); - } + UML_MAPVAR(block, MAPVAR_PC, desc->pc); // check for pending interrupts UML_SUB(block, I0, mem(&m_core->intblock), 1); @@ -751,6 +746,17 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi UML_MOV(block, mem(&m_core->intblock), I0); UML_CALLHc(block, uml::COND_LE, *m_interrupt_checks); +#if E132XS_LOG_DRC_REGS + UML_CALLC(block, &c_funcs::dump_registers, this); +#endif + + // if we are debugging, call the debugger + if (machine().debug_flags & DEBUG_FLAG_ENABLED) + { + //save_fast_iregs(block); + UML_DEBUG(block, desc->pc); + } + if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) { // compile the instruction diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx index 62920bef016..3e3dce69638 100644 --- a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx +++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx @@ -390,15 +390,15 @@ void hyperstone_device::generate_set_dst(drcuml_block &block, compiler_state &co if (src.is_int_register() && (desc->targetpc == BRANCH_TARGET_DYNAMIC)) { UML_AND(block, src, src, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, src, desc); + generate_branch(block, compiler, compiler.m_mode, src, desc); } else if (src.is_immediate() && (desc->targetpc == BRANCH_TARGET_DYNAMIC)) { - generate_branch(block, compiler.m_mode, src.immediate() & ~uint32_t(1), desc); + generate_branch(block, compiler, compiler.m_mode, src.immediate() & ~uint32_t(1), desc); } else { - generate_branch(block, compiler.m_mode, desc->targetpc, desc); + generate_branch(block, compiler, compiler.m_mode, desc->targetpc, desc); } } } @@ -468,6 +468,26 @@ void hyperstone_device::generate_update_flags_addsubs(drcuml_block &block, compi UML_ROLINS(block, sr, I1, 0, (V_MASK | N_MASK | Z_MASK)); } +void hyperstone_device::generate_update_flags_cmp(drcuml_block &block, compiler_state &compiler, uml::parameter sr) +{ + // expects UML flags set by ADD/SUB + // clobbers I0, I1, I3 and I4 + + UML_SETc(block, uml::COND_V, I0); // I0 = ...V + UML_SETc(block, uml::COND_L, I1); // I1 = ...N + UML_SETc(block, uml::COND_Z, I3); // I3 = ...Z + UML_SETc(block, uml::COND_C, I4); // I4 = ...C + UML_AND(block, sr, sr, ~(V_MASK | N_MASK | Z_MASK | C_MASK)); + UML_SHL(block, I0, I0, V_SHIFT); // I0 = V... + UML_SHL(block, I1, I1, N_SHIFT); // I1 = .N.. + UML_SHL(block, I3, I3, Z_SHIFT); // I3 = ..Z. + UML_SHL(block, I4, I4, C_SHIFT); // I4 = ...C + UML_OR(block, I0, I0, I1); // I0 = VN.. + UML_OR(block, I3, I3, I4); // I1 = ..ZC + UML_OR(block, sr, sr, I0); + UML_OR(block, sr, sr, I3); +} + template void hyperstone_device::generate_trap_exception_or_int(drcuml_block &block, uml::code_label &label, uml::parameter trapno) { @@ -508,8 +528,8 @@ void hyperstone_device::generate_trap_exception_or_int(drcuml_block &block, uml: UML_ADD(block, I7, I7, mem(&m_core->clock_cycles_2)); // assume exception dispatch takes two cycles UML_MOV(block, DRC_PC, I0); // branch to exception handler - - generate_branch(block, 1, uml::I0, nullptr); // T cleared and S set - mode will always be 1 + generate_update_cycles(block); + UML_HASHJMP(block, 1, I0, *m_nocode); // T cleared and S set - mode will always be 1 } void hyperstone_device::generate_int(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t addr) @@ -601,7 +621,7 @@ void hyperstone_device::generate_software(drcuml_block &block, compiler_state &c UML_ROLINS(block, I0, I4, FP_SHIFT, FP_MASK); // SET_FP(reg) UML_MOV(block, DRC_SR, I0); - generate_branch(block, compiler.m_mode & 0x1, uml::I5, desc); // T cleared - only keep S in bit zero of mode + generate_branch(block, compiler, compiler.m_mode & 0x1, uml::I5, desc); // T cleared - only keep S in bit zero of mode } @@ -815,7 +835,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi UML_MOV(block, mem(&SP), I0); // SP = I0 UML_LABEL(block, done_ret); - generate_branch(block, BRANCH_TARGET_DYNAMIC, desc->targetpc, nullptr); // don't pass desc - must not update ILC and P + generate_branch(block, compiler, BRANCH_TARGET_DYNAMIC, desc->targetpc, nullptr); // don't pass desc - must not update ILC and P return; } else if (SRC_GLOBAL && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR @@ -1135,9 +1155,9 @@ void hyperstone_device::generate_cmp(drcuml_block &block, compiler_state &compil generate_load_src_addsub(block, compiler, SRC_GLOBAL, src_code, uml::I1, uml::I1, uml::I2); generate_load_operand(block, compiler, DST_GLOBAL, dst_code, uml::I0, uml::I3); - UML_SUB(block, I0, I0, I1); + UML_CMP(block, I0, I1); - generate_update_flags_addsub(block, compiler, uml::I2); + generate_update_flags_cmp(block, compiler, uml::I2); UML_MOV(block, DRC_SR, I2); } @@ -1230,7 +1250,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil { UML_AND(block, DRC_SR, DRC_SR, ~M_MASK); UML_AND(block, I5, I5, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I5, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I5, desc); } UML_JMP(block, done); @@ -1606,9 +1626,9 @@ void hyperstone_device::generate_cmpi(drcuml_block &block, compiler_state &compi generate_load_operand(block, compiler, DST_GLOBAL, dst_code, uml::I0, uml::I0); - UML_SUB(block, I0, I0, src); + UML_CMP(block, I0, src); - generate_update_flags_addsub(block, compiler, uml::I2); + generate_update_flags_cmp(block, compiler, uml::I2); UML_MOV(block, DRC_SR, I2); } @@ -1629,43 +1649,43 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi generate_check_delay_pc(block, compiler, desc); - int done; - if (DST_GLOBAL) + UML_AND(block, I2, DRC_SR, ~(Z_MASK | N_MASK)); + if (!src) + UML_OR(block, I2, I2, Z_MASK); + else if (src & 0x80000000) + UML_OR(block, I2, I2, N_MASK); +#if MISSIONCRAFT_FLAGS + UML_AND(block, I2, I2, ~V_MASK); +#endif + + if (DST_GLOBAL && !BIT(compiler.m_mode, 0)) { - done = compiler.m_labelnum++; - if (!BIT(compiler.m_mode, 0)) - { - const int no_exception = compiler.m_labelnum++; - UML_TEST(block, DRC_SR, H_MASK); - UML_JMPc(block, uml::COND_Z, no_exception); - UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR); - UML_JMP(block, done); - UML_LABEL(block, no_exception); - } + const int no_exception = compiler.m_labelnum++; + UML_TEST(block, I2, H_MASK); + UML_JMPc(block, uml::COND_Z, no_exception); + UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR); + UML_LABEL(block, no_exception); } - UML_AND(block, DRC_SR, DRC_SR, ~(Z_MASK | N_MASK)); - - if (src) - UML_OR(block, DRC_SR, DRC_SR, (src & 0x80000000) ? (Z_MASK | N_MASK) : Z_MASK); - -#if MISSIONCRAFT_FLAGS - UML_AND(block, DRC_SR, DRC_SR, ~V_MASK); -#endif + UML_MOV(block, DRC_SR, I2); if (DST_GLOBAL) { const int highglobal = compiler.m_labelnum++; + const int done = compiler.m_labelnum++; - UML_TEST(block, DRC_SR, H_MASK); + UML_TEST(block, I2, H_MASK); UML_JMPc(block, uml::COND_NZ, highglobal); generate_set_global_register_low(block, compiler, dst_code, src); if (dst_code == PC_REGISTER) { UML_AND(block, DRC_SR, DRC_SR, ~M_MASK); - generate_branch(block, compiler.m_mode, src & ~uint32_t(1), desc); + generate_branch(block, compiler, compiler.m_mode, src & ~uint32_t(1), desc); + } + else + { + UML_JMP(block, done); } - UML_JMP(block, done); UML_LABEL(block, highglobal); UML_AND(block, DRC_SR, DRC_SR, ~H_MASK); @@ -2612,7 +2632,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp if (src_code == PC_REGISTER) { UML_AND(block, I1, I1, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I1, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I1, desc); } } else @@ -2634,7 +2654,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp if (src_code == PC_REGISTER) { UML_AND(block, I1, I1, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I1, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I1, desc); } } else @@ -2659,7 +2679,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp if (src_code == PC_REGISTER) { UML_AND(block, I1, I1, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I1, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I1, desc); } } else @@ -2688,7 +2708,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp if (src_code == PC_REGISTER) { UML_AND(block, I1, I1, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I1, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I1, desc); } } else @@ -2708,7 +2728,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp if (src_code == PC_REGISTER) { UML_AND(block, I1, I1, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I1, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I1, desc); } } else @@ -2744,7 +2764,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp if (src_code == 0) { UML_AND(block, I1, I1, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I1, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I1, desc); } } else @@ -2766,7 +2786,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp if (src_code == PC_REGISTER) { UML_AND(block, I1, I1, ~uint32_t(1)); - generate_branch(block, compiler.m_mode, uml::I1, desc); + generate_branch(block, compiler, compiler.m_mode, uml::I1, desc); } } else @@ -3602,7 +3622,7 @@ void hyperstone_device::generate_ldwp(drcuml_block &block, compiler_state &compi UML_STORE(block, (void *)m_core->local_regs, I2, I3, SIZE_DWORD, SCALE_x4); if (src_code == PC_REGISTER) - generate_branch(block, compiler.m_mode, desc->targetpc, desc); + generate_branch(block, compiler, compiler.m_mode, desc->targetpc, desc); } else { @@ -3657,7 +3677,7 @@ void hyperstone_device::generate_lddp(drcuml_block &block, compiler_state &compi UML_STORE(block, (void *)m_core->local_regs, I2, I3, SIZE_DWORD, SCALE_x4); if (src_code == PC_REGISTER || (src_code + 1) == PC_REGISTER) - generate_branch(block, compiler.m_mode, desc->targetpc, desc); + generate_branch(block, compiler, compiler.m_mode, desc->targetpc, desc); } else { @@ -3875,22 +3895,17 @@ void hyperstone_device::generate_b(drcuml_block &block, compiler_state &compiler { static const uint32_t condition_masks[6] = { V_MASK, Z_MASK, C_MASK, C_MASK | Z_MASK, N_MASK, N_MASK | Z_MASK }; - int done = compiler.m_labelnum++; uml::condition_t condition = COND_SET ? uml::COND_Z : uml::COND_NZ; - int skip; + const int skip = compiler.m_labelnum++; UML_TEST(block, DRC_SR, condition_masks[CONDITION]); - UML_JMPc(block, condition, skip = compiler.m_labelnum++); + UML_JMPc(block, condition, skip); generate_br(block, compiler, desc); - UML_JMP(block, done); - UML_LABEL(block, skip); generate_ignore_pcrel(block, desc); generate_check_delay_pc(block, compiler, desc); UML_MOV(block, I7, mem(&m_core->clock_cycles_1)); - - UML_LABEL(block, done); } @@ -3905,7 +3920,7 @@ void hyperstone_device::generate_br(drcuml_block &block, compiler_state &compile UML_ADD(block, DRC_PC, DRC_PC, target); UML_AND(block, DRC_SR, DRC_SR, ~M_MASK); - generate_branch(block, compiler.m_mode, desc->targetpc, desc); + generate_branch(block, compiler, compiler.m_mode, desc->targetpc, desc); // TODO: correct cycle count } @@ -4077,7 +4092,7 @@ void hyperstone_device::generate_call(drcuml_block &block, compiler_state &compi UML_MOV(block, mem(&m_core->intblock), 2); - generate_branch(block, compiler.m_mode, uml::I2, nullptr); + generate_branch(block, compiler, compiler.m_mode, uml::I2, nullptr); //TODO: add interrupt locks, errors, .... } diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e132xsfe.cpp index 602f724269f..ec5c8df4442 100644 --- a/src/devices/cpu/e132xs/e132xsfe.cpp +++ b/src/devices/cpu/e132xs/e132xsfe.cpp @@ -12,8 +12,6 @@ #include "e132xsfe.h" #include "32xsdefs.h" -#define FE_FP ((m_cpu->m_core->global_regs[1] & 0xfe000000) >> 25) -#define FE_FL (m_cpu->m_core->fl_lut[((m_cpu->m_core->global_regs[1] >> 21) & 0xf)]) #define FE_DST_CODE ((op & 0xf0) >> 4) #define FE_SRC_CODE (op & 0x0f) #define SR_CODE (1 << 1) @@ -22,25 +20,25 @@ INSTRUCTION PARSERS ***************************************************************************/ -e132xs_frontend::e132xs_frontend(hyperstone_device *e132xs, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) - : drc_frontend(*e132xs, window_start, window_end, max_sequence) - , m_cpu(e132xs) +e132xs_frontend::e132xs_frontend(hyperstone_device &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) + : drc_frontend(cpu, window_start, window_end, max_sequence) + , m_cpu(cpu) { } inline uint16_t e132xs_frontend::read_word(opcode_desc &desc) { - return m_cpu->m_pr16(desc.physpc); + return m_cpu.m_pr16(desc.physpc); } inline uint16_t e132xs_frontend::read_imm1(opcode_desc &desc) { - return m_cpu->m_pr16(desc.physpc + 2); + return m_cpu.m_pr16(desc.physpc + 2); } inline uint16_t e132xs_frontend::read_imm2(opcode_desc &desc) { - return m_cpu->m_pr16(desc.physpc + 4); + return m_cpu.m_pr16(desc.physpc + 4); } inline uint32_t e132xs_frontend::read_ldstxx_imm(opcode_desc &desc) @@ -69,15 +67,13 @@ inline uint32_t e132xs_frontend::read_limm(opcode_desc &desc, uint16_t op) { static const int32_t immediate_values[16] = { - 16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000), + 16, 0, 0, 0, 32, 64, 128, int32_t(uint32_t(0x80000000)), -8, -7, -6, -5, -4, -3, -2, -1 }; - uint8_t nybble = op & 0xf; + const uint8_t nybble = op & 0xf; switch (nybble) { - case 0: - return 16; case 1: desc.length = 6; return (read_imm1(desc) << 16) | read_imm2(desc); @@ -88,7 +84,7 @@ inline uint32_t e132xs_frontend::read_limm(opcode_desc &desc, uint16_t op) desc.length = 4; return 0xffff0000 | read_imm1(desc); default: - return immediate_values[nybble]; + return uint32_t(immediate_values[nybble]); } } @@ -96,13 +92,10 @@ inline int32_t e132xs_frontend::decode_pcrel(opcode_desc &desc, uint16_t op) { if (op & 0x80) { - uint16_t next = read_imm1(desc); - desc.length = 4; - int32_t offset = (op & 0x7f) << 16; - offset |= (next & 0xfffe); - + const uint16_t next = read_imm1(desc); + int32_t offset = ((op & 0x7f) << 16) | (next & 0xfffe); if (next & 1) offset |= 0xff800000; @@ -113,6 +106,7 @@ inline int32_t e132xs_frontend::decode_pcrel(opcode_desc &desc, uint16_t op) int32_t offset = op & 0x7e; if (op & 1) offset |= 0xffffff80; + return offset; } } @@ -154,19 +148,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.length = 2; desc.delayslots = 0; - const uint32_t fp = FE_FP; const uint32_t gdst_code = FE_DST_CODE; const uint32_t gdstf_code = gdst_code + 1; const uint32_t gsrc_code = FE_SRC_CODE; const uint32_t gsrcf_code = gsrc_code + 1; - const uint32_t ldst_code = (gdst_code + fp) & 0x1f; - const uint32_t ldstf_code = (gdstf_code + fp) & 0x1f; - const uint32_t lsrc_code = (gsrc_code + fp) & 0x1f; - const uint32_t lsrcf_code = (gsrcf_code + fp) & 0x1f; - const uint32_t ldst_group = BIT(FE_DST_CODE + fp, 5) + 1; - const uint32_t ldstf_group = BIT(FE_DST_CODE + fp + 1, 5) + 1; - const uint32_t lsrc_group = BIT(FE_SRC_CODE + fp, 5) + 1; - const uint32_t lsrcf_group = BIT(FE_SRC_CODE + fp + 1, 5) + 1; switch (op >> 8) { @@ -178,19 +163,15 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x01: // chk global,local desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gdst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; break; case 0x02: // chk local,global desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regin[0] |= 1 << gsrc_code; desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; break; case 0x03: // chk local,local desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; break; case 0x04: // movd global,global @@ -200,25 +181,19 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regout[0] |= 1 << gdstf_code; if (gdst_code == 0) { - desc.regout[1] = 0xffffffff; - desc.regout[2] = 0xffffffff; desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_CHANGE_MODES; } desc.regout[0] |= SR_CODE; break; case 0x05: // movd global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[lsrcf_group] |= 1 << lsrcf_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdstf_code; if (gdst_code == 0) { - desc.regout[1] = 0xffffffff; - desc.regout[2] = 0xffffffff; desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; } desc.regout[0] |= SR_CODE; break; @@ -226,16 +201,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; desc.regin[0] |= 1 << gsrcf_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0x07: // movd local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[lsrcf_group] |= 1 << lsrcf_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0x08: // divu global,global @@ -252,7 +221,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x0d: // divs global,local desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regin[0] |= 1 << gdst_code; desc.regin[0] |= 1 << gdstf_code; desc.regout[0] |= 1 << gdst_code; @@ -264,21 +232,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regin[ldstf_group] |= 1 << ldstf_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0x0b: // divu local,local case 0x0f: // divs local,local desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regin[ldstf_group] |= 1 << ldstf_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0x10: // xm global,global @@ -290,7 +249,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x11: // xm global,local desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regout[0] |= 1 << gdst_code; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; break; @@ -298,14 +256,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; break; case 0x13: // xm local,local desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; break; case 0x14: // mask global,global @@ -316,7 +271,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) break; case 0x15: // mask global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; @@ -324,14 +278,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x16: // mask local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; break; case 0x17: // mask local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; break; @@ -346,7 +297,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x19: // sum global,local case 0x1d: // sums global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; @@ -356,7 +306,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x1e: // sums local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; @@ -364,8 +313,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x1b: // sum local,local case 0x1f: // sums local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; @@ -379,7 +326,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x21: // cmp global,local case 0x31: // cmpb global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; break; @@ -387,14 +333,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x32: // cmpb local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x23: // cmp local,local case 0x33: // cmpb local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x24: // mov global,global @@ -406,7 +349,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + if (gsrc_code != PC_REGISTER) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else + desc.targetpc = desc.physpc + desc.length; desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } else if (gdst_code == 5) // TPR_REGISTER & 0xf @@ -416,7 +362,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) break; case 0x25: // mov global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; @@ -434,13 +379,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; desc.regin[0] |= 1 << (gsrc_code + 16); - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x27: // mov local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x28: // add global,global @@ -454,7 +396,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + if (gsrc_code != PC_REGISTER) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else if (((op >> 8) == 0x28) || ((op >> 8) == 0x2c)) + desc.targetpc = (desc.physpc + desc.length) << 1; + else + desc.targetpc = 0; desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; @@ -463,7 +410,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x49: // sub global,local case 0x4d: // subs global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; @@ -480,8 +426,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x4e: // subs local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs break; @@ -490,9 +434,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x4b: // sub local,local case 0x4f: // subs local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs break; @@ -506,7 +447,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regout[0] |= SR_CODE; if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + if (gsrc_code != PC_REGISTER) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else if (((op >> 8) == 0x34) || ((op >> 8) == 0x3c)) + desc.targetpc = 0; + else + desc.targetpc = desc.physpc + desc.length; desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; @@ -515,7 +461,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x3d: // xor global,local case 0x55: // and global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; @@ -531,8 +476,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x56: // and local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x37: // andn local,local @@ -540,9 +483,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x3f: // xor local,local case 0x57: // and local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x40: // subc global,global @@ -561,7 +501,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x41: // subc global,local case 0x51: // addc global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; @@ -575,16 +514,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x52: // addc local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x43: // subc local,local case 0x53: // addc local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x44: // not global,global @@ -594,14 +528,18 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regout[0] |= SR_CODE; if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + if (gsrc_code != PC_REGISTER) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else if ((op >> 8) == 0x44) + desc.targetpc = ~uint32_t(desc.physpc + desc.length) & ~uint32_t(1); + else + desc.targetpc = uint32_t(-int32_t(desc.physpc + desc.length)) & ~uint32_t(1); desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; case 0x45: // not global,local case 0x59: // neg global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; if (gdst_code == PC_REGISTER) @@ -614,14 +552,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x5a: // neg local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x47: // not local,local case 0x5b: // neg local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x5c: // negs global,global @@ -631,13 +566,15 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + if (gsrc_code != PC_REGISTER) + desc.targetpc = BRANCH_TARGET_DYNAMIC; + else + desc.targetpc = uint32_t(-int32_t(desc.physpc + desc.length)) & ~uint32_t(1); desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; case 0x5d: // negs global,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; @@ -650,14 +587,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x5e: // negs local,global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; break; case 0x5f: // negs local,local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; break; @@ -675,13 +609,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x62: // cmpi local,simm case 0x72: // cmpbi local,simm desc.regin[0] |= SR_CODE; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x63: // cmpi local,limm case 0x73: // cmpbi local,limm desc.regin[0] |= SR_CODE; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = hyperstone_device::imm_length(op) << 1; break; @@ -693,7 +625,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; if (gdst_code == PC_REGISTER) { - desc.targetpc = op & 0xf; + desc.targetpc = op & 0xe; desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } else if (gdst_code == 5) // TPR_REGISTER & 0xf @@ -710,7 +642,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; if (gdst_code == PC_REGISTER) { - desc.targetpc = read_limm(desc, op); + desc.targetpc = read_limm(desc, op) & ~uint32_t(1); desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } else if (gdst_code == 5) // TPR_REGISTER & 0xf @@ -720,12 +652,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) break; case 0x66: // movi local,simm desc.regin[0] |= SR_CODE; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x67: // movi local,limm desc.regin[0] |= SR_CODE; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = hyperstone_device::imm_length(op) << 1; break; @@ -738,7 +668,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.targetpc = desc.physpc + desc.length + (op & 0xe); desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; @@ -752,29 +682,45 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi if (gdst_code == PC_REGISTER) { - desc.targetpc = desc.pc + desc.length + read_limm(desc, op); + desc.targetpc = desc.pc + desc.length + (read_limm(desc, op) & ~uint32_t(1)); desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; case 0x6a: // addi local,simm case 0x6e: // addsi local,simm desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi break; case 0x6b: // addi local,limm case 0x6f: // addsi local,limm desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = hyperstone_device::imm_length(op) << 1; if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi break; case 0x74: // andni global,simm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = (desc.physpc + desc.length) & ~uint32_t(op & 0xf); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; case 0x78: // ori global,simm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = (desc.physpc + desc.length) | (op & 0xe); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; case 0x7c: // xori global,simm desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gdst_code; @@ -782,12 +728,34 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regout[0] |= SR_CODE; if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.targetpc = (desc.physpc + desc.length) ^ (op & 0xe); desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; case 0x75: // andni global,limm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = hyperstone_device::imm_length(op) << 1; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = (desc.physpc + desc.length) & ~read_limm(desc, op); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; case 0x79: // ori global,limm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = hyperstone_device::imm_length(op) << 1; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = (desc.physpc + desc.length) | (read_limm(desc, op) & ~uint32_t(1)); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; case 0x7d: // xori global,limm desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gdst_code; @@ -796,7 +764,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.length = hyperstone_device::imm_length(op) << 1; if (gdst_code == PC_REGISTER) { - desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.targetpc = (desc.physpc + desc.length) ^ (read_limm(desc, op) & ~uint32_t(1)); desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; } break; @@ -804,16 +772,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x7a: // ori local,simm case 0x7e: // xori local,simm desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x77: // andni local,limm case 0x7b: // ori local,limm case 0x7f: // xori local,limm desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; desc.length = hyperstone_device::imm_length(op) << 1; break; @@ -821,17 +785,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x84: case 0x85: // sardi case 0x88: case 0x89: // shldi desc.regin[0] |= SR_CODE; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0x82: // shrd case 0x86: // sard case 0x8a: // shld desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0x83: // shr @@ -839,16 +798,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x8b: // shl case 0x8f: // rol desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0x8c: case 0x8d: // reserved return false; case 0x8e: // testlz desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; break; case 0x90: // ldxx1 global,global { @@ -871,12 +826,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x91: // ldxx1 global,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gdst_code; - desc.regout[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; @@ -893,7 +846,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[0] |= 1 << gsrc_code; if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; @@ -904,12 +856,9 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x93: // ldxx1 local,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; @@ -937,13 +886,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x95: // ldxx2 global,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; - desc.regout[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; @@ -960,8 +907,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= 1 << gsrc_code; if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; @@ -972,13 +917,9 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x97: // ldxx2 local,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; @@ -1000,12 +941,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x99: // stxx1 global,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gdst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_WRITES_MEMORY; @@ -1017,7 +956,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regin[0] |= 1 << gsrc_code; if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; @@ -1028,12 +966,9 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x9b: // stxx1 local,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_WRITES_MEMORY; @@ -1056,12 +991,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x9d: // stxx2 global,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gdst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; desc.regout[0] |= 1 << gdst_code; desc.length = (imm1 & 0x8000) ? 6 : 4; @@ -1074,10 +1007,8 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regin[0] |= 1 << gsrc_code; if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_WRITES_MEMORY; @@ -1086,13 +1017,9 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x9f: // stxx2 local,local { const uint16_t imm1 = read_imm1(desc); - const uint32_t extra_s = read_ldstxx_imm(desc); + [[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc); desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; - if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_WRITES_MEMORY; @@ -1115,8 +1042,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0xaa: // shli local (lo n) case 0xab: // shli local (hi n) desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0xac: case 0xad: case 0xae: case 0xaf: // reserved @@ -1131,7 +1056,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) break; case 0xb1: // mulu global,local case 0xb5: // muls global,local - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdstf_code; @@ -1140,17 +1064,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0xb2: // mulu local,global case 0xb6: // muls local,global desc.regin[0] |= 1 << gsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0xb3: // mulu local,local case 0xb7: // muls local,local - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.regout[0] |= SR_CODE; break; case 0xb8: // set global (lo n) @@ -1160,7 +1077,6 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) break; case 0xba: // set local (lo n) case 0xbb: // set local (hi n) - desc.regout[ldst_group] |= 1 << ldst_code; break; case 0xbc: // mul global,global desc.regin[0] |= 1 << gsrc_code; @@ -1169,50 +1085,30 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regout[0] |= SR_CODE; break; case 0xbd: // muls global,local - desc.regin[lsrc_group] |= 1 << lsrc_code; desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; break; case 0xbe: // muls local,global desc.regin[0] |= 1 << gsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0xbf: // mulu local,local - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; break; case 0xc0: case 0xc1: case 0xc2: case 0xc3: // software case 0xc4: case 0xc5: case 0xc6: case 0xc7: // software case 0xc8: case 0xc9: case 0xca: case 0xcb: // software case 0xcc: case 0xcd: // software - { desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[lsrcf_group] |= 1 << lsrcf_code; - - const uint32_t reg = FE_FP + FE_FL; - desc.regout[1 + (((reg + 0) & 0x20) >> 5)] |= 1 << ((reg + 0) & 0x1f); - desc.regout[1 + (((reg + 1) & 0x20) >> 5)] |= 1 << ((reg + 1) & 0x1f); - desc.regout[1 + (((reg + 2) & 0x20) >> 5)] |= 1 << ((reg + 2) & 0x1f); - desc.regout[1 + (((reg + 3) & 0x20) >> 5)] |= 1 << ((reg + 3) & 0x1f); - desc.regout[1 + (((reg + 4) & 0x20) >> 5)] |= 1 << ((reg + 4) & 0x1f); - desc.regout[0] |= SR_CODE; desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CHANGE_MODES; break; - } case 0xce: // extend - 4 bytes desc.regin[0] |= SR_CODE; desc.regin[0] |= (3 << 14); // global regs 14, 15 - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[0] |= (3 << 14); // global regs 14, 15 desc.length = 4; break; @@ -1221,109 +1117,83 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0xd0: // ldwr global case 0xd4: // ldwp global desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[0] |= 1 << gsrc_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_READS_MEMORY; break; case 0xd1: // ldwr local case 0xd5: // ldwp local desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[lsrc_group] |= 1 << lsrc_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_READS_MEMORY; break; case 0xd2: // lddr global case 0xd6: // lddp global desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[0] |= 1 << gsrc_code; desc.regout[0] |= 1 << gsrcf_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_READS_MEMORY; break; case 0xd3: // lddr local case 0xd7: // lddp local desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regout[lsrc_group] |= 1 << lsrc_code; - desc.regout[lsrcf_group] |= 1 << lsrcf_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_READS_MEMORY; break; case 0xd8: // stwr global case 0xdc: // stwp global desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regin[0] |= 1 << gsrc_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_WRITES_MEMORY; break; case 0xd9: // stwr local case 0xdd: // stwp local desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_WRITES_MEMORY; break; case 0xda: // stdr global case 0xde: // stdp global desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; desc.regin[0] |= 1 << gsrc_code; desc.regin[0] |= 1 << gsrcf_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_WRITES_MEMORY; break; case 0xdb: // stdr local case 0xdf: // stdp local desc.regin[0] |= SR_CODE; - desc.regin[ldst_group] |= 1 << ldst_code; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regin[lsrcf_group] |= 1 << lsrcf_code; - if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; desc.flags |= OPFLAG_WRITES_MEMORY; break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: // dbv, dbnv, dbe, dbne - could be 4 bytes (pcrel) case 0xe4: case 0xe5: case 0xe6: case 0xe7: // dbc, dbnc, dbse, dbht - could be 4 bytes (pcrel) case 0xe8: case 0xe9: case 0xea: case 0xeb: // dbn, dbnn, dblt, dbgt - could be 4 bytes (pcrel) - decode_pcrel(desc, op); desc.regin[0] |= SR_CODE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; desc.delayslots = 1; desc.length = (op & 0x80) ? 4 : 2; + desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op); break; case 0xec: // dbr - decode_pcrel(desc, op); - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH; desc.delayslots = 1; desc.length = (op & 0x80) ? 4 : 2; + desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op); break; case 0xed: // frame desc.regin[0] |= SR_CODE; - desc.regin[1] = 0xffffffff; - desc.regin[2] = 0xffffffff; desc.regout[0] |= SR_CODE; - desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE; + desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; break; case 0xee: // call global desc.regin[0] |= SR_CODE; desc.regin[0] |= 1 << gsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; - desc.targetpc = BRANCH_TARGET_DYNAMIC; desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (gsrc_code == PC_REGISTER) + desc.targetpc = desc.physpc + desc.length + (decode_call(desc) & ~uint32_t(1)); + else if (gsrc_code == SR_REGISTER) + desc.targetpc = decode_call(desc) & ~uint32_t(1); + else + desc.targetpc = BRANCH_TARGET_DYNAMIC; break; case 0xef: // call local desc.regin[0] |= SR_CODE; - desc.regin[lsrc_group] |= 1 << lsrc_code; - desc.regout[ldst_group] |= 1 << ldst_code; - desc.regout[ldstf_group] |= 1 << ldstf_code; desc.targetpc = BRANCH_TARGET_DYNAMIC; desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; @@ -1331,24 +1201,23 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0xf0: case 0xf1: case 0xf2: case 0xf3: // bv, bnv, be, bne case 0xf4: case 0xf5: case 0xf6: case 0xf7: // bc, bnc, bse, bht case 0xf8: case 0xf9: case 0xfa: case 0xfb: // bn, bnn, blt, bgt - decode_pcrel(desc, op); desc.regin[0] |= SR_CODE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; desc.length = (op & 0x80) ? 4 : 2; + desc.targetpc = desc.pc + desc.length + decode_pcrel(desc, op); break; case 0xfc: // br - { - int32_t offset = decode_pcrel(desc, op); - desc.targetpc = (desc.pc + desc.length) + offset; desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; desc.length = (op & 0x80) ? 4 : 2; + desc.targetpc = desc.pc + desc.length + decode_pcrel(desc, op); break; - } case 0xfd: case 0xfe: case 0xff: // trap desc.regin[0] |= SR_CODE; desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + if ((((op & 0x300) >> 6) | (op & 0x03)) == 15) + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + else + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_CAN_CAUSE_EXCEPTION; break; } return true; diff --git a/src/devices/cpu/e132xs/e132xsfe.h b/src/devices/cpu/e132xs/e132xsfe.h index 1cac61a08cd..c71849228e8 100644 --- a/src/devices/cpu/e132xs/e132xsfe.h +++ b/src/devices/cpu/e132xs/e132xsfe.h @@ -11,7 +11,7 @@ class e132xs_frontend : public drc_frontend { public: - e132xs_frontend(hyperstone_device *e132xs, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); + e132xs_frontend(hyperstone_device &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); void flush(); protected: @@ -19,15 +19,15 @@ protected: virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override; private: - inline uint16_t read_word(opcode_desc &desc); - inline uint16_t read_imm1(opcode_desc &desc); - inline uint16_t read_imm2(opcode_desc &desc); - inline uint32_t read_ldstxx_imm(opcode_desc &desc); - inline uint32_t read_limm(opcode_desc &desc, uint16_t op); - inline int32_t decode_pcrel(opcode_desc &desc, uint16_t op); - inline int32_t decode_call(opcode_desc &desc); + uint16_t read_word(opcode_desc &desc); + uint16_t read_imm1(opcode_desc &desc); + uint16_t read_imm2(opcode_desc &desc); + uint32_t read_ldstxx_imm(opcode_desc &desc); + uint32_t read_limm(opcode_desc &desc, uint16_t op); + int32_t decode_pcrel(opcode_desc &desc, uint16_t op); + int32_t decode_call(opcode_desc &desc); - hyperstone_device *m_cpu; + hyperstone_device &m_cpu; }; -#endif /* MAME_CPU_E132XS_E132XSFE_H */ +#endif // MAME_CPU_E132XS_E132XSFE_H