e132xs: Added mask, sum, cmpi, movi, and ori, nw

This commit is contained in:
mooglyguy 2017-11-28 21:44:53 +01:00
parent bccc962b69
commit ad5172a47d
8 changed files with 558 additions and 162 deletions

View File

@ -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);

View File

@ -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 <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_xor(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_not(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> int generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addsi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpbi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);

View File

@ -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); // <subtract cycles>
@ -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<GLOBAL, GLOBAL>(block, compiler, desc); break;
@ -755,10 +786,10 @@ bool hyperstone_device::generate_opcode(drcuml_block *block, compiler_state *com
case 0x61: generate_cmpi<GLOBAL, LIMM>(block, compiler, desc); break;
case 0x62: generate_cmpi<LOCAL, SIMM>(block, compiler, desc); break;
case 0x63: generate_cmpi<LOCAL, LIMM>(block, compiler, desc); break;
case 0x64: label = generate_movi<GLOBAL, SIMM>(block, compiler, desc); break;
case 0x65: label = generate_movi<GLOBAL, LIMM>(block, compiler, desc); break;
case 0x66: label = generate_movi<LOCAL, SIMM>(block, compiler, desc); break;
case 0x67: label = generate_movi<LOCAL, LIMM>(block, compiler, desc); break;
case 0x64: generate_movi<GLOBAL, SIMM>(block, compiler, desc); break;
case 0x65: generate_movi<GLOBAL, LIMM>(block, compiler, desc); break;
case 0x66: generate_movi<LOCAL, SIMM>(block, compiler, desc); break;
case 0x67: generate_movi<LOCAL, LIMM>(block, compiler, desc); break;
case 0x68: generate_addi<GLOBAL, SIMM>(block, compiler, desc); break;
case 0x69: generate_addi<GLOBAL, LIMM>(block, compiler, desc); break;
case 0x6a: generate_addi<LOCAL, SIMM>(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);

View File

@ -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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
void hyperstone_device::generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
{
}
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG>
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);
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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