summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2025-03-27 08:07:52 +1100
committer Vas Crabb <vas@vastheman.com>2025-03-27 08:07:52 +1100
commit128c29c52f4d57789fa4ad51271ca58bfc815dfc (patch)
tree65aad2de9111e109852dbbff33ca27b454d38ffd
parent08fae4612b5fb5b40e52672d0b5d0b5e60fc6489 (diff)
cpu/e132xs: More fixes and optimisation:
* Fixed failing to call the debugger instruction hook for the first instruction following an interrupt, exception or trap. * Use UML branches to emulate non-delayed intra-block branches, avoiding the expensive "hash jump". * Re-worked the instruction description code: - Calculate static branch targets for more instructions. - Flag instructions that may cause mode changes. - Don't be so eager to end an instruction sequence. - Removed the local register input/output flags - FP may no be the same when executing the code as when describing instructions. * Fixed interpreter incorrectly setting ILC when an interrupt immediately follows a RET instruction. * Fixed recompiler flag calculation regressions, and optimised a little.
-rw-r--r--src/devices/cpu/e132xs/e132xs.cpp15
-rw-r--r--src/devices/cpu/e132xs/e132xs.h3
-rw-r--r--src/devices/cpu/e132xs/e132xsdrc.cpp52
-rw-r--r--src/devices/cpu/e132xs/e132xsdrc_ops.hxx121
-rw-r--r--src/devices/cpu/e132xs/e132xsfe.cpp359
-rw-r--r--src/devices/cpu/e132xs/e132xsfe.h20
6 files changed, 230 insertions, 340 deletions
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<e132xs_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+ m_drcfe = std::make_unique<e132xs_frontend>(*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<NO_TIMER>();
}
+#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 <trap_exception_or_int TYPE> 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,26 +738,25 @@ 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);
+ UML_MAPVAR(block, MAPVAR_PC, desc->pc);
+
+ // check for pending interrupts
+ UML_SUB(block, I0, mem(&m_core->intblock), 1);
+ UML_MOVc(block, uml::COND_S, I0, 0);
+ 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) != 0)
+ if (machine().debug_flags & DEBUG_FLAG_ENABLED)
{
//save_fast_iregs(block);
UML_DEBUG(block, desc->pc);
}
- // check for pending interrupts
- UML_SUB(block, I0, mem(&m_core->intblock), 1);
- UML_MOVc(block, uml::COND_S, I0, 0);
- UML_MOV(block, mem(&m_core->intblock), I0);
- UML_CALLHc(block, uml::COND_LE, *m_interrupt_checks);
-
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 <hyperstone_device::trap_exception_or_int TYPE>
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