diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index 3a31e93a2a9..a200a57261f 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -1,4 +1,3 @@ - // license:BSD-3-Clause // copyright-holders:Pierpaolo Prazzoli /******************************************************************** @@ -401,46 +400,26 @@ uint32_t hyperstone_device::get_emu_code_addr(uint8_t num) /* num is OP */ return addr; } -void hyperstone_device::hyperstone_set_trap_entry(int which) -{ - switch( which ) - { - case E132XS_ENTRY_MEM0: - m_trap_entry = 0x00000000; - break; +/*static*/ const uint32_t hyperstone_device::s_trap_entries[8] = { + 0x00000000, // MEM0 + 0x40000000, // MEM1 + 0x80000000, // MEM2 + 0xc0000000, // IRAM + 0, + 0, + 0, + 0xffffff00, // MEM3 +}; - case E132XS_ENTRY_MEM1: - m_trap_entry = 0x40000000; - break; - - case E132XS_ENTRY_MEM2: - m_trap_entry = 0x80000000; - break; - - case E132XS_ENTRY_MEM3: - m_trap_entry = 0xffffff00; - break; - - case E132XS_ENTRY_IRAM: - m_trap_entry = 0xc0000000; - break; - - default: - LOG("Set entry point to a reserved value: %d\n", which); - break; - } -} - -uint32_t hyperstone_device::compute_tr() +void hyperstone_device::compute_tr() { uint64_t cycles_since_base = total_cycles() - m_tr_base_cycles; uint64_t clocks_since_base = cycles_since_base >> m_clck_scale; - return m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick); + m_tr_result = m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick); } void hyperstone_device::update_timer_prescale() { - uint32_t prevtr = compute_tr(); TPR &= ~0x80000000; m_clck_scale = (TPR >> 26) & m_clock_scale_mask; m_clock_cycles_1 = 1 << m_clck_scale; @@ -449,7 +428,7 @@ void hyperstone_device::update_timer_prescale() m_clock_cycles_4 = 4 << m_clck_scale; m_clock_cycles_6 = 6 << m_clck_scale; m_tr_clocks_per_tick = ((TPR >> 16) & 0xff) + 2; - m_tr_base_value = prevtr; + m_tr_base_value = m_tr_result; m_tr_base_cycles = total_cycles(); } @@ -499,10 +478,13 @@ TIMER_CALLBACK_MEMBER( hyperstone_device::timer_callback ) /* update the values if necessary */ if (update) + { + compute_tr(); update_timer_prescale(); + } /* see if the timer is right for firing */ - if (!((compute_tr() - TCR) & 0x80000000)) + if (!((m_tr_result - TCR) & 0x80000000)) m_timer_int_pending = 1; /* adjust ourselves for the next time */ @@ -552,7 +534,8 @@ uint32_t hyperstone_device::get_global_register(uint8_t code) /* it is common to poll this in a loop */ if (m_icount > m_tr_clocks_per_tick / 2) m_icount -= m_tr_clocks_per_tick / 2; - return compute_tr(); + compute_tr(); + return m_tr_result; } return m_global_regs[code & 0x1f]; } @@ -606,7 +589,10 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val) case TPR_REGISTER: m_global_regs[code] = val; if (!(val & 0x80000000)) /* change immediately */ + { + compute_tr(); update_timer_prescale(); + } adjust_timer_interrupt(); return; case TCR_REGISTER: @@ -632,15 +618,19 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val) case FCR_REGISTER: if ((m_global_regs[code] ^ val) & 0x00800000) adjust_timer_interrupt(); - m_global_regs[code] = val; + m_global_regs[code] = val; if (m_intblock < 1) m_intblock = 1; return; case MCR_REGISTER: + { // bits 14..12 EntryTableMap - hyperstone_set_trap_entry((val & 0x7000) >> 12); + const int which = (val & 0x7000) >> 12; + assert(which < 4 || which == 7); + m_trap_entry = s_trap_entries[which]; m_global_regs[code] = val; return; + } case 28: case 29: case 30: @@ -1043,6 +1033,7 @@ void hyperstone_device::init(int scale_mask) m_tr_base_cycles = 0; m_tr_base_value = 0; + m_tr_result = 0; m_tr_clocks_per_tick = 0; m_timer_int_pending = 0; @@ -1081,7 +1072,7 @@ void hyperstone_device::init(int scale_mask) for (int i=0; i < 64; i++) { sprintf(buf, "l%d", i); - m_drcuml->symbol_add(&m_global_regs[i], sizeof(uint32_t), buf); + m_drcuml->symbol_add(&m_local_regs[i], sizeof(uint32_t), buf); } m_drcuml->symbol_add(&m_drc_arg0, sizeof(uint32_t), "arg0"); @@ -1328,7 +1319,7 @@ void hyperstone_device::device_reset() m_tr_clocks_per_tick = 2; - hyperstone_set_trap_entry(E132XS_ENTRY_MEM3); /* default entry point @ MEM3 */ + m_trap_entry = s_trap_entries[E132XS_ENTRY_MEM3]; // default entry point @ MEM3 set_global_register(BCR_REGISTER, ~0); set_global_register(MCR_REGISTER, ~0); diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index 93247a4bbc1..14e82bcd3ed 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -65,6 +65,10 @@ class hyperstone_device : public cpu_device public: inline void ccfunc_unimplemented(); inline void ccfunc_print(); + inline void ccfunc_total_cycles(); + void update_timer_prescale(); + void compute_tr(); + void adjust_timer_interrupt(); protected: enum @@ -223,10 +227,13 @@ protected: uint64_t m_tr_base_cycles; uint32_t m_tr_base_value; + uint32_t m_tr_result; uint32_t m_tr_clocks_per_tick; uint8_t m_timer_int_pending; emu_timer *m_timer; + uint64_t m_numcycles; + uint32_t m_delay_pc; uint32_t m_delay_slot; @@ -239,6 +246,7 @@ protected: int m_icount; uint8_t m_fl_lut[16]; + static const uint32_t s_trap_entries[8]; static const int32_t s_immediate_values[16]; uint32_t get_trap_addr(uint8_t trapno); @@ -253,10 +261,6 @@ private: uint32_t get_global_register(uint8_t code); uint32_t get_emu_code_addr(uint8_t num); - void hyperstone_set_trap_entry(int which); - uint32_t compute_tr(); - void update_timer_prescale(); - void adjust_timer_interrupt(); TIMER_CALLBACK_MEMBER(timer_callback); @@ -407,15 +411,15 @@ private: void log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op); bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - int generate_get_trap_addr(drcuml_block *block, int label, uint32_t trapno); - void generate_check_delay_pc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_get_trap_addr(drcuml_block *block, uml::code_label &label, uint32_t trapno); + void generate_check_delay_pc(drcuml_block *block); void generate_decode_const(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - int generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_ignore_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_decode_pcrel(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_ignore_pcrel(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - int generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int label); + void generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_trap(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr); void generate_int(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr); @@ -446,7 +450,7 @@ private: template void generate_xor(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); template void generate_not(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); template void generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); - template int generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template void generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); template void generate_addi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); template void generate_addsi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); template void generate_cmpbi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp index 43dc59dd016..c180cd62f95 100644 --- a/src/devices/cpu/e132xs/e132xsdrc.cpp +++ b/src/devices/cpu/e132xs/e132xsdrc.cpp @@ -7,6 +7,7 @@ using namespace uml; +#define DRC_PC mem(m_global_regs) #define DRC_SR mem(&m_global_regs[1]) void hyperstone_device::execute_run_drc() @@ -44,6 +45,66 @@ void hyperstone_device::execute_run_drc() } while (execute_result != EXECUTE_OUT_OF_CYCLES); } + +/*************************************************************************** + C FUNCTION CALLBACKS +***************************************************************************/ + +/*------------------------------------------------- + cfunc_unimplemented - handler for + unimplemented opcdes +-------------------------------------------------*/ + +inline void hyperstone_device::ccfunc_unimplemented() +{ + fatalerror("PC=%08X: Unimplemented op %08X\n", PC, m_drc_arg0); +} + +inline void hyperstone_device::ccfunc_print() +{ + printf("%c: %08X\n", (char)m_drc_arg0, m_drc_arg1); +} + +static void cfunc_unimplemented(void *param) +{ + ((hyperstone_device *)param)->ccfunc_unimplemented(); +} + +static void cfunc_adjust_timer_interrupt(void *param) +{ + ((hyperstone_device *)param)->adjust_timer_interrupt(); +} + +static void cfunc_compute_tr(void *param) +{ + ((hyperstone_device *)param)->compute_tr(); +} + +static void cfunc_update_timer_prescale(void *param) +{ + ((hyperstone_device *)param)->update_timer_prescale(); +} + +static void cfunc_print(void *param) +{ + ((hyperstone_device *)param)->ccfunc_print(); +} + +/*------------------------------------------------- + ccfunc_total_cycles - compute the total number + of cycles executed so far +-------------------------------------------------*/ + +void hyperstone_device::ccfunc_total_cycles() +{ + m_numcycles = total_cycles(); +} + +static void cfunc_total_cycles(void *param) +{ + ((hyperstone_device *)param)->ccfunc_total_cycles(); +} + /*************************************************************************** CACHE MANAGEMENT ***************************************************************************/ @@ -99,7 +160,7 @@ void hyperstone_device::code_flush_cache() } /* Return the entry point for a determinated trap */ -int hyperstone_device::generate_get_trap_addr(drcuml_block *block, int label, uint32_t trapno) +void hyperstone_device::generate_get_trap_addr(drcuml_block *block, uml::code_label &label, uint32_t trapno) { int no_mem3; UML_MOV(block, I0, trapno); @@ -110,7 +171,6 @@ int hyperstone_device::generate_get_trap_addr(drcuml_block *block, int label, ui UML_LABEL(block, no_mem3); UML_SHL(block, I0, I0, 2); UML_OR(block, I0, I0, mem(&m_trap_entry)); - return label; } /*------------------------------------------------- @@ -196,7 +256,9 @@ void hyperstone_device::code_compile_block(offs_t pc) /* otherwise we just go to the next instruction */ else - nextpc = seqlast->pc + (seqlast->skipslots + 1) * 2; + { + nextpc = seqlast->pc + seqlast->length; + } /* count off cycles and go there */ generate_update_cycles(block, &compiler, nextpc); // @@ -220,37 +282,6 @@ void hyperstone_device::code_compile_block(offs_t pc) } } -/*************************************************************************** - C FUNCTION CALLBACKS -***************************************************************************/ - -/*------------------------------------------------- - cfunc_unimplemented - handler for - unimplemented opcdes --------------------------------------------------*/ - -inline void hyperstone_device::ccfunc_unimplemented() -{ - fatalerror("PC=%08X: Unimplemented op %08X\n", PC, m_drc_arg0); -} - -inline void hyperstone_device::ccfunc_print() -{ - printf("%c: %08X\n", (char)m_drc_arg0, m_drc_arg1); -} - -static void cfunc_unimplemented(void *param) -{ - ((hyperstone_device *)param)->ccfunc_unimplemented(); -} - -#if 0 -static void cfunc_print(void *param) -{ - ((hyperstone_device *)param)->ccfunc_print(); -} -#endif - /*************************************************************************** STATIC CODEGEN ***************************************************************************/ @@ -294,7 +325,8 @@ void hyperstone_device::static_generate_exception(uint32_t exception, const char alloc_handle(drcuml, &exception_handle, name); UML_HANDLE(block, *exception_handle); - generate_get_trap_addr(block, 1, exception); + uml::code_label label = 1; + generate_get_trap_addr(block, label, exception); UML_ROLAND(block, I1, DRC_SR, 7, 0x7f); UML_ROLAND(block, I2, DRC_SR, 11, 0xf); UML_TEST(block, I2, 0xf); @@ -309,7 +341,7 @@ void hyperstone_device::static_generate_exception(uint32_t exception, const char UML_ROLINS(block, DRC_SR, I1, 25, 0xfe000000); UML_AND(block, I3, I1, 0x3f); - UML_AND(block, I1, mem(m_global_regs), ~1); + UML_AND(block, I1, DRC_PC, ~1); UML_ROLAND(block, I2, DRC_SR, 14, 1); UML_OR(block, I1, I1, I2); UML_STORE(block, (void *)m_local_regs, I3, I1, SIZE_DWORD, SCALE_x4); @@ -320,7 +352,7 @@ void hyperstone_device::static_generate_exception(uint32_t exception, const char UML_AND(block, DRC_SR, DRC_SR, ~(M_MASK | T_MASK)); UML_OR(block, DRC_SR, DRC_SR, (L_MASK | S_MASK)); - UML_MOV(block, mem(m_global_regs), I0); + UML_MOV(block, DRC_PC, I0); UML_SUB(block, mem(&m_icount), mem(&m_icount), 2); UML_EXHc(block, COND_S, *m_out_of_cycles, 0); @@ -622,7 +654,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block *block, compi /* if we are debugging, call the debugger */ if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) { - UML_MOV(block, mem(m_global_regs), desc->pc); + UML_MOV(block, DRC_PC, desc->pc); //save_fast_iregs(block); UML_DEBUG(block, desc->pc); } @@ -632,7 +664,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block *block, compi /* compile the instruction */ if (!generate_opcode(block, compiler, desc)) { - UML_MOV(block, mem(m_global_regs), desc->pc); + UML_MOV(block, DRC_PC, desc->pc); UML_MOV(block, mem(&m_drc_arg0), desc->opptr.l[0]); UML_CALLC(block, cfunc_unimplemented, this); } @@ -649,10 +681,9 @@ bool hyperstone_device::generate_opcode(drcuml_block *block, compiler_state *com UML_MOV(block, I0, op); UML_AND(block, I7, DRC_SR, H_MASK); - UML_ADD(block, mem(m_global_regs), mem(m_global_regs), 2); + UML_ADD(block, DRC_PC, DRC_PC, 2); UML_MOV(block, mem(&m_instruction_length), (1 << 19)); - int label = 1; switch (op >> 8) { case 0x00: generate_chk(block, compiler, desc); break; @@ -755,10 +786,10 @@ bool hyperstone_device::generate_opcode(drcuml_block *block, compiler_state *com case 0x61: generate_cmpi(block, compiler, desc); break; case 0x62: generate_cmpi(block, compiler, desc); break; case 0x63: generate_cmpi(block, compiler, desc); break; - case 0x64: label = generate_movi(block, compiler, desc); break; - case 0x65: label = generate_movi(block, compiler, desc); break; - case 0x66: label = generate_movi(block, compiler, desc); break; - case 0x67: label = generate_movi(block, compiler, desc); break; + case 0x64: generate_movi(block, compiler, desc); break; + case 0x65: generate_movi(block, compiler, desc); break; + case 0x66: generate_movi(block, compiler, desc); break; + case 0x67: generate_movi(block, compiler, desc); break; case 0x68: generate_addi(block, compiler, desc); break; case 0x69: generate_addi(block, compiler, desc); break; case 0x6a: generate_addi(block, compiler, desc); break; @@ -919,7 +950,7 @@ bool hyperstone_device::generate_opcode(drcuml_block *block, compiler_state *com int done; UML_AND(block, I0, DRC_SR, (T_MASK | P_MASK)); UML_CMP(block, I0, (T_MASK | P_MASK)); - UML_JMPc(block, uml::COND_NE, done = label++); + UML_JMPc(block, uml::COND_NE, done = compiler->m_labelnum++); UML_TEST(block, mem(&m_delay_slot), 1); UML_EXHc(block, uml::COND_E, *m_exception[EXCEPTION_TRACE], 0); diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx index 4da04f7588d..26d58a071c9 100644 --- a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx +++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx @@ -3,19 +3,51 @@ #include "e132xs.h" -void hyperstone_device::generate_check_delay_pc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +void hyperstone_device::generate_check_delay_pc(drcuml_block *block) { /* if PC is used in a delay instruction, the delayed PC should be used */ UML_TEST(block, mem(&m_delay_slot), 1); - UML_MOVc(block, COND_E, mem(m_global_regs), mem(&m_delay_pc)); - UML_MOVc(block, COND_E, mem(&m_delay_slot), 0); + UML_MOVc(block, uml::COND_NZ, DRC_PC, mem(&m_delay_pc)); + UML_MOVc(block, uml::COND_NZ, mem(&m_delay_slot), 0); } void hyperstone_device::generate_decode_const(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { + int half_read; + UML_READ(block, I1, DRC_PC, SIZE_WORD, SPACE_PROGRAM); + UML_ADD(block, DRC_PC, DRC_PC, 2); + UML_TEST(block, I1, 0x8000); + UML_JMPc(block, uml::COND_Z, half_read = compiler->m_labelnum++); + + UML_MOV(block, mem(&m_instruction_length), (3<<19)); + + int skip; + UML_SHL(block, I1, I1, 16); + UML_AND(block, I2, I1, 0x3fff0000); + UML_TEST(block, I1, 0x40000000); + UML_MOVc(block, uml::COND_Z, I1, I2); + UML_JMPc(block, uml::COND_Z, skip = compiler->m_labelnum++); + UML_OR(block, I1, I2, 0xc0000000); + UML_LABEL(block, skip); + UML_READ(block, I2, DRC_PC, SIZE_WORD, SPACE_PROGRAM); + UML_ADD(block, DRC_PC, DRC_PC, 2); + UML_OR(block, I1, I1, I2); + + int done; + UML_JMP(block, done = compiler->m_labelnum++); + + UML_LABEL(block, half_read); + UML_MOV(block, mem(&m_instruction_length), (2<<19)); + UML_TEST(block, I1, 0x4000); + UML_MOVc(block, uml::COND_NZ, I2, 0xffffc000); + UML_MOVc(block, uml::COND_Z, I2, 0); + UML_AND(block, I1, I1, 0x3fff); + UML_OR(block, I1, I1, I2); + + UML_LABEL(block, done); } -int hyperstone_device::generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +void hyperstone_device::generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { static int32_t immediate_values[16] = { @@ -23,25 +55,24 @@ int hyperstone_device::generate_decode_immediate_s(drcuml_block *block, compiler -8, -7, -6, -5, -4, -3, -2, -1 }; - int label = 1; int nolut, done, zero_or_one, three; UML_AND(block, I1, I0, 0x0f); UML_CMP(block, I1, 4); - UML_JMPc(block, COND_L, nolut = label++); + UML_JMPc(block, COND_L, nolut = compiler->m_labelnum++); // 4..f, immediate lookup UML_LOAD(block, I1, (void *)immediate_values, I1, SIZE_DWORD, SCALE_x4); - UML_JMP(block, done = label++); + UML_JMP(block, done = compiler->m_labelnum++); UML_LABEL(block, nolut); UML_CMP(block, I1, 2); - UML_JMPc(block, COND_L, zero_or_one = label++); - UML_JMPc(block, COND_G, three = label++); + UML_JMPc(block, COND_L, zero_or_one = compiler->m_labelnum++); + UML_JMPc(block, COND_G, three = compiler->m_labelnum++); // 2 UML_MOV(block, mem(&m_instruction_length), (2<<19)); - UML_READ(block, I1, mem(m_global_regs), SIZE_WORD, SPACE_PROGRAM); + UML_READ(block, I1, DRC_PC, SIZE_WORD, SPACE_PROGRAM); UML_JMP(block, done); // 0..1 @@ -52,22 +83,21 @@ int hyperstone_device::generate_decode_immediate_s(drcuml_block *block, compiler // 1 UML_MOV(block, mem(&m_instruction_length), (3<<19)); - UML_READ(block, I1, mem(m_global_regs), SIZE_WORD, SPACE_PROGRAM); + UML_READ(block, I1, DRC_PC, SIZE_WORD, SPACE_PROGRAM); UML_SHL(block, I1, I1, 16); - UML_ADD(block, mem(m_global_regs), mem(m_global_regs), 2); - UML_READ(block, I2, mem(m_global_regs), SIZE_WORD, SPACE_PROGRAM); - UML_ADD(block, mem(m_global_regs), mem(m_global_regs), 2); + UML_ADD(block, DRC_PC, DRC_PC, 2); + UML_READ(block, I2, DRC_PC, SIZE_WORD, SPACE_PROGRAM); + UML_ADD(block, DRC_PC, DRC_PC, 2); UML_JMP(block, done); // 3 UML_LABEL(block, three); UML_MOV(block, mem(&m_instruction_length), (2<<19)); - UML_READ(block, I1, mem(m_global_regs), SIZE_WORD, SPACE_PROGRAM); + UML_READ(block, I1, DRC_PC, SIZE_WORD, SPACE_PROGRAM); UML_SEXT(block, I1, I1, SIZE_WORD); // fall through to done UML_LABEL(block, done); - return label; } void hyperstone_device::generate_ignore_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) @@ -82,10 +112,108 @@ void hyperstone_device::generate_ignore_pcrel(drcuml_block *block, compiler_stat { } -int hyperstone_device::generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int label) +void hyperstone_device::generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { - // Expects register index in I0, value in I1 - return label; + // Expects register index in I4, value in I5, clobbers I6 + int extended; + UML_CMP(block, I4, 16); + UML_JMPc(block, uml::COND_AE, extended = compiler->m_labelnum++); + + int generic_store, set_sr, done; + UML_CMP(block, I4, 1); + UML_JMPc(block, uml::COND_A, generic_store = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, set_sr = compiler->m_labelnum++); + UML_AND(block, DRC_PC, I5, ~1); + generate_delay_slot_and_branch(block, compiler, desc); + UML_JMP(block, done = compiler->m_labelnum++); + + UML_LABEL(block, set_sr); + UML_ROLINS(block, DRC_SR, I5, 0, 0x0000ffff); + UML_AND(block, DRC_SR, DRC_SR, ~0x40); + UML_TEST(block, mem(&m_intblock), ~0); + UML_MOVc(block, uml::COND_Z, mem(&m_intblock), 1); + UML_JMP(block, done); + + UML_LABEL(block, generic_store); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_JMP(block, done); + + int above_bcr; + UML_LABEL(block, extended); + UML_CMP(block, I4, 17); + UML_JMPc(block, uml::COND_BE, generic_store); + UML_CMP(block, I4, BCR_REGISTER); + UML_JMPc(block, uml::COND_A, above_bcr = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, generic_store); + + // SP or UB + UML_AND(block, I5, I5, ~3); + UML_JMP(block, generic_store); + + int set_tpr, set_tcr, set_tr, set_fcr; + UML_LABEL(block, above_bcr); + UML_CMP(block, I4, TCR_REGISTER); + UML_JMPc(block, uml::COND_B, set_tpr = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, set_tcr = compiler->m_labelnum++); + // Above TCR + UML_CMP(block, I4, WCR_REGISTER); + UML_JMPc(block, uml::COND_B, set_tr = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, generic_store); // WCR + // Above WCR + UML_CMP(block, I4, FCR_REGISTER); + UML_JMPc(block, uml::COND_B, done); // ISR - read only + UML_JMPc(block, uml::COND_E, set_fcr = compiler->m_labelnum++); + UML_CMP(block, I4, MCR_REGISTER); + UML_JMPc(block, uml::COND_A, generic_store); // regs 28..31 + // Set MCR + UML_ROLAND(block, I6, I5, 20, 0x7); + UML_LOAD(block, I6, (void *)s_trap_entries, I6, SIZE_DWORD, SCALE_x4); + UML_MOV(block, mem(&m_trap_entry), I6); + UML_JMP(block, generic_store); + + int skip_compute_tr; + UML_LABEL(block, set_tpr); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_TEST(block, I5, 0x80000000); + UML_JMPc(block, uml::COND_NZ, skip_compute_tr = compiler->m_labelnum++); + UML_CALLC(block, cfunc_compute_tr, this); + UML_CALLC(block, cfunc_update_timer_prescale, this); + UML_LABEL(block, skip_compute_tr); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_JMP(block, done); + + UML_LABEL(block, set_tcr); + UML_LOAD(block, I6, (void *)m_global_regs, I4, SIZE_DWORD, SCALE_x4); + UML_CMP(block, I6, I5); + UML_JMPc(block, uml::COND_E, done); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_CMP(block, mem(&m_intblock), 1); + UML_MOVc(block, uml::COND_L, mem(&m_intblock), 1); + UML_JMP(block, done); + + UML_LABEL(block, set_tr); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_MOV(block, mem(&m_tr_base_value), I5); + UML_CALLC(block, cfunc_total_cycles, this); + UML_DMOV(block, mem(&m_tr_base_cycles), mem(&m_numcycles)); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_JMP(block, done); + + int skip_adjust_timer; + UML_LABEL(block, set_fcr); + UML_LOAD(block, I6, (void *)m_global_regs, I4, SIZE_DWORD, SCALE_x4); + UML_XOR(block, I6, I6, I5); + UML_TEST(block, I6, 0x80000000); + UML_JMPc(block, uml::COND_Z, skip_adjust_timer = compiler->m_labelnum++); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_LABEL(block, skip_adjust_timer); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_CMP(block, mem(&m_intblock), 1); + UML_MOVc(block, uml::COND_L, mem(&m_intblock), 1); + // Fall through to done + + UML_LABEL(block, done); } void hyperstone_device::generate_trap(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr) @@ -132,12 +260,111 @@ void hyperstone_device::generate_xm(drcuml_block *block, compiler_state *compile template void hyperstone_device::generate_mask(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { + generate_decode_const(block, compiler, desc); + generate_check_delay_pc(block); + UML_AND(block, I2, I0, 0x000f); + if (!SRC_GLOBAL || !DST_GLOBAL) + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + } + + if (SRC_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, I2, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ADD(block, I2, I2, I3); + UML_AND(block, I2, I2, 0x3f); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, I1, I2, I1); + + int skip_mask; + UML_AND(block, DRC_SR, DRC_SR, ~Z_MASK); + UML_TEST(block, I1, ~0); + UML_JMPc(block, uml::COND_NZ, skip_mask = compiler->m_labelnum++); + UML_OR(block, DRC_SR, DRC_SR, Z_MASK); + UML_LABEL(block, skip_mask); + + if (DST_GLOBAL) + { + UML_ROLAND(block, I4, I0, 28, 0xf); + UML_MOV(block, I5, I2); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I0, I0, 28, 0xf); + UML_ADD(block, I0, I0, I3); + UML_AND(block, I0, I0, 0x3f); + UML_STORE(block, (void *)m_local_regs, I0, I1, SIZE_DWORD, SCALE_x4); + } } template void hyperstone_device::generate_sum(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { + generate_decode_const(block, compiler, desc); + generate_check_delay_pc(block); + UML_AND(block, I2, I0, 0x000f); + if (!SRC_GLOBAL || !DST_GLOBAL) + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + } + + if (SRC_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, I2, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ADD(block, I2, I2, I3); + UML_AND(block, I2, I2, 0x3f); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_MOV(block, mem(&m_drc_arg0), (uint32_t)'Q'); + UML_MOV(block, mem(&m_drc_arg1), I1); + UML_CALLC(block, cfunc_print, this); + UML_MOV(block, mem(&m_drc_arg0), (uint32_t)'R'); + UML_MOV(block, mem(&m_drc_arg1), I2); + UML_CALLC(block, cfunc_print, this); + UML_DADD(block, I5, I1, I2); + + UML_AND(block, DRC_SR, DRC_SR, ~(C_MASK | V_MASK | Z_MASK | N_MASK)); + UML_DTEST(block, I5, 0x100000000U); + UML_SETc(block, uml::COND_NZ, I6); + UML_ROLINS(block, DRC_SR, I6, 0, C_MASK); + + UML_XOR(block, I1, I5, I2); + UML_XOR(block, I6, I5, I1); + UML_AND(block, I1, I1, I6); + UML_TEST(block, I1, 0x80000000); + UML_SETc(block, uml::COND_NZ, I6); + UML_ROLINS(block, DRC_SR, I6, 0, V_MASK); + + UML_TEST(block, I5, ~0); + UML_SETc(block, uml::COND_Z, I6); + UML_ROLINS(block, DRC_SR, I6, 0, Z_MASK); + + UML_TEST(block, I5, 0x80000000); + UML_SETc(block, uml::COND_NZ, I6); + UML_ROLINS(block, DRC_SR, I6, 0, N_MASK); + + UML_ROLAND(block, I4, I0, 28, 0xf); + if (DST_GLOBAL) + { + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I0, I4, I3); + UML_AND(block, I2, I0, 0x3f); + UML_STORE(block, (void *)m_local_regs, I0, I1, SIZE_DWORD, SCALE_x4); + } } @@ -246,42 +473,90 @@ void hyperstone_device::generate_not(drcuml_block *block, compiler_state *compil template void hyperstone_device::generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { -} - - -template -int hyperstone_device::generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) -{ - int label = 1; if (IMM_LONG) { - label = generate_decode_immediate_s(block, compiler, desc); // I1 <-- imm32 + generate_decode_immediate_s(block, compiler, desc); // I1 <-- imm32 } else { UML_AND(block, I1, I0, 0xf); } - int done = label++; + generate_check_delay_pc(block); + + UML_ROLAND(block, I2, I0, 28, 0xf); + if (DST_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, I2, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I2, I3); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, DRC_SR, DRC_SR, ~(V_MASK | Z_MASK | N_MASK | C_MASK)); + UML_DSUB(block, I0, I2, I1); + + int no_v; + UML_XOR(block, I0, I0, I2); + UML_XOR(block, I3, I1, I2); + UML_AND(block, I0, I0, I3); + UML_TEST(block, I0, 0x80000000); + UML_JMPc(block, uml::COND_Z, no_v = compiler->m_labelnum++); + UML_OR(block, DRC_SR, DRC_SR, V_MASK); + UML_LABEL(block, no_v); + + int no_n; + UML_MOV(block, I3, 0); + UML_CMP(block, I2, I1); + UML_MOVc(block, uml::COND_E, I3, Z_MASK); + UML_MOVc(block, uml::COND_B, I3, C_MASK); + UML_JMPc(block, uml::COND_L, no_n = compiler->m_labelnum++); + UML_OR(block, I3, I3, N_MASK); + UML_LABEL(block, no_n); + UML_OR(block, DRC_SR, DRC_SR, I3); + + UML_CMP(block, I2, I1); + +} + + +template +void hyperstone_device::generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + if (IMM_LONG) + { + generate_decode_immediate_s(block, compiler, desc); // I1 <-- imm32 + } + else + { + UML_AND(block, I1, I0, 0xf); + } + + generate_check_delay_pc(block); + + int done; if (DST_GLOBAL) { UML_AND(block, I2, mem(&m_global_regs[1]), H_MASK); UML_TEST(block, mem(&m_global_regs[1]), S_MASK); UML_EXHc(block, uml::COND_Z, *m_exception[EXCEPTION_PRIVILEGE_ERROR], 0); - UML_JMPc(block, uml::COND_Z, done); + UML_JMPc(block, uml::COND_Z, done = compiler->m_labelnum++); } UML_AND(block, DRC_SR, DRC_SR, ~(Z_MASK | N_MASK)); int no_z; UML_TEST(block, I1, ~0); - UML_JMPc(block, uml::COND_NZ, no_z = label++); + UML_JMPc(block, uml::COND_NZ, no_z = compiler->m_labelnum++); UML_OR(block, DRC_SR, DRC_SR, Z_MASK); UML_LABEL(block, no_z); int no_n; UML_TEST(block, I1, 0x80000000); - UML_JMPc(block, uml::COND_Z, no_n = label++); + UML_JMPc(block, uml::COND_Z, no_n = compiler->m_labelnum++); UML_OR(block, DRC_SR, DRC_SR, N_MASK); UML_LABEL(block, no_n); @@ -289,22 +564,22 @@ int hyperstone_device::generate_movi(drcuml_block *block, compiler_state *compil UML_AND(block, DRC_SR, DRC_SR, ~V_MASK); #endif - UML_ROLAND(block, I0, I0, 30, 0x3c); - if (DST_GLOBAL) { - int no_pc; + UML_ROLAND(block, I4, I0, 28, 0xf); + UML_TEST(block, I2, ~0); + UML_MOVc(block, uml::COND_NZ, I2, 16); + UML_MOVc(block, uml::COND_Z, I2, 0); + UML_ADD(block, I4, I4, I2); + UML_MOV(block, I5, I1); + generate_set_global_register(block, compiler, desc); + UML_TEST(block, I0, 0xf0); - UML_JMPc(block, uml::COND_NZ, no_pc = label++); - UML_AND(block, mem(m_global_regs), I1, ~1); + UML_JMPc(block, uml::COND_NZ, done); UML_AND(block, DRC_SR, DRC_SR, ~M_MASK); generate_delay_slot_and_branch(block, compiler, desc); - UML_JMP(block, done); - UML_LABEL(block, no_pc); - - // TODO - UML_JMP(block, done); + UML_LABEL(block, done); } else { @@ -313,9 +588,6 @@ int hyperstone_device::generate_movi(drcuml_block *block, compiler_state *compil UML_AND(block, I0, I0, 0x3f); UML_STORE(block, (void *)m_local_regs, I0, I1, SIZE_DWORD, SCALE_x4); } - - UML_LABEL(block, done); - return label; } @@ -346,6 +618,44 @@ void hyperstone_device::generate_andni(drcuml_block *block, compiler_state *comp template void hyperstone_device::generate_ori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { + if (IMM_LONG) + { + generate_decode_immediate_s(block, compiler, desc); // I1 <-- imm32 + } + else + { + UML_AND(block, I1, I0, 0xf); + } + + generate_check_delay_pc(block); + + UML_ROLAND(block, I2, I0, 28, 0xf); + if (DST_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, I2, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I2, I3); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, DRC_SR, DRC_SR, ~Z_MASK); + UML_OR(block, I5, I2, I1); + UML_ROLAND(block, I4, I0, 28, 0xf); + + if (DST_GLOBAL) + { + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I4, I0, 28, 0xf); + UML_ADD(block, I4, I4, I2); + UML_AND(block, I4, I4, 0x3f); + UML_STORE(block, (void *)m_local_regs, I4, I5, SIZE_DWORD, SCALE_x4); + } } diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e132xsfe.cpp index c13e72f8e89..8d4848373a3 100644 --- a/src/devices/cpu/e132xs/e132xsfe.cpp +++ b/src/devices/cpu/e132xs/e132xsfe.cpp @@ -28,10 +28,21 @@ e132xs_frontend::e132xs_frontend(hyperstone_device *e132xs, uint32_t window_star { } -/*------------------------------------------------- - describe_instruction - build a description - of a single instruction --------------------------------------------------*/ +inline uint32_t e132xs_frontend::imm_length(opcode_desc &desc, uint16_t op) +{ + uint8_t nybble = op & 0x0f; + switch (nybble) + { + case 0: + default: + return 2; + case 1: + return 6; + case 2: + case 3: + return 4; + } +} inline uint16_t e132xs_frontend::read_word(opcode_desc &desc) { @@ -142,6 +153,12 @@ inline int32_t e132xs_frontend::decode_call(opcode_desc &desc) return extra_s; } + +/*------------------------------------------------- + describe - build a description of a single + instruction +-------------------------------------------------*/ + bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) { uint16_t op = desc.opptr.w[0] = read_word(desc); @@ -164,6 +181,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) const uint32_t lsrc_group = 1 + (((SRC_CODE + fp) & 0x20) >> 5); const uint32_t lsrcf_group = 1 + ((SRC_CODE + fp + 1) >> 5); + printf("physpc: %08x\n", desc.physpc); switch (op >> 8) { case 0x00: // chk global,global @@ -612,7 +630,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x71: // cmpbi global,limm desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); break; case 0x62: // cmpi local,simm case 0x72: // cmpbi local,simm @@ -625,7 +643,8 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= SR_CODE; desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); + printf("%04x, %d\n", read_imm1(desc), desc.length); break; case 0x64: // movi global,simm desc.regin[0] |= SR_CODE; @@ -644,7 +663,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= 1 << (gdst_code + 16); desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; if (gdst_code == PC_REGISTER) { @@ -661,7 +680,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= SR_CODE; desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); break; case 0x68: // addi global,simm case 0x6c: // addsi global,simm @@ -670,6 +689,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; case 0x69: // addi global,limm case 0x6d: // addsi global,limm @@ -677,8 +701,13 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; case 0x6a: // addi local,simm case 0x6e: // addsi local,simm @@ -694,7 +723,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi break; case 0x74: // andni global,simm @@ -704,6 +733,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; case 0x75: // andni global,limm case 0x79: // ori global,limm @@ -712,7 +746,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[0] |= 1 << gdst_code; desc.regout[0] |= 1 << gdst_code; desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; case 0x76: // andni local,simm case 0x7a: // ori local,simm @@ -729,7 +768,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.regin[ldst_group] |= 1 << ldst_code; desc.regout[ldst_group] |= 1 << ldst_code; desc.regout[0] |= SR_CODE; - desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + desc.length = imm_length(desc, op); break; case 0x80: case 0x81: // shrdi case 0x84: case 0x85: // sardi @@ -777,6 +816,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; } case 0x91: // ldxx1 global,local @@ -791,6 +835,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; } case 0x92: // ldxx1 local,global @@ -833,6 +882,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; } case 0x95: // ldxx2 global,local @@ -848,6 +902,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.length = (imm1 & 0x8000) ? 6 : 4; desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } break; } case 0x96: // ldxx2 local,global diff --git a/src/devices/cpu/e132xs/e132xsfe.h b/src/devices/cpu/e132xs/e132xsfe.h index 1cac61a08cd..7463fd964d0 100644 --- a/src/devices/cpu/e132xs/e132xsfe.h +++ b/src/devices/cpu/e132xs/e132xsfe.h @@ -19,6 +19,7 @@ protected: virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override; private: + inline uint32_t imm_length(opcode_desc &desc, uint16_t op); inline uint16_t read_word(opcode_desc &desc); inline uint16_t read_imm1(opcode_desc &desc); inline uint16_t read_imm2(opcode_desc &desc); diff --git a/src/devices/cpu/e132xs/e132xsop.hxx b/src/devices/cpu/e132xs/e132xsop.hxx index 22b39a70818..1f15399cb3d 100644 --- a/src/devices/cpu/e132xs/e132xsop.hxx +++ b/src/devices/cpu/e132xs/e132xsop.hxx @@ -1101,11 +1101,11 @@ void hyperstone_device::hyperstone_ori() if (!IMM_LONG) imm = m_op & 0x0f; - uint32_t dreg; + if (DST_GLOBAL) { const uint32_t dst_code = DST_CODE; - dreg = m_global_regs[dst_code] | imm; + const uint32_t dreg = m_global_regs[dst_code] | imm; if (dreg) SR &= ~Z_MASK; @@ -1117,7 +1117,7 @@ void hyperstone_device::hyperstone_ori() else { const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; - dreg = m_local_regs[dst_code] |= imm; + const uint32_t dreg = m_local_regs[dst_code] |= imm; if (dreg) SR &= ~Z_MASK; diff --git a/src/devices/cpu/uml.h b/src/devices/cpu/uml.h index 1b60d46cd8b..be32dedd724 100644 --- a/src/devices/cpu/uml.h +++ b/src/devices/cpu/uml.h @@ -73,20 +73,20 @@ namespace uml COND_NV, // requires V COND_U, // requires U COND_NU, // requires U - COND_A, // requires CZ - COND_BE, // requires CZ - COND_G, // requires SVZ - COND_LE, // requires SVZ - COND_L, // requires SV - COND_GE, // requires SV + COND_A, // requires CZ, unsigned + COND_BE, // requires CZ, unsigned + COND_G, // requires SVZ, signed + COND_LE, // requires SVZ, signed + COND_L, // requires SV, signed + COND_GE, // requires SV, signed COND_MAX, // basic condition code aliases COND_E = COND_Z, COND_NE = COND_NZ, - COND_B = COND_C, - COND_AE = COND_NC + COND_B = COND_C, // unsigned + COND_AE = COND_NC // unsigned }; // floating point rounding modes