summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2018-12-25 17:41:15 +0100
committer mooglyguy <therealmogminer@gmail.com>2018-12-25 17:41:27 +0100
commit1cd0c119083d95aa60f1025a74d96f0646ad3da1 (patch)
tree49e842e4a13c6e2e62f9c34ed88e3943e7271d4d
parent46ade7d73dae018c0fa75b85da30b05b03a6c943 (diff)
-dspp: Preliminary DRC. Still disabled by default. [Ryan Holtz]
-rw-r--r--src/devices/cpu/dspp/dspp.cpp116
-rw-r--r--src/devices/cpu/dspp/dspp.h103
-rw-r--r--src/devices/cpu/dspp/dsppdrc.cpp1259
-rw-r--r--src/devices/cpu/dspp/dsppfe.cpp331
-rw-r--r--src/devices/cpu/dspp/dsppfe.h9
5 files changed, 999 insertions, 819 deletions
diff --git a/src/devices/cpu/dspp/dspp.cpp b/src/devices/cpu/dspp/dspp.cpp
index 411365bbc29..e8488d73708 100644
--- a/src/devices/cpu/dspp/dspp.cpp
+++ b/src/devices/cpu/dspp/dspp.cpp
@@ -33,8 +33,8 @@ enum
#define SINGLE_INSTRUCTION_MODE (0)
-#define CACHE_SIZE (4 * 1024 * 1024) // FIXME
-// FIXME!!!
+#define CACHE_SIZE (4 * 1024 * 1024)
+
/* compilation boundaries -- how far back/forward does the analysis extend? */
#define COMPILE_BACKWARDS_BYTES 128
#define COMPILE_FORWARDS_BYTES 512
@@ -47,56 +47,6 @@ enum
#define EXECUTE_UNMAPPED_CODE 2
#define EXECUTE_RESET_CACHE 3
-
-
-
-//**************************************************************************
-// MACROS
-//**************************************************************************
-
-//#define DSPI_FLAG_CC_CARRY 0x0001
-//#define DSPI_FLAG_CC_ZERO 0x0002
-//#define DSPI_FLAG_CC_NEG 0x0004
-//#define DSPI_FLAG_CC_OVER 0x0008
-//#define DSPI_FLAG_CC_EXACT 0x0010
-//#define DSPI_FLAG_AUDLOCK 0x0020
-//#define DSPI_FLAG_SLEEP 0x0040
-//#define DSPI_FLAG_CC_MASK 0x001f
-
-#define DSPX_CONTROL_GWILLING 0x0001
-#define DSPX_CONTROL_STEP_CYCLE 0x0002
-#define DSPX_CONTROL_STEP_PC 0x0004
-#define DSPX_CONTROL_SNOOP 0x0008
-
-#define DSPX_RESET_DSPP 0x0001
-#define DSPX_RESET_INPUT 0x0002
-#define DSPX_RESET_OUTPUT 0x0004
-
-#define DSPX_F_DMA_NEXTVALID 0x0001
-#define DSPX_F_DMA_GO_FOREVER 0x0002
-#define DSPX_F_INT_DMANEXT_EN 0x0004
-#define DSPX_F_SHADOW_SET_DMANEXT 0x00040000
-#define DSPX_F_SHADOW_SET_FOREVER 0x00020000
-#define DSPX_F_SHADOW_SET_NEXTVALID 0x00010000
-#define DSPX_F_SHADOW_SET_ADDRESS_COUNT 0x80000000
-
-#define DSPX_F_INT_TIMER 0x00000100
-#define DSPX_F_INT_INPUT_UNDER 0x00000080
-#define DSPX_F_INT_INPUT_OVER 0x00000040
-#define DSPX_F_INT_OUTPUT_UNDER 0x00000020
-#define DSPX_F_INT_OUTPUT_OVER 0x00000010
-#define DSPX_F_INT_UNDEROVER 0x00000008
-#define DSPX_F_INT_CONSUMED 0x00000002
-#define DSPX_F_INT_DMANEXT 0x00000001
-
-#define DSPX_F_INT_ALL_DMA (DSPX_F_INT_DMANEXT | DSPX_F_INT_CONSUMED | DSPX_F_INT_UNDEROVER)
-
-#define DSPX_FLD_INT_SOFT_WIDTH 16 /* width of the field and the number of interrupts */
-#define DSPX_FLD_INT_SOFT_SHIFT 16
-#define DSPX_FLD_INT_SOFT_MASK (0xffff0000)
-
-
-
//**************************************************************************
// INTERNAL MEMORY MAPS
//**************************************************************************
@@ -153,7 +103,6 @@ dspp_device::dspp_device(const machine_config &mconfig, device_type type, const
m_data(nullptr),
m_output_fifo_start(0),
m_output_fifo_count(0),
- m_dspx_control(0),
m_dspx_reset(0),
m_dspx_int_enable(0),
m_dspx_channel_enable(0),
@@ -194,7 +143,6 @@ dspp_device::dspp_device(const machine_config &mconfig, device_type type, const
void dspp_device::device_start()
{
- // DSPP DRC is not yet ready for prime time
m_isdrc = false;//allow_drc();
m_core = (dspp_internal_state *)m_cache.alloc_near(sizeof(dspp_internal_state));
@@ -215,6 +163,7 @@ void dspp_device::device_start()
m_data = &space(AS_DATA);
auto code_cache = m_code->cache<1, -1, ENDIANNESS_BIG>();
m_code_cache = code_cache;
+ m_code16 = [code_cache](offs_t address) -> uint16_t { return code_cache->read_word(address); };
m_codeptr = [code_cache](offs_t address) -> const void * { return code_cache->read_ptr(address); };
// Register our state for the debugger
@@ -275,7 +224,7 @@ void dspp_device::device_start()
save_item(NAME(m_core->m_partial_int));
- save_item(NAME(m_dspx_control));
+ save_item(NAME(m_core->m_dspx_control));
save_item(NAME(m_dspx_reset));
save_item(NAME(m_dspx_int_enable));
save_item(NAME(m_dspx_channel_enable));
@@ -489,8 +438,8 @@ void dspp_device::parse_operands(uint32_t numops)
for (uint32_t i = 0; i < MAX_OPERANDS; ++i)
{
// Reset operands
- m_operands[i].value = -1;
- m_operands[i].addr = -1;
+ m_core->m_operands[i].value = -1;
+ m_core->m_operands[i].addr = -1;
}
// Reset global op index
@@ -520,7 +469,7 @@ void dspp_device::parse_operands(uint32_t numops)
if (val & 0x1000)
val |= 0xe000;
}
- m_operands[opidx++].value = val;
+ m_core->m_operands[opidx++].value = val;
}
else if((operand & 0xe000) == 0x8000)
{
@@ -532,14 +481,14 @@ void dspp_device::parse_operands(uint32_t numops)
// Indirect
addr = read_data(addr);
}
- m_operands[opidx].addr = addr;
+ m_core->m_operands[opidx].addr = addr;
if (operand & 0x0800)
{
// Write Back
m_core->m_writeback = addr;
}
- ++opidx;
+ opidx++;
}
else if ((operand & 0xe000) == 0xa000)
{
@@ -582,7 +531,7 @@ void dspp_device::parse_operands(uint32_t numops)
m_core->m_writeback = addr;
}
- m_operands[opidx++].addr = addr;
+ m_core->m_operands[opidx++].addr = addr;
}
numregs = 0;
}
@@ -597,10 +546,14 @@ void dspp_device::parse_operands(uint32_t numops)
uint16_t dspp_device::read_next_operand()
{
- int32_t value = m_operands[m_core->m_opidx].value;
+ int32_t value = m_core->m_operands[m_core->m_opidx].value;
+ //if (m_core->m_op == 0x46a0) printf("Value is %08x\n", value);
if (value < 0)
- value = read_data(m_operands[m_core->m_opidx].addr);
+ {
+ value = read_data(m_core->m_operands[m_core->m_opidx].addr);
+ //if (m_core->m_op == 0x46a0) printf("New value is %08x from %08x\n", value, m_core->m_operands[m_core->m_opidx].addr);
+ }
// Next operand
++m_core->m_opidx;
@@ -616,7 +569,7 @@ uint16_t dspp_device::read_next_operand()
void dspp_device::write_next_operand(uint16_t value)
{
- int32_t addr = m_operands[m_core->m_opidx].addr;
+ int32_t addr = m_core->m_operands[m_core->m_opidx].addr;
assert(addr != -1);
@@ -724,11 +677,19 @@ void dspp_device::execute_run()
{
if (m_isdrc)
{
- // TODO: TEMPORARY HACK!
- if (m_dspx_control & DSPX_CONTROL_GWILLING)
- execute_run_drc();
- else
- m_core->m_icount = 0;
+ // Only run if enabled
+ do
+ {
+ if (m_core->m_dspx_control & DSPX_CONTROL_GWILLING)
+ {
+ execute_run_drc();
+ }
+ else
+ {
+ update_ticks();
+ update_fifo_dma();
+ }
+ } while (m_core->m_icount > 0);
return;
}
@@ -740,12 +701,13 @@ void dspp_device::execute_run()
update_fifo_dma();
// Only run if enabled
- if (m_dspx_control & DSPX_CONTROL_GWILLING)
+ if (m_core->m_dspx_control & DSPX_CONTROL_GWILLING)
{
if (check_debugger)
debugger_instruction_hook(m_core->m_pc);
m_core->m_op = read_op(m_core->m_pc);
+ //printf("%04x: %04x\n", (uint16_t)m_core->m_pc, (uint16_t)m_core->m_op);
update_pc();
// Decode and execute
@@ -845,7 +807,6 @@ inline void dspp_device::exec_special()
if (regdi & 0x0010)
{
addr = read_data(addr);
- break;
}
parse_operands(1);
@@ -908,6 +869,8 @@ void dspp_device::exec_branch()
if (mode == 2)
branch = !branch;
+ //printf("Branch: %d %d %d %d %d\n", branch ? 1 : 0, flag0 ? 1 : 0, mask0 ? 1 : 0, flag1 ? 1 : 0, mask1 ? 1 : 0);
+
if (branch)
m_core->m_pc = m_core->m_op & 0x3ff;
}
@@ -1072,6 +1035,9 @@ inline void dspp_device::exec_arithmetic()
int32_t alu_a, alu_b;
+ //if (m_core->m_op == 0x46a0)
+ //printf("Arithmetic: numops:%d, muxa:%d, muxb:%d, alu_op:%d, barrel_code:%d\n", numops, muxa, muxb, alu_op, barrel_code);
+
switch (muxa)
{
case 0:
@@ -1082,6 +1048,8 @@ inline void dspp_device::exec_arithmetic()
case 1: case 2:
{
alu_a = read_next_operand() << 4;
+ //if (m_core->m_op == 0x46a0)
+ //printf("Arithmetic: Next operand: %04x\n", alu_a >> 4);
break;
}
case 3:
@@ -2122,7 +2090,7 @@ uint32_t dspp_device::read_ext_control(offs_t offset)
// DSPX_CONTROL
case 0x6070/4:
{
- data = m_dspx_control;
+ data = m_core->m_dspx_control;
break;
}
default:
@@ -2346,7 +2314,7 @@ void dspp_device::write_ext_control(offs_t offset, uint32_t data)
// DSPX_CONTROL
case 0x6070/4:
{
- m_dspx_control = data;
+ m_core->m_dspx_control = data;
break;
}
@@ -2620,7 +2588,7 @@ void dspp_device::dump_state()
char buffer[64];
printf("\n=== GLOBAL REGISTER===\n");
- printf("DSPX_CONTROL: %08X\n", m_dspx_control);
+ printf("DSPX_CONTROL: %08X\n", m_core->m_dspx_control);
printf("DSPX_RESET: %08X\n", m_dspx_reset);
printf("DSPX_INT_ENABLE: %08X\n", m_dspx_int_enable);
printf("DSPX_CHANNEL_ENABLE: %08X %s\n", m_dspx_channel_enable, GetBinary(buffer, m_dspx_channel_enable, 32));
diff --git a/src/devices/cpu/dspp/dspp.h b/src/devices/cpu/dspp/dspp.h
index b99940e24aa..4d8688ae41c 100644
--- a/src/devices/cpu/dspp/dspp.h
+++ b/src/devices/cpu/dspp/dspp.h
@@ -66,6 +66,12 @@ public:
DECLARE_WRITE16_MEMBER( clock_w );
DECLARE_READ16_MEMBER( noise_r );
+ void update_fifo_dma();
+ void print_sums() { printf("%04x: %04x\n", (uint16_t)m_core->m_arg0, (uint16_t)m_core->m_arg1); }
+ void print_branches() { printf("Branch: %d %d %d %d %d\n", m_core->m_arg0 ? 1 : 0, m_core->m_arg1 ? 1 : 0, m_core->m_arg2 ? 1 : 0, m_core->m_arg3 ? 1 : 0, m_core->m_arg4 ? 1 : 0); }
+ void print_value() { printf("Value is %08x\n", m_core->m_arg0); }
+ void print_addr() { printf("New value is %08x from %08x\n", m_core->m_arg0, m_core->m_arg1); }
+
protected:
// device-level overrides
virtual void device_start() override;
@@ -90,6 +96,41 @@ protected:
void code_map(address_map &map);
void data_map(address_map &map);
+ enum
+ {
+ DSPX_CONTROL_GWILLING = 0x0001,
+ DSPX_CONTROL_STEP_CYCLE = 0x0002,
+ DSPX_CONTROL_STEP_PC = 0x0004,
+ DSPX_CONTROL_SNOOP = 0x0008,
+
+ DSPX_RESET_DSPP = 0x0001,
+ DSPX_RESET_INPUT = 0x0002,
+ DSPX_RESET_OUTPUT = 0x0004,
+
+ DSPX_F_DMA_NEXTVALID = 0x0001,
+ DSPX_F_DMA_GO_FOREVER = 0x0002,
+ DSPX_F_INT_DMANEXT_EN = 0x0004,
+ DSPX_F_SHADOW_SET_DMANEXT = 0x00040000,
+ DSPX_F_SHADOW_SET_FOREVER = 0x00020000,
+ DSPX_F_SHADOW_SET_NEXTVALID = 0x00010000,
+ DSPX_F_SHADOW_SET_ADDRESS_COUNT = 0x80000000,
+
+ DSPX_F_INT_TIMER = 0x00000100,
+ DSPX_F_INT_INPUT_UNDER = 0x00000080,
+ DSPX_F_INT_INPUT_OVER = 0x00000040,
+ DSPX_F_INT_OUTPUT_UNDER = 0x00000020,
+ DSPX_F_INT_OUTPUT_OVER = 0x00000010,
+ DSPX_F_INT_UNDEROVER = 0x00000008,
+ DSPX_F_INT_CONSUMED = 0x00000002,
+ DSPX_F_INT_DMANEXT = 0x00000001,
+
+ DSPX_F_INT_ALL_DMA = (DSPX_F_INT_DMANEXT | DSPX_F_INT_CONSUMED | DSPX_F_INT_UNDEROVER),
+
+ DSPX_FLD_INT_SOFT_WIDTH = 16, /* width of the field and the number of interrupts */
+ DSPX_FLD_INT_SOFT_SHIFT = 16,
+ DSPX_FLD_INT_SOFT_MASK = 0xffff0000
+ };
+
private:
// Constants
static const uint32_t PC_STACK_DEPTH = 4;
@@ -130,7 +171,6 @@ private:
inline void set_rbase(uint32_t base, uint32_t addr);
inline uint16_t translate_reg(uint16_t reg);
- void update_fifo_dma();
void process_next_dma(int32_t channel);
void service_input_dma(int32_t channel);
void service_output_dma(int32_t channel);
@@ -162,6 +202,7 @@ private:
address_space * m_code;
address_space * m_data;
memory_access_cache<1, -1, ENDIANNESS_BIG> *m_code_cache;
+ std::function<uint16_t (offs_t)> m_code16;
std::function<const void * (offs_t)> m_codeptr;
struct dspp_internal_state
@@ -187,17 +228,25 @@ private:
uint16_t m_op;
uint32_t m_opidx;
int32_t m_writeback;
+ uint32_t m_jmpdest;
const char *m_format;
uint32_t m_arg0;
+ uint32_t m_arg1;
+ uint32_t m_arg2;
+ uint32_t m_arg3;
+ uint32_t m_arg4;
+
+ struct
+ {
+ uint32_t value;
+ uint32_t addr;
+ } m_operands[MAX_OPERANDS];
+
+ // External control registers
+ uint32_t m_dspx_control;
} * m_core;
- struct
- {
- uint32_t value;
- uint32_t addr;
- } m_operands[MAX_OPERANDS];
-
// DMA
struct fifo_dma
{
@@ -229,7 +278,6 @@ private:
uint32_t m_output_fifo_count;
// External control registers
- uint32_t m_dspx_control;
uint32_t m_dspx_reset;
uint32_t m_dspx_int_enable;
uint32_t m_dspx_channel_enable;
@@ -268,6 +316,7 @@ private:
uint32_t cycles; /* accumulated cycles */
uint8_t checkints; /* need to check interrupts before next instruction */
uint8_t checksoftints; /* need to check software interrupts before next instruction */
+ uml::code_label abortlabel; /* label to abort execution of this block */
uml::code_label labelnum; /* index for local labels */
};
@@ -288,18 +337,44 @@ public: // TODO
void static_generate_entry_point();
void static_generate_nocode_handler();
void static_generate_out_of_cycles();
- void static_generate_memory_accessor(int size, bool istlb, bool iswrite, const char *name, uml::code_handle **handleptr);
+ void static_generate_memory_accessor(bool iswrite, const char *name, uml::code_handle *&handleptr);
void generate_update_cycles(drcuml_block &block, compiler_state *compiler, uml::parameter param);
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);
- bool generate_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
-
+ void generate_push_pc(drcuml_block &block);
+ void generate_read_next_operand(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_write_next_operand(drcuml_block &block, compiler_state *compiler);
+ void generate_update_pc(drcuml_block &block);
+ void generate_update_ticks(drcuml_block &block);
+ void generate_translate_reg(drcuml_block &block, uint16_t reg);
+ void generate_set_rbase(drcuml_block &block, compiler_state *compiler, uint32_t base, uint32_t addr);
+ void generate_branch(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_complex_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_super_special(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_special_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_arithmetic_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_parse_operands(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc, uint32_t numops);
/* subroutines */
- uml::code_handle * m_entry; /* entry point */
- uml::code_handle * m_nocode; /* nocode exception handler */
- uml::code_handle * m_out_of_cycles; /* out of cycles exception handler */
+ uml::code_handle *m_entry; /* entry point */
+ uml::code_handle *m_nocode; /* nocode exception handler */
+ uml::code_handle *m_out_of_cycles; /* out of cycles exception handler */
+
+ enum
+ {
+ MEM_ACCESSOR_PM_READ48,
+ MEM_ACCESSOR_PM_WRITE48,
+ MEM_ACCESSOR_PM_READ32,
+ MEM_ACCESSOR_PM_WRITE32,
+ MEM_ACCESSOR_DM_READ32,
+ MEM_ACCESSOR_DM_WRITE32
+ };
+
+ uml::code_handle *m_dm_read16;
+ uml::code_handle *m_dm_write16;
};
diff --git a/src/devices/cpu/dspp/dsppdrc.cpp b/src/devices/cpu/dspp/dsppdrc.cpp
index 2d27885e34b..aefa9b9999c 100644
--- a/src/devices/cpu/dspp/dsppdrc.cpp
+++ b/src/devices/cpu/dspp/dsppdrc.cpp
@@ -22,8 +22,7 @@ using namespace uml;
// map variables
#define MAPVAR_PC M0
-#define MAPVAR_CYCLES M1
-#define MAPVAR_ACC M2
+#define MAPVAR_CYCLES M1
// exit codes
#define EXECUTE_OUT_OF_CYCLES 0
@@ -31,12 +30,6 @@ using namespace uml;
#define EXECUTE_UNMAPPED_CODE 2
#define EXECUTE_RESET_CACHE 3
-#define FLAG_C(reg) mem(&m_core->m_flag_carry)
-#define FLAG_Z(reg) mem(&m_core->m_flag_zero)
-#define FLAG_N(reg) mem(&m_core->m_flag_neg)
-#define FLAG_V(reg) mem(&m_core->m_flag_over)
-#define FLAG_X(reg) mem(&m_core->m_flag_exact)
-
inline void dspp_device::alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name)
{
if (*handleptr == nullptr)
@@ -63,6 +56,35 @@ void dspp_device::cfunc_unimplemented()
// fatalerror("PC=%08X: Unimplemented op %04X%08X\n", m_core->m_pc, (uint32_t)(op >> 32), (uint32_t)(op));
}
+static void cfunc_update_fifo_dma(void *param)
+{
+ dspp_device *dspp = (dspp_device *)param;
+ dspp->update_fifo_dma();
+}
+
+/*static void cfunc_print_sums(void *param)
+{
+ dspp_device *dspp = (dspp_device *)param;
+ dspp->print_sums();
+}
+
+static void cfunc_print_value(void *param)
+{
+ dspp_device *dspp = (dspp_device *)param;
+ dspp->print_value();
+}
+
+static void cfunc_print_addr(void *param)
+{
+ dspp_device *dspp = (dspp_device *)param;
+ dspp->print_addr();
+}
+
+static void cfunc_print_branches(void *param)
+{
+ dspp_device *dspp = (dspp_device *)param;
+ dspp->print_branches();
+}*/
/*-------------------------------------------------
load_fast_iregs - load any fast integer
@@ -103,58 +125,30 @@ void dspp_device::save_fast_iregs(drcuml_block &block)
#endif
}
-#if 0
-void dspp_device::static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, const char *name, code_handle *&handleptr)
+void dspp_device::static_generate_memory_accessor(bool iswrite, const char *name, uml::code_handle *&handleptr)
{
// I0 = read/write data
// I1 = address
- drcuml_block &block = m_drcuml->begin_block(1024);
+ drcuml_block &block = m_drcuml->begin_block(10);
// add a global entry for this
alloc_handle(m_drcuml.get(), &handleptr, name);
UML_HANDLE(block, *handleptr); // handle *handleptr
- switch (type)
+ if (iswrite)
{
- case MEM_ACCESSOR_PM_READ48:
- UML_SHL(block, I1, I1, 3);
- UML_DREAD(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM);
- break;
-
- case MEM_ACCESSOR_PM_WRITE48:
- UML_SHL(block, I1, I1, 3);
- UML_DWRITE(block, I1, I0, SIZE_QWORD, SPACE_PROGRAM);
- UML_MOV(block, mem(&m_core->force_recompile), 1);
- break;
-
- case MEM_ACCESSOR_PM_READ32:
- UML_SHL(block, I1, I1, 3);
- UML_READ(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM);
- break;
-
- case MEM_ACCESSOR_PM_WRITE32:
- UML_SHL(block, I1, I1, 3);
- UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_PROGRAM);
- UML_MOV(block, mem(&m_core->force_recompile), 1);
- break;
-
- case MEM_ACCESSOR_DM_READ32:
- UML_SHL(block, I1, I1, 2);
- UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA);
- break;
-
- case MEM_ACCESSOR_DM_WRITE32:
- UML_SHL(block, I1, I1, 2);
- UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA);
- break;
+ UML_WRITE(block, I1, I0, SIZE_WORD, SPACE_DATA);
+ }
+ else
+ {
+ UML_READ(block, I0, I1, SIZE_WORD, SPACE_DATA);
}
UML_RET(block);
block.end();
}
-#endif
void dspp_device::execute_run_drc()
@@ -192,13 +186,12 @@ void dspp_device::compile_block(offs_t pc)
drcuml_state *drcuml = m_drcuml.get();
compiler_state compiler = { 0 };
const opcode_desc *seqhead, *seqlast;
- const opcode_desc *desclist;
int override = false;
g_profiler.start(PROFILER_DRC_COMPILE);
/* get a description of this sequence */
- desclist = m_drcfe->describe_code(pc);
+ const opcode_desc *desclist = m_drcfe->describe_code(pc);
bool succeeded = false;
while (!succeeded)
@@ -206,7 +199,7 @@ void dspp_device::compile_block(offs_t pc)
try
{
/* start the block */
- drcuml_block &block = drcuml->begin_block(4096);
+ drcuml_block &block = drcuml->begin_block(32768);
/* loop until we get through all instruction sequences */
for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next())
@@ -216,7 +209,7 @@ void dspp_device::compile_block(offs_t pc)
/* add a code log entry */
if (drcuml->logging())
- block.append_comment("-------------------------"); // comment
+ block.append_comment("-------------------------");
/* determine the last instruction in this sequence */
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
@@ -251,17 +244,20 @@ void dspp_device::compile_block(offs_t pc)
if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc
+ compiler.abortlabel = compiler.labelnum++;
/* iterate over instructions in the sequence and compile them */
for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
generate_sequence_instruction(block, &compiler, curdesc);
+ UML_LABEL(block, compiler.abortlabel);
+
/* if we need to return to the start, do it */
if (seqlast->flags & OPFLAG_RETURN_TO_START)
nextpc = pc;
/* otherwise we just go to the next instruction */
else
- nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4;
+ nextpc = seqlast->pc + seqlast->length;
/* count off cycles and go there */
generate_update_cycles(block, &compiler, nextpc); // <subtract cycles>
@@ -290,72 +286,41 @@ void dspp_device::generate_checksum_block(drcuml_block &block, compiler_state *c
block.append_comment("[Validation for %08X]", seqhead->pc); // comment
/* loose verify or single instruction: just compare and fail */
- if (!(m_drcoptions & DSPPDRC_STRICT_VERIFY) || seqhead->next() == nullptr)
+ if (false/*!(m_drcoptions & DSPPDRC_STRICT_VERIFY)*/ || seqhead->next() == nullptr)
{
if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
{
- uint32_t sum = seqhead->opptr.l[0];
+ uint32_t sum = seqhead->opptr.w[0];
uint32_t addr = seqhead->physpc;
const void *base = m_codeptr(addr);
- UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,0,dword
-
- if (seqhead->delay.first() != nullptr && seqhead->physpc != seqhead->delay.first()->physpc)
- {
- addr = seqhead->delay.first()->physpc;
- base = m_codeptr(addr);
- assert(base != nullptr);
- UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword
- UML_ADD(block, I0, I0, I1); // add i0,i0,i1
+ UML_MOV(block, I0, 0);
+ UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,0,word
- sum += seqhead->delay.first()->opptr.l[0];
- }
-
- UML_CMP(block, I0, sum); // cmp i0,opptr[0]
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
+ UML_CMP(block, I0, sum); // cmp i0,opptr[0]
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc
}
}
/* full verification; sum up everything */
else
{
-#if 0
- for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
- {
- void *base = m_code_direct->read_ptr(seqhead->physpc);
- UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,0,dword
- UML_CMP(block, I0, curdesc->opptr.l[0]); // cmp i0,opptr[0]
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
- }
-#else
uint32_t sum = 0;
uint32_t addr = seqhead->physpc;
const void *base = m_codeptr(addr);
- UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,0,dword
- sum += seqhead->opptr.l[0];
+ UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,0,dword
+ sum += seqhead->opptr.w[0];
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
{
addr = curdesc->physpc;
base = m_codeptr(addr);
assert(base != nullptr);
- UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword
- UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->opptr.l[0];
-
- if (curdesc->delay.first() != nullptr && (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->physpc != curdesc->delay.first()->physpc)))
- {
- addr = curdesc->delay.first()->physpc;
- base = m_codeptr(addr);
- assert(base != nullptr);
- UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword
- UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->delay.first()->opptr.l[0];
- }
+ UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); // load i1,base,dword
+ UML_ADD(block, I0, I0, I1); // add i0,i0,i1
+ sum += curdesc->opptr.w[0];
}
- UML_CMP(block, I0, sum); // cmp i0,sum
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
-#endif
+ UML_CMP(block, I0, sum); // cmp i0,sum
+ UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
}
}
@@ -372,27 +337,9 @@ void dspp_device::flush_cache()
static_generate_nocode_handler();
static_generate_out_of_cycles();
-#if 0
- // generate utility functions
- static_generate_push_pc();
- static_generate_pop_pc();
- static_generate_push_loop();
- static_generate_pop_loop();
- static_generate_push_status();
- static_generate_pop_status();
- static_generate_mode1_ops();
-
- // generate exception handlers
- static_generate_exception(EXCEPTION_INTERRUPT, "exception_interrupt");
-
// generate memory accessors
- static_generate_memory_accessor(MEM_ACCESSOR_PM_READ48, "pm_read48", m_pm_read48);
- static_generate_memory_accessor(MEM_ACCESSOR_PM_WRITE48, "pm_write48", m_pm_write48);
- static_generate_memory_accessor(MEM_ACCESSOR_PM_READ32, "pm_read32", m_pm_read32);
- static_generate_memory_accessor(MEM_ACCESSOR_PM_WRITE32, "pm_write32", m_pm_write32);
- static_generate_memory_accessor(MEM_ACCESSOR_DM_READ32, "dm_read32", m_dm_read32);
- static_generate_memory_accessor(MEM_ACCESSOR_DM_WRITE32, "dm_write32", m_dm_write32);
-#endif
+ static_generate_memory_accessor(false, "dm_read16", m_dm_read16);
+ static_generate_memory_accessor(true, "dm_write16", m_dm_write16);
}
catch (drcuml_block::abort_compilation &)
{
@@ -408,38 +355,17 @@ void dspp_device::static_generate_entry_point()
/* forward references */
alloc_handle(m_drcuml.get(), &m_nocode, "nocode");
-// alloc_handle(m_drcuml.get(), &m_exception[EXCEPTION_INTERRUPT], "exception_interrupt");
-
alloc_handle(m_drcuml.get(), &m_entry, "entry");
UML_HANDLE(block, *m_entry); // handle entry
- load_fast_iregs(block); // <load fastregs>
-
-#if 0 // TODO: No interrupts?
- /* check for interrupts */
- UML_CMP(block, mem(&m_core->irq_pending), 0); // cmp [irq_pending],0
- UML_JMPc(block, COND_E, skip); // je skip
- UML_CMP(block, mem(&m_core->interrupt_active), 0); // cmp [interrupt_active],0
- UML_JMPc(block, COND_NE, skip); // jne skip
- UML_TEST(block, mem(&m_core->irq_pending), IMASK); // test [irq_pending],IMASK
- UML_JMPc(block, COND_Z, skip); // jz skip
- UML_TEST(block, mem(&m_core->mode1), MODE1_IRPTEN); // test MODE1,MODE1_IRPTEN
- UML_JMPc(block, COND_Z, skip); // jz skip
-#endif
-
-// UML_MOV(block, I0, mem(&m_core->m_pc)); // mov i0,nextpc
-// UML_MOV(block, I1, 0); // mov i1,0
-// UML_CALLH(block, *m_exception[EXCEPTION_INTERRUPT]); // callh m_exception[EXCEPTION_INTERRUPT]
-
-// UML_LABEL(block, skip);
+ //load_fast_iregs(block); // <load fastregs>
/* generate a hash jump via the current mode and PC */
- UML_HASHJMP(block, 0, mem(&m_core->m_pc), *m_nocode); // hashjmp <mode>,<pc>,nocode
+ UML_HASHJMP(block, 0, mem(&m_core->m_pc), *m_nocode);
block.end();
}
-
void dspp_device::static_generate_nocode_handler()
{
/* begin generating */
@@ -447,11 +373,12 @@ void dspp_device::static_generate_nocode_handler()
/* generate a hash jump via the current mode and PC */
alloc_handle(m_drcuml.get(), &m_nocode, "nocode");
- UML_HANDLE(block, *m_nocode); // handle nocode
- UML_GETEXP(block, I0); // getexp i0
- UML_MOV(block, mem(&m_core->m_pc), I0); // mov [pc],i0
- save_fast_iregs(block); // <save fastregs>
- UML_EXIT(block, EXECUTE_MISSING_CODE); // exit EXECUTE_MISSING_CODE
+ UML_HANDLE(block, *m_nocode); // handle nocode
+ UML_GETEXP(block, I0); // getexp i0
+
+ UML_MOV(block, mem(&m_core->m_pc), I0); // mov [pc],i0
+ //save_fast_iregs(block); // <save fastregs>
+ UML_EXIT(block, EXECUTE_MISSING_CODE); // exit EXECUTE_MISSING_CODE
block.end();
}
@@ -463,280 +390,606 @@ void dspp_device::static_generate_out_of_cycles()
/* generate a hash jump via the current mode and PC */
alloc_handle(m_drcuml.get(), &m_out_of_cycles, "out_of_cycles");
- UML_HANDLE(block, *m_out_of_cycles); // handle out_of_cycles
- UML_GETEXP(block, I0); // getexp i0
- UML_MOV(block, mem(&m_core->m_pc), I0); // mov <pc>,i0
- save_fast_iregs(block); // <save fastregs>
- UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); // exit EXECUTE_OUT_OF_CYCLES
+ UML_HANDLE(block, *m_out_of_cycles); // handle out_of_cycles
+ UML_GETEXP(block, I0); // getexp i0
+ UML_MOV(block, mem(&m_core->m_pc), I0); // mov <pc>,i0
+ //save_fast_iregs(block); // <save fastregs>
+ UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); // exit EXECUTE_OUT_OF_CYCLES
block.end();
}
-
void dspp_device::generate_sequence_instruction(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- /* add an entry for the log */
-// if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
-// log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
-
/* set the PC map variable */
- UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,desc->pc
+ UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,desc->pc
- /* accumulate total cycles */
+ /* accumulate total cycles */
compiler->cycles += desc->cycles;
/* update the icount map variable */
- UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles
+ UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles
/* if we are debugging, call the debugger */
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
{
- UML_MOV(block, mem(&m_core->m_pc), desc->pc); // mov [pc],desc->pc
- save_fast_iregs(block); // <save fastregs>
- UML_DEBUG(block, desc->pc); // debug desc->pc
+ UML_MOV(block, mem(&m_core->m_pc), desc->pc); // mov [pc],desc->pc
+ //save_fast_iregs(block); // <save fastregs>
+ UML_DEBUG(block, desc->pc); // debug desc->pc
}
/* if we hit an unmapped address, fatal error */
if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
{
- UML_MOV(block, mem(&m_core->m_pc), desc->pc); // mov [pc],desc->pc
- save_fast_iregs(block); // <save fastregs>
- UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
+ UML_MOV(block, mem(&m_core->m_pc), desc->pc); // mov [pc],desc->pc
+ save_fast_iregs(block); // <save fastregs>
+ UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
}
- /* if this is an invalid opcode, generate the exception now */
-// if (desc->flags & OPFLAG_INVALID_OPCODE)
-// UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
-
/* unless this is a virtual no-op, it's a regular instruction */
if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
{
- /* compile the instruction */
- //if (!generate_opcode(block, compiler, desc))
- {
- UML_MOV(block, mem(&m_core->m_pc), desc->pc); // mov [pc],desc->pc
- UML_DMOV(block, mem(&m_core->m_arg0), desc->opptr.q[0]); // dmov [m_arg0],*desc->opptr.q // FIXME
-// UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented,ppc
- }
+ generate_opcode(block, compiler, desc);
}
}
void dspp_device::generate_update_cycles(drcuml_block &block, compiler_state *compiler, uml::parameter param)
{
-#if 0 // No interrupts
- if (compiler->checkints)
- {
- code_label skip = compiler->labelnum++;
- compiler->checkints = false;
-
- UML_CMP(block, mem(&m_core->irq_pending), 0); // cmp [irq_pending],0
- UML_JMPc(block, COND_E, skip); // je skip
- UML_CMP(block, mem(&m_core->interrupt_active), 0); // cmp [interrupt_active],0
- UML_JMPc(block, COND_NE, skip); // jne skip
- UML_TEST(block, mem(&m_core->irq_pending), IMASK); // test [irq_pending],IMASK
- UML_JMPc(block, COND_Z, skip); // jz skip
- UML_TEST(block, mem(&m_core->mode1), MODE1_IRPTEN); // test MODE1,MODE1_IRPTEN
- UML_JMPc(block, COND_Z, skip); // jz skip
-
- UML_MOV(block, I0, param); // mov i0,nextpc
- UML_MOV(block, I1, compiler->cycles); // mov i1,cycles
- UML_CALLH(block, *m_exception[EXCEPTION_INTERRUPT]); // callh m_exception[EXCEPTION_INTERRUPT]
-
- UML_LABEL(block, skip);
- }
-#endif
-
/* account for cycles */
if (compiler->cycles > 0)
{
- UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), MAPVAR_CYCLES); // sub icount,icount,cycles
- UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0
-#if 0 // FIXME
- if (allow_exception)
- UML_EXHc(block, COND_S, *m_out_of_cycles, param); // exh out_of_cycles,nextpc
-#endif
+ UML_SUB(block, mem(&m_core->m_icount), mem(&m_core->m_icount), MAPVAR_CYCLES); // sub icount,icount,cycles
+ UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0
+ UML_EXHc(block, COND_S, *m_out_of_cycles, param); // exh out_of_cycles,nextpc
}
compiler->cycles = 0;
}
-#if 0
-bool dspp_device::generate_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+void dspp_device::generate_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ uint16_t op = desc->opptr.w[0];
+
+ UML_SUB(block, mem(&m_core->m_tclock), mem(&m_core->m_tclock), 1);
+ UML_CALLC(block, cfunc_update_fifo_dma, this);
+
+ if (m_drcuml.get()->logging())
+ block.append_comment("generate_opcode: %04x", op);
+
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, mem(&m_core->m_dspx_control), DSPX_CONTROL_GWILLING);
+ UML_JMPc(block, COND_Z, compiler->abortlabel);
+ //UML_TEST(block, mem(&m_core->m_flag_sleep), 1);
+ //UML_JMPc(block, COND_NZ, compiler->abortlabel);
+
+ //UML_MOV(block, mem(&m_core->m_arg0), desc->physpc);
+ //UML_MOV(block, mem(&m_core->m_arg1), op);
+ //UML_CALLC(block, cfunc_print_sums, this);
if (op & 0x8000)
{
switch ((op >> 13) & 3)
{
case 0:
- return generate_special_opcode(op, desc);
-
+ generate_special_opcode(block, compiler, desc);
+ break;
case 1:
case 2:
- return generate_branch_opcode(op, desc);
-
+ generate_branch_opcode(block, compiler, desc);
+ break;
case 3:
- return generate_complex_branch_opcode(op, desc);
+ generate_complex_branch_opcode(block, compiler, desc);
+ break;
}
-
- return false;
}
else
{
- return generate_arithmetic_opcode(op, desc);
+ generate_arithmetic_opcode(block, compiler, desc);
}
- return false;
+ UML_LABEL(block, skip);
}
-bool dspp_device::generate_special_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+void dspp_device::generate_set_rbase(drcuml_block &block, compiler_state *compiler, uint32_t base, uint32_t addr)
{
- return true;
+ if (m_drcuml.get()->logging())
+ block.append_comment("set_rbase");
+ switch (base)
+ {
+ case 4:
+ UML_MOV(block, mem(&m_core->m_rbase[1]), addr + 4 - base);
+ break;
+ case 0:
+ UML_MOV(block, mem(&m_core->m_rbase[0]), addr);
+ UML_MOV(block, mem(&m_core->m_rbase[1]), addr + 4 - base);
+ // Intentional fall-through
+ case 8:
+ UML_MOV(block, mem(&m_core->m_rbase[2]), addr + 8 - base);
+ // Intentional fall-through
+ case 12:
+ UML_MOV(block, mem(&m_core->m_rbase[3]), addr + 12 - base);
+ break;
+ }
}
-bool dspp_device::generate_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+void dspp_device::generate_super_special(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t mode = (m_core->m_op >> 13) & 3;
- uint32_t select = (m_core->m_op >> 12) & 1;
- uint32_t mask = (m_core->m_op >> 10) & 3;
+ uint16_t op = desc->opptr.w[0];
+ uint32_t sel = (op >> 7) & 7;
- bool flag0, flag1;
-
- if (select == 0)
- {
- flag0 = (m_core->m_flags & DSPI_FLAG_CC_NEG) != 0;
- flag1 = (m_core->m_flags & DSPI_FLAG_CC_OVER) != 0;
- }
- else
+ switch (sel)
{
- flag0 = (m_core->m_flags & DSPI_FLAG_CC_CARRY) != 0;
- flag1 = (m_core->m_flags & DSPI_FLAG_CC_ZERO) != 0;
- }
+ case 1: // BAC
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("BAC");
+ UML_SHR(block, mem(&m_core->m_jmpdest), mem(&m_core->m_acc), 4); // m_core->m_pc = m_core->m_acc >> 4;
+ generate_branch(block, compiler, desc);
+ break;
+ }
+ case 4: // RTS
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("RTS");
+ // m_core->m_pc = m_core->m_stack[--m_core->m_stack_ptr];
+ UML_SUB(block, mem(&m_core->m_stack_ptr), mem(&m_core->m_stack_ptr), 1);
+ UML_LOAD(block, mem(&m_core->m_jmpdest), (void *)m_core->m_stack, mem(&m_core->m_stack_ptr), SIZE_DWORD, SCALE_x4);
+ generate_branch(block, compiler, desc);
+ break;
+ }
+ case 5: // OP_MASK
+ {
+ // TODO
+ if (m_drcuml.get()->logging())
+ block.append_comment("OP_MASK");
+ break;
+ }
- bool mask0 = (mask & 2) != 0;
- bool mask1 = (mask & 1) != 0;
+ case 7: // SLEEP
+ {
+ // TODO: How does sleep work?
+ if (m_drcuml.get()->logging())
+ block.append_comment("SLEEP");
+ UML_SUB(block, mem(&m_core->m_pc), mem(&m_core->m_pc), 1); // --m_core->m_pc;
+ UML_MOV(block, mem(&m_core->m_flag_sleep), 1); // m_core->m_flag_sleep = 1;
+ break;
+ }
- bool branch = (flag0 || !mask0) && (flag1 || !mask1);
+ case 0: // NOP
+ case 2: // Unused
+ case 3:
+ case 6:
+ break;
+ }
+}
- if (mode == 2)
- branch = !branch;
+void dspp_device::generate_special_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+{
+ uint16_t op = desc->opptr.w[0];
- if (branch)
- m_core->m_pc = m_core->m_op & 0x3ff;
+ switch ((op >> 10) & 7)
+ {
+ case 0:
+ {
+ generate_super_special(block, compiler, desc);
+ break;
+ }
+ case 1: // JUMP
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("JUMP");
- return true;
-}
+ UML_MOV(block, mem(&m_core->m_jmpdest), op & 0x3ff);
+ generate_branch(block, compiler, desc);
+ break;
+ }
+ case 2: // JSR
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("JSR");
+ UML_STORE(block, (void *)m_core->m_stack, mem(&m_core->m_stack_ptr), mem(&m_core->m_pc), SIZE_DWORD, SCALE_x4);
+ UML_ADD(block, mem(&m_core->m_stack_ptr), mem(&m_core->m_stack_ptr), 1);
+ UML_MOV(block, mem(&m_core->m_jmpdest), op & 0x3ff);
+ generate_branch(block, compiler, desc);
+ break;
+ }
+ case 3: // BFM
+ {
+ // TODO
+ if (m_drcuml.get()->logging())
+ block.append_comment("BFM");
+ break;
+ }
+ case 4: // MOVEREG
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("MOVEREG");
+ const uint32_t regdi = op & 0x3f;
+ generate_translate_reg(block, regdi & 0xf);
+ // Indirect
+ if (regdi & 0x0010)
+ {
+ UML_CALLH(block, *m_dm_read16); // addr = read_data(addr);
+ UML_MOV(block, I2, I0);
+ }
+ else
+ {
+ UML_MOV(block, I2, I1);
+ }
-void adsp21062_device::generate_jump(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc, bool delayslot, bool loopabort, bool clearint)
-{
- compiler_state compiler_temp = *compiler;
+ generate_parse_operands(block, compiler, desc, 1);
+ generate_read_next_operand(block, compiler, desc);
+ UML_MOV(block, I0, I1);
+ UML_MOV(block, I1, I2);
+ UML_CALLH(block, *m_dm_write16); // write_data(addr, read_next_operand());
+ break;
+ }
+ case 5: // RBASE
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("RBASE");
+ generate_set_rbase(block, compiler, (op & 3) << 2, op & 0x3fc);
+ break;
+ }
+ case 6: // MOVED
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("MOVED");
+ generate_parse_operands(block, compiler, desc, 1);
+ generate_read_next_operand(block, compiler, desc);
+ UML_MOV(block, I0, I1);
+ UML_MOV(block, I1, op & 0x3ff);
+ UML_CALLH(block, *m_dm_write16); // write_data(op & 0x3ff, read_next_operand());
+ break;
+ }
+ case 7: // MOVEI
+ {
+ if (m_drcuml.get()->logging())
+ block.append_comment("MOVEI");
+ generate_parse_operands(block, compiler, desc, 1);
+ UML_MOV(block, I1, op & 0x3ff);
+ UML_CALLH(block, *m_dm_read16); // uint32_t addr = read_data(op & 0x3ff);
+ UML_MOV(block, I2, I1);
+ generate_read_next_operand(block, compiler, desc);
+ UML_MOV(block, I0, I1);
+ UML_MOV(block, I1, I2);
+ UML_CALLH(block, *m_dm_write16); // write_data(addr, read_next_operand());
+ break;
+ }
- // save branch target
- if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
- {
- UML_MOV(block, mem(&m_core->jmpdest), I0); // mov [jmpdest],i0
+ default:
+ break;
}
+}
+
+void dspp_device::generate_branch(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+{
+ compiler_state compiler_temp(*compiler);
- // update cycles and hash jump
+ /* update the cycles and jump through the hash table to the target */
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
{
- generate_update_cycles(block, &compiler_temp, desc->targetpc, true);
+ generate_update_cycles(block, &compiler_temp, desc->targetpc); // <subtract cycles>
if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
- UML_JMP(block, desc->targetpc | 0x80000000); // jmp targetpc | 0x80000000
+ UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000
else
- UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); // hashjmp 0,targetpc,nocode
+ UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); // hashjmp <mode>,desc->targetpc,nocode
}
else
{
- generate_update_cycles(block, &compiler_temp, mem(&m_core->jmpdest), true);
- UML_HASHJMP(block, 0, mem(&m_core->jmpdest), *m_nocode); // hashjmp 0,jmpdest,nocode
+ generate_update_cycles(block, &compiler_temp, uml::mem(&m_core->m_jmpdest)); // <subtract cycles>
+ UML_HASHJMP(block, 0, mem(&m_core->m_jmpdest), *m_nocode); // hashjmp <mode>,<rsreg>,nocode
}
- // update compiler label
+ /* update the label */
compiler->labelnum = compiler_temp.labelnum;
- /* reset the mapvar to the current cycles and account for skipped slots */
-// compiler->cycles += desc->skipslots;
- UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles
+ /* reset the mapvar to the current cycles */
+ UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler.cycles
}
-bool dspp_device::generate_complex_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+void dspp_device::generate_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ uint16_t op = desc->opptr.w[0];
- code_label skip_label = compiler->labelnum++;
+ if (m_drcuml.get()->logging())
+ block.append_comment("branch_opcode");
-// generate_branch_target(block, compiler, desc, op & 0x3ff, ef2);
-// generate_condition(block, compiler, desc, ef1, true, skip_label, true);
+ uint32_t mode = (op >> 13) & 3;
+ uint32_t select = (op >> 12) & 1;
+ uint32_t mask = (op >> 10) & 3;
+
+ if (select == 0)
+ {
+ UML_MOV(block, I0, mem(&m_core->m_flag_neg));
+ UML_MOV(block, I1, mem(&m_core->m_flag_over));
+ }
+ else
+ {
+ UML_MOV(block, I0, mem(&m_core->m_flag_carry));
+ UML_MOV(block, I1, mem(&m_core->m_flag_zero));
+ }
+
+ //UML_MOV(block, mem(&m_core->m_arg1), I0);
+ //UML_MOV(block, mem(&m_core->m_arg3), I1);
+
+ const uint32_t mask0 = (mask & 2) ? 0 : 1;
+ const uint32_t mask1 = (mask & 1) ? 0 : 1;
+
+ UML_OR(block, I0, I0, mask0);
+ UML_OR(block, I1, I1, mask1);
+ UML_AND(block, I0, I0, I1); // bool branch = (flag0 || mask0) && (flag1 || mask1);
+
+ if (mode == 2) // if (mode == 2)
+ UML_SUB(block, I0, 1, I0); // branch = !branch;
+
+ //UML_MOV(block, mem(&m_core->m_arg0), I0);
+ //UML_MOV(block, mem(&m_core->m_arg2), 1-mask0);
+ //UML_MOV(block, mem(&m_core->m_arg4), 1-mask1);
+ //UML_CALLC(block, cfunc_print_branches, this);
+
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, I0, 1); // if (branch)
+ UML_JMPc(block, COND_Z, skip);
+ UML_MOV(block, mem(&m_core->m_jmpdest), op & 0x3ff); // m_core->m_pc = op & 0x3ff;
generate_branch(block, compiler, desc);
- UML_LABEL(block, skip_label);
+ UML_LABEL(block, skip);
+}
+
+void dspp_device::generate_complex_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+{
+ uint16_t op = desc->opptr.w[0];
switch ((op >> 10) & 7)
{
case 0: // BLT
- // branch = (n && !v) || (!n && v);
- UML_XOR(I0, FLAG_N, 1);
- UML_XOR(I1, FLAG_V, 1);
- UML_AND(I0, I0, FLAG_V);
- UML_AND(I1, FLAG_N, I1);
- UML_OR(I0, I1, I2);
- UML_CMP(block, I0, 1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("BLT");
+ UML_XOR(block, I0, mem(&m_core->m_flag_neg), mem(&m_core->m_flag_over)); // branch = (n && !v) || (!n && v);
break;
case 1: // BLE
- //branch = ((n && !v) || (!n && v)) || z;
+ if (m_drcuml.get()->logging())
+ block.append_comment("BLE");
+ UML_XOR(block, I0, mem(&m_core->m_flag_neg), mem(&m_core->m_flag_over));
+ UML_OR(block, I0, I0, mem(&m_core->m_flag_zero)); // branch = ((n && !v) || (!n && v)) || z;
break;
case 2: // BGE
- //branch = ((n && v) || (!n && !v));
+ if (m_drcuml.get()->logging())
+ block.append_comment("BGE");
+ UML_XOR(block, I0, mem(&m_core->m_flag_neg), mem(&m_core->m_flag_over));
+ UML_SUB(block, I0, 1, I0); // branch = ((n && v) || (!n && !v));
break;
case 3: // BGT
- //branch = ((n && v) || (!n && !v)) && !z;
- UML_AND(I2, FLAG_N, FLAG_V);
- UML_XOR(I0, FLAG_N, 1);
- UML_XOR(I1, FLAG_V, 1);
- UML_AND(I0, I0, I1);
- UML_OR(I0, I2, I0);
- UML_XOR(I1, FLAG_Z, 1);
- UML_AND(I0, I0, I1);
- UML_CMP(I0, 1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("BGT");
+ UML_AND(block, I0, mem(&m_core->m_flag_neg), mem(&m_core->m_flag_over));
+ UML_SUB(block, I0, 1, I0);
+ UML_SUB(block, I1, 1, mem(&m_core->m_flag_zero));
+ UML_AND(block, I0, I0, I1); // branch = ((n && v) || (!n && !v)) && !z;
break;
case 4: // BHI
- //branch = c && !z;
- UML_XOR(I0, FLAG_Z, 1)
- UML_AND(I0, FLAG_C, I0);
- UML_CMP(I0, 1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("BHI");
+ UML_SUB(block, I0, 1, mem(&m_core->m_flag_zero));
+ UML_AND(block, I0, I0, mem(&m_core->m_flag_carry)); // branch = c && !z;
break;
case 5: // BLS
- //branch = !c || z;
- UML_XOR(I0, FLAG_C, 1);
- UML_OR(I0, I0, FLAG_Z);
- UML_CMP(block, I0, 1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("BLS");
+ UML_SUB(block, I0, 1, mem(&m_core->m_flag_carry));
+ UML_OR(block, I0, I0, mem(&m_core->m_flag_zero)); // branch = !c || z;
break;
case 6: // BXS
- //branch = x;
- UML_CMP(block, FLAG_X, 1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("BXS");
+ UML_MOV(block, I0, mem(&m_core->m_flag_exact)); // branch = x;
break;
case 7: // BXC
- //branch = !x;
- UML_CMP(block, FLAG_X, 0);
+ if (m_drcuml.get()->logging())
+ block.append_comment("BXC");
+ UML_SUB(block, I0, 1, mem(&m_core->m_flag_exact)); // branch = !x;
break;
}
- UML_JMPc(block, COND_E, skip_label);
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, I0, 1); // if (branch)
+ UML_JMPc(block, COND_Z, skip);
+ UML_MOV(block, mem(&m_core->m_jmpdest), op & 0x3ff); // m_core->m_pc = op & 0x3ff;
+ generate_branch(block, compiler, desc);
+ UML_LABEL(block, skip);
+}
+
+void dspp_device::generate_translate_reg(drcuml_block &block, uint16_t reg)
+{
+ const uint32_t base = (reg >> 2) & 3;
+ if (m_drcuml.get()->logging())
+ block.append_comment("translate_reg");
+ UML_MOV(block, I1, mem(&m_core->m_rbase[base]));
+ UML_ADD(block, I1, I1, reg - (reg & ~3));
+}
+
+void dspp_device::generate_parse_operands(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc, uint32_t numops)
+{
+ uint32_t addr, val = 0xBAD;
+ uint32_t opidx = 0;
+ uint32_t operand = 0;
+ uint32_t numregs = 0;
+
+ if (m_drcuml.get()->logging())
+ block.append_comment("parse_operands");
+
+ for (uint32_t i = 0; i < MAX_OPERANDS; ++i)
+ {
+ // Reset operands
+ UML_DMOV(block, mem(&m_core->m_operands[i]), 0xffffffffffffffffULL);
+ }
+
+ // Reset global op index
+ UML_MOV(block, mem(&m_core->m_opidx), 0);
+
+ uint32_t opoffset = 1;
+ while (opidx < numops)
+ {
+ operand = m_code16(desc->pc + opoffset);
+ opoffset++;
+
+ if (operand & 0x8000)
+ {
+ // Immediate value
+ if ((operand & 0xc000) == 0xc000)
+ {
+ val = operand & 0x1fff;
+
+ if (operand & 0x2000)
+ {
+ // Left justify
+ val = val << 3;
+ }
+ else
+ {
+ // Sign extend if right justified
+ if (val & 0x1000)
+ val |= 0xe000;
+ }
+ UML_MOV(block, mem(&m_core->m_operands[opidx].value), val);
+ opidx++;
+ }
+ else if((operand & 0xe000) == 0x8000)
+ {
+ // Address operand
+ addr = operand & 0x03ff;
+
+ if (operand & 0x0400)
+ {
+ // Indirect
+ UML_MOV(block, I1, addr);
+ UML_CALLH(block, *m_dm_read16);
+ UML_MOV(block, mem(&m_core->m_operands[opidx].addr), I0);
+ if (operand & 0x0800)
+ {
+ // Writeback
+ UML_MOV(block, mem(&m_core->m_writeback), I0);
+ }
+ }
+ else
+ {
+ UML_MOV(block, mem(&m_core->m_operands[opidx].addr), addr);
+ if (operand & 0x0800)
+ {
+ // Writeback
+ UML_MOV(block, mem(&m_core->m_writeback), addr);
+ }
+ }
+ ++opidx;
+ }
+ else if ((operand & 0xe000) == 0xa000)
+ {
+ // 1 or 2 register operand
+ numregs = (operand & 0x0400) ? 2 : 1;
+ }
+ }
+ else
+ {
+ numregs = 3;
+ }
+
+ if (numregs > 0)
+ {
+ // Shift successive register operands from a single operand word
+ for (uint32_t i = 0; i < numregs; ++i)
+ {
+ uint32_t shifter = ((numregs - i) - 1) * 5;
+ uint32_t regdi = (operand >> shifter) & 0x1f;
+ generate_translate_reg(block, regdi & 0xf);
+
+ if (regdi & 0x0010)
+ {
+ // Indirect?
+ UML_CALLH(block, *m_dm_read16);
+ }
+
+ if (numregs == 2)
+ {
+ if ((i == 0) && (operand & 0x1000))
+ UML_MOV(block, mem(&m_core->m_writeback), I0);
+ else if ((i == 1) && (operand & 0x0800))
+ UML_MOV(block, mem(&m_core->m_writeback), I0);
+ }
+ else if (numregs == 1)
+ {
+ if (operand & 0x800)
+ UML_MOV(block, mem(&m_core->m_writeback), I0);
+ }
+
+ UML_MOV(block, mem(&m_core->m_operands[opidx].addr), I0);
+ opidx++;
+ }
+ numregs = 0;
+ }
+ }
+ UML_ADD(block, mem(&m_core->m_pc), mem(&m_core->m_pc), opoffset-1);
+ UML_SUB(block, mem(&m_core->m_tclock), mem(&m_core->m_tclock), opoffset-1);
+}
+
+void dspp_device::generate_read_next_operand(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+{
+ //uint16_t op = (uint16_t)desc->opptr.w[0];
+
+ code_label no_load;
+ if (m_drcuml.get()->logging())
+ block.append_comment("read_next_operand");
+ UML_LOAD(block, I0, (void *)&m_core->m_operands[0].value, mem(&m_core->m_opidx), SIZE_DWORD, SCALE_x8);
+ //if (op == 0x46a0)
+ //{
+ // UML_MOV(block, mem(&m_core->m_arg0), I0);
+ // UML_CALLC(block, cfunc_print_value, this);
+ //}
+
+ UML_TEST(block, I0, 0x80000000U);
+ UML_JMPc(block, COND_Z, no_load = compiler->labelnum++);
+ UML_LOAD(block, I1, (void *)&m_core->m_operands[0].addr, mem(&m_core->m_opidx), SIZE_DWORD, SCALE_x8);
+ //if (op == 0x46a0)
+ //{
+ // UML_MOV(block, mem(&m_core->m_arg1), I1);
+ //}
+ UML_CALLH(block, *m_dm_read16);
+ //if (op == 0x46a0)
+ //{
+ // UML_MOV(block, mem(&m_core->m_arg0), I0);
+ // UML_CALLC(block, cfunc_print_addr, this);
+ //}
+
+ UML_LABEL(block, no_load);
+
+ // Next operand
+ UML_ADD(block, mem(&m_core->m_opidx), mem(&m_core->m_opidx), 1);
+}
- return true;
+void dspp_device::generate_write_next_operand(drcuml_block &block, compiler_state *compiler)
+{
+ if (m_drcuml.get()->logging())
+ block.append_comment("write_next_operand");
+ // int32_t addr = m_core->m_operands[m_core->m_opidx].addr;
+ UML_LOAD(block, I1, (void *)&m_core->m_operands[0].addr, mem(&m_core->m_opidx), SIZE_DWORD, SCALE_x8);
+
+ // write_data(addr, m_core->m_acc >> 4);
+ UML_SHR(block, I0, mem(&m_core->m_acc), 4);
+
+ // Advance to the next operand
+ UML_ADD(block, mem(&m_core->m_opidx), mem(&m_core->m_opidx), 1);
}
-bool dspp_device::generate_arithmetic_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
+void dspp_device::generate_arithmetic_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t numops = (m_core->m_op >> 13) & 3;
- uint32_t muxa = (m_core->m_op >> 10) & 3;
- uint32_t muxb = (m_core->m_op >> 8) & 3;
- uint32_t alu_op = (m_core->m_op >> 4) & 0xf;
- uint32_t barrel_code = m_core->m_op & 0xf;
+ uint16_t op = (uint16_t)desc->opptr.w[0];
+ uint32_t numops = (op >> 13) & 3;
+ uint32_t muxa = (op >> 10) & 3;
+ uint32_t muxb = (op >> 8) & 3;
+ uint32_t alu_op = (op >> 4) & 0xf;
+ uint32_t barrel_code = op & 0xf;
- int32_t mul_res = 0;
- uint32_t alu_res = 0;
+ if (m_drcuml.get()->logging())
+ block.append_comment("arithmetic_opcode");
// Check for operand overflow
if (numops == 0 && ((muxa == 1) || (muxa == 2) || (muxb == 1) || (muxb == 2)))
@@ -747,224 +1000,336 @@ bool dspp_device::generate_arithmetic_opcode(drcuml_block &block, compiler_state
++numops;
// Parse ops...
- parse_operands(numops);
+ generate_parse_operands(block, compiler, desc, numops);
if (muxa == 3 || muxb == 3)
{
- uint32_t mul_sel = (m_core->m_op >> 12) & 1;
+ uint32_t mul_sel = (op >> 12) & 1;
- int32_t op1 = sign_extend16(read_next_operand());
- int32_t op2 = sign_extend16(mul_sel ? read_next_operand() : m_core->m_acc >> 4);
+ generate_read_next_operand(block, compiler, desc);
+ UML_SEXT(block, I2, I2, SIZE_WORD);
+ if (mul_sel)
+ {
+ generate_read_next_operand(block, compiler, desc);
+ }
+ else
+ {
+ UML_SHR(block, I0, mem(&m_core->m_acc), 4);
+ }
+ UML_SEXT(block, I0, I0, SIZE_WORD);
+ UML_MULS(block, I3, I0, I0, I2); // mul_res = (op1 * op2);
+ UML_SHR(block, I3, I3, 11); // mul_res >>= 11;
+ }
- mul_res = (op1 * op2) >> 11;
+ switch (muxa)
+ {
+ case 0:
+ UML_MOV(block, I2, mem(&m_core->m_acc)); // alu_a = m_core->m_acc;
+ break;
+ case 1: case 2:
+ generate_read_next_operand(block, compiler, desc);
+ UML_SHL(block, I2, I0, 4); // alu_a = read_next_operand() << 4;
+ break;
+ case 3:
+ {
+ UML_MOV(block, I2, I3); // alu_a = mul_res;
+ break;
+ }
+ }
-#if 0
- // SELECT
- UML_DSEXT(block, I0, OP1, SIZE_WORD);
- UML_DSEXT(block, I1, OP1, SIZE_WORD);
- UML_MULS(block, I0, I1, I0, I1);
- UML_SHR(block, I2, I0, 11);
-#endif
+ switch (muxb)
+ {
+ case 0:
+ {
+ UML_MOV(block, I3, mem(&m_core->m_acc)); // alu_b = m_core->m_acc;
+ break;
+ }
+ case 1: case 2:
+ {
+ generate_read_next_operand(block, compiler, desc);
+ UML_SHL(block, I3, I0, 4); // alu_b = read_next_operand() << 4;
+ break;
+ }
+ case 3:
+ {
+ // alu_b = mul_res;
+ break;
+ }
}
- // MULRES = I2
- // MUXA = I0
- // MUXB = I1
+ // For carry detection apparently
+ UML_AND(block, I2, I2, 0x000fffff);
+ UML_AND(block, I3, I3, 0x000fffff);
- // ALURES = I2
- // ACC_RESULT = I1?
+ code_label skip_over = compiler->labelnum++;
+ // ALU_A = I2
+ // ALU_B = I3
+ // ALU_RES = I0
switch (alu_op)
{
case 0: // _TRA
- // alu_res = alu_a;
- UML_MOV(block, I2, I0);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_TRA");
+ UML_MOV(block, I0, I2); // alu_res = alu_a;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 1: // _NEG
- // alu_res = -alu_b;
- UML_SUB(block, I2, 0, I1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_NEG");
+ UML_SUB(block, I0, 0, I3); // alu_res = -alu_b;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 2: // _+
- // alu_res = alu_a + alu_b;
- UML_ADD(block, I2, I0, I1);
-
- // if ((alu_a & 0x80000) == (alu_b & 0x80000) &&
- // (alu_a & 0x80000) != (alu_res & 0x80000))
- // m_core->m_flags |= DSPI_FLAG_CC_OVER;
-
- // if (alu_res & 0x00100000)
- // m_core->m_flags |= DSPI_FLAG_CC_CARRY;
-
- // CC_V_MODIFIED(desc);
- // CC_C_MODIFIED(desc);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_+");
+ UML_ADD(block, I0, I2, I3); // alu_res = alu_a + alu_b;
+
+ UML_MOV(block, mem(&m_core->m_flag_over), 0);
+
+ UML_XOR(block, I3, I2, I3);
+ UML_TEST(block, I3, 0x80000);
+ UML_JMPc(block, COND_NZ, skip_over); // if ((alu_a & 0x80000) == (alu_b & 0x80000) &&
+ UML_XOR(block, I3, I2, I0);
+ UML_TEST(block, I3, 0x80000); // (alu_a & 0x80000) != (alu_res & 0x80000))
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_over), 1); // m_core->m_flag_over = 1;
+
+ UML_LABEL(block, skip_over);
+ UML_TEST(block, I0, 0x00100000); // if (alu_res & 0x00100000)
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_carry), 1); // m_core->m_flag_carry = 1;
+ // else
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 3: // _+C
- UML_ADD(block, I2, I0, mew);
- // alu_res = alu_a + (m_core->m_flags & DSPI_FLAG_CC_CARRY) ? (1 << 4) : 0;
+ if (m_drcuml.get()->logging())
+ block.append_comment("_+C");
+ UML_SHL(block, I3, mem(&m_core->m_flag_carry), 4);
+ UML_ADD(block, I0, I2, I3); // alu_res = alu_a + (m_core->m_flag_carry << 4);
- // if (alu_res & 0x00100000)
- // m_core->m_flags |= DSPI_FLAG_CC_CARRY;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
- CC_C_USED(desc);
- CC_C_MODIFIED(desc);
+ UML_TEST(block, I0, 0x00100000); // if (alu_res & 0x00100000)
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_carry), 1); // m_core->m_flag_carry = 1;
+ // else
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 4: // _-
- // alu_res = alu_a - alu_b;
- UML_SUB(block, I2, I0, I1);
-
- // if ((alu_a & 0x80000) == (~alu_b & 0x80000) &&
- // (alu_a & 0x80000) != (alu_res & 0x80000))
- // m_core->m_flags |= DSPI_FLAG_CC_OVER;
-
- // if (alu_res & 0x00100000)
- // m_core->m_flags |= DSPI_FLAG_CC_CARRY;
-
- CC_C_MODIFIED(desc);
- CC_V_MODIFIED(desc);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_-");
+ UML_SUB(block, I0, I2, I3); // alu_res = alu_a - alu_b;
+
+ UML_MOV(block, mem(&m_core->m_flag_over), 0);
+
+ UML_XOR(block, I3, I3, 0xffffffffU);
+ UML_XOR(block, I3, I2, I3);
+ UML_TEST(block, I3, 0x80000);
+ UML_JMPc(block, COND_NZ, skip_over); // if ((alu_a & 0x80000) == (~alu_b & 0x80000) &&
+ UML_XOR(block, I3, I2, I0);
+ UML_TEST(block, I3, 0x80000); // (alu_a & 0x80000) != (alu_res & 0x80000))
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_over), 1); // m_core->m_flag_over = 1;
+
+ UML_LABEL(block, skip_over);
+ UML_TEST(block, I0, 0x00100000); // if (alu_res & 0x00100000)
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_carry), 1); // m_core->m_flag_carry = 1;
+ // else
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 5: // _-B
- // alu_res = alu_a - (m_core->m_flags & DSPI_FLAG_CC_CARRY) ? (1 << 4) : 0;
+ if (m_drcuml.get()->logging())
+ block.append_comment("_-B");
+ UML_SHL(block, I3, mem(&m_core->m_flag_carry), 4);
+ UML_SUB(block, I0, I2, I3); // alu_res = alu_a - (m_core->m_flag_carry << 4);
- // if (alu_res & 0x00100000)
- // m_core->m_flags |= DSPI_FLAG_CC_CARRY;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
- CC_C_USED(desc);
- CC_C_MODIFIED(desc);
+ UML_TEST(block, I0, 0x00100000); // if (alu_res & 0x00100000)
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_carry), 1); // m_core->m_flag_carry = 1;
+ // else
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 6: // _++
- UML_ADD(block, I2, I0, 1);
- // alu_res = alu_a + 1;
+ if (m_drcuml.get()->logging())
+ block.append_comment("_++");
+ UML_ADD(block, I0, I2, 1); // alu_res = alu_a + 1;
- // if (!(alu_a & 0x80000) && (alu_res & 0x80000))
- // m_core->m_flags |= DSPI_FLAG_CC_OVER;
+ UML_XOR(block, I3, I2, 0x80000);
+ UML_AND(block, I3, I3, I0);
+ UML_TEST(block, I3, 0x80000);
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_over), 1);
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = !(alu_a & 0x80000) && (alu_res & 0x80000);
- CC_V_MODIFIED(desc);
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 7: // _--
- // alu_res = alu_a - 1;
- UML_SUB(block, I2, I0, 1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_--");
+ UML_SUB(block, I0, I2, 1); // alu_res = alu_a - 1;
- // if ((alu_a & 0x80000) && !(alu_res & 0x80000))
- // m_core->m_flags |= DSPI_FLAG_CC_OVER;
+ UML_XOR(block, I3, I0, 0x80000);
+ UML_AND(block, I3, I3, I2);
+ UML_TEST(block, I3, 0x80000);
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_over), 1);
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = (alu_a & 0x80000) && !(alu_res & 0x80000);
- CC_V_MODIFIED(desc);
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 8: // _TRL
- //alu_res = alu_a;
- UML_MOV(block, I2, I0);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_TRL");
+ UML_MOV(block, I0, I2); // alu_res = alu_a;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 9: // _NOT
- //alu_res = ~alu_a;
- UML_XOR(block, I2, I0, 0xffff);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_NOT");
+ UML_XOR(block, I0, I2, 0xffffffff); // alu_res = ~alu_a;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 10: // _AND
- //alu_res = alu_a & alu_b;
- UML_AND(block, I2, I0, I1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_AND");
+ UML_AND(block, I0, I2, I3); // alu_res = alu_a & alu_b;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 11: // _NAND
- //alu_res = ~(alu_a & alu_b);
- UML_AND(block, I2, I0, I1);
- UML_XOR(block, I2, 0xffff);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_NAND");
+ UML_AND(block, I0, I2, I3);
+ UML_XOR(block, I0, I0, 0xffffffff); // alu_res = ~(alu_a & alu_b);
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 12: // _OR
- //alu_res = alu_a | alu_b;
- UML_OR(block, I2, I0, I1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_OR");
+ UML_OR(block, I0, I2, I3); // alu_res = alu_a | alu_b;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 13: // _NOR
- //alu_res = ~(alu_a | alu_b);
- UML_OR(block, I2, I0, I1);
- UML_XOR(block, I2, I2, 0xffff);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_NOR");
+ UML_OR(block, I0, I2, I3);
+ UML_XOR(block, I0, I0, 0xffffffff); // alu_res = ~(alu_a | alu_b);
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 14: // _XOR
- //alu_res = alu_a ^ alu_b;
- UML_XOR(block, I2, I0, I1);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_XOR");
+ UML_XOR(block, I0, I2, I3); // alu_res = alu_a ^ alu_b;
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
case 15: // _XNOR
- //alu_res = ~(alu_a ^ alu_b);
- UML_XOR(block, I2, I0, I1);
- UML_XOR(block, I2, I0, 0xffff);
+ if (m_drcuml.get()->logging())
+ block.append_comment("_XNOR");
+ UML_XOR(block, I0, I2, I3);
+ UML_XOR(block, I0, I0, 0xffffffff); // alu_res = ~(alu_a ^ alu_b);
+ UML_MOV(block, mem(&m_core->m_flag_over), 0); // m_core->m_flag_over = 0;
+ UML_MOV(block, mem(&m_core->m_flag_carry), 0); // m_core->m_flag_carry = 0;
break;
}
- // SET FLAGS
- CC_SET_NEG(alu_res & 0x00080000);
- CC_SET_ZERO((alu_res & 0x000ffff0) == 0);
- CC_SET_EXACT((alu_res & 0x0000000f) == 0);
+ UML_TEST(block, I0, 0x00080000);
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_neg), 1);
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_neg), 0); // m_core->m_flag_neg = (alu_res & 0x00080000) != 0;
- // Barrel shift
- static const int32_t shifts[8] = { 0, 1, 2, 3, 4, 5, 8, 16 };
+ UML_TEST(block, I0, 0x000ffff0);
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_zero), 1);
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_zero), 0); // m_core->m_flag_zero = (alu_res & 0x000ffff0) == 0;
- if (barrel_code == 8)
- barrel_code = read_next_operand();
-
- if (barrel_code & 8)
- {
- // Right shift
- uint32_t shift = shifts[(~barrel_code + 1) & 7];
+ UML_TEST(block, I0, 0x0000000f);
+ UML_MOVc(block, COND_Z, mem(&m_core->m_flag_exact), 1);
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_flag_exact), 0); // m_core->m_flag_exact = (alu_res & 0x0000000f) == 0;
- if (alu_op < 8)
- {
- // Arithmetic
-// m_core->m_acc = sign_extend20(alu_res) >> shift;
+ // ALU_RES = I3
+ UML_MOV(block, I3, I0);
- // TODO: Sign Extend to 20-bits
- UML_SHR(block, I2, I2, shift);
- UML_MAPVAR(block, MAPVAR_ACC, I2);
- }
- else
- {
- // Logical
-// m_core->m_acc = (alu_res & 0xfffff) >> shift;
- UML_AND(block, I2, 0xfffff);
- UML_SHR(block, I2, I2, shift);
- UML_MAPVAR(block, MAPVAR_ACC, I2);
- }
+ // Barrel shift
+ static const int32_t shifts[8] = { 0, 1, 2, 3, 4, 5, 8, 16 };
- }
+ if (barrel_code == 8)
+ generate_read_next_operand(block, compiler, desc); // I0 = barrel_code;
else
- {
- // Left shift
- uint32_t shift = shifts[barrel_code];
-
- if (shift == 16)
- {
- // Clip and saturate
- if (m_core->m_flags & DSPI_FLAG_CC_OVER)
- m_core->m_acc = (m_core->m_flags & DSPI_FLAG_CC_NEG) ? 0x7ffff : 0xfff80000;
- else
- m_core->m_acc = sign_extend20(alu_res);
- }
- else
- {
- m_core->m_acc = sign_extend20(alu_res) << shift;
- }
- }
-
- if (m_core->m_writeback >= 0)
- {
- write_data(m_core->m_writeback, m_core->m_acc >> 4);
- m_core->m_writeback = -1;
- }
- else if (m_core->m_opidx < numops)
- {
- write_next_operand(m_core->m_acc >> 4);
- }
-
- return true;
+ UML_MOV(block, I0, barrel_code); // I0 = barrel_code;
+
+ code_label left_shift = compiler->labelnum++;
+ code_label done_shift = compiler->labelnum++;
+ code_label no_shift = compiler->labelnum++;
+ code_label no_clip = compiler->labelnum++;
+ code_label no_writeback = compiler->labelnum++;
+ code_label done = compiler->labelnum++;
+ UML_TEST(block, I0, 8); // if (barrel_code & 8)
+ UML_JMPc(block, COND_Z, left_shift); // {
+ UML_XOR(block, I0, I0, 0xffffffffU);
+ UML_ADD(block, I0, I0, 1);
+ UML_AND(block, I0, I0, 7);
+ UML_LOAD(block, I0, (void *)shifts, I0, SIZE_DWORD, SCALE_x8); // uint32_t shift = shifts[(~barrel_code + 1) & 7];
+ if (alu_op < 8) // if (alu_op < 8)
+ { // {
+ UML_SHL(block, I3, I3, 12);
+ UML_SAR(block, I3, I3, 12); // // Arithmetic
+ UML_SAR(block, mem(&m_core->m_acc), I3, I0); // m_core->m_acc = sign_extend20(alu_res) >> shift;
+ } // }
+ else // else
+ { // {
+ UML_AND(block, I3, I3, 0x000fffff); // // Logical
+ UML_SHR(block, mem(&m_core->m_acc), I3, I0); // m_core->m_acc = (alu_res & 0xfffff) >> shift;
+ } // }
+ UML_JMP(block, done_shift); // }
+ UML_LABEL(block, left_shift); // else
+ // {
+ UML_LOAD(block, I0, (void *)shifts, I0, SIZE_DWORD, SCALE_x8); // uint32_t shift = shifts[barrel_code];
+ UML_CMP(block, I0, 16); // if (shift != 16)
+ UML_JMPc(block, COND_E, no_shift); // {
+ UML_SHL(block, I3, I3, 12);
+ UML_SAR(block, I3, I3, 12);
+ UML_SHL(block, mem(&m_core->m_acc), I3, I0); // m_core->m_acc = sign_extend20(alu_res) << shift;
+ UML_JMP(block, done_shift); // }
+ // else
+ UML_LABEL(block, no_shift); // {
+ UML_TEST(block, mem(&m_core->m_flag_over), 1); // // Clip and saturate
+ UML_JMPc(block, COND_Z, no_clip); // if (m_core->m_flag_over)
+ UML_TEST(block, mem(&m_core->m_flag_neg), 1);
+ UML_MOVc(block, COND_NZ, mem(&m_core->m_acc), 0x7ffff); // m_core->m_acc = m_core->m_flag_neg ? 0x7ffff : 0xfff80000;
+ UML_MOVc(block, COND_Z, mem(&m_core->m_acc), 0xfff80000);
+ UML_JMP(block, done_shift); // else
+ UML_LABEL(block, no_clip);
+ UML_SHL(block, I3, I3, 12); // sign_extend20(alu_res);
+ UML_SAR(block, mem(&m_core->m_acc), I3, 12); // }
+ UML_LABEL(block, done_shift); // }
+
+ UML_CMP(block, mem(&m_core->m_writeback), 0); // if (m_core->m_writeback >= 0)
+ UML_JMPc(block, COND_L, no_writeback); // {
+ UML_SHR(block, I0, mem(&m_core->m_acc), 4);
+ UML_MOV(block, I1, mem(&m_core->m_writeback));
+ UML_CALLH(block, *m_dm_write16); // write_data(m_core->m_writeback, m_core->m_acc >> 4);
+ UML_MOV(block, mem(&m_core->m_writeback), 0xffffffffU); // m_core->m_writeback = -1;
+ UML_JMP(block, done); // }
+
+ UML_LABEL(block, no_writeback);
+ UML_CMP(block, mem(&m_core->m_opidx), numops); // else if (m_core->m_opidx < numops)
+ UML_JMPc(block, COND_GE, done); // {
+ generate_write_next_operand(block, compiler); // write_next_operand(m_core->m_acc >> 4);
+ UML_LABEL(block, done); // }
}
-
-#endif
diff --git a/src/devices/cpu/dspp/dsppfe.cpp b/src/devices/cpu/dspp/dsppfe.cpp
index 7ea800d6162..4f29ad08c0e 100644
--- a/src/devices/cpu/dspp/dsppfe.cpp
+++ b/src/devices/cpu/dspp/dsppfe.cpp
@@ -26,8 +26,6 @@
#define CC_X_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
#define CC_FLAGS_MODIFIED(desc) do { } while(0)
-//#define MULT_FLAGS_MODIFIED(desc) do { MN_MODIFIED(desc);MV_MODIFIED(desc);MU_MODIFIED(desc);MI_MODIFIED(desc); } while(0)
-//#define SHIFT_FLAGS_MODIFIED(desc) do { SZ_MODIFIED(desc);SV_MODIFIED(desc);SS_MODIFIED(desc); } while(0)
dspp_frontend::dspp_frontend(dspp_device *dspp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
: drc_frontend(*dspp, window_start, window_end, max_sequence),
@@ -78,9 +76,8 @@ bool dspp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
uint16_t op = desc.opptr.w[0] = m_dspp->read_op(desc.physpc);
- // TODO: NOOOOPE
- desc.cycles = 1; // TODO: Extra cycles for extra operands
- desc.length = 2;
+ desc.cycles = 1;
+ desc.length = 1;
// Decode and execute
if (op & 0x8000)
@@ -88,28 +85,25 @@ bool dspp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
switch ((op >> 13) & 3)
{
case 0:
- return describe_special(op, desc);
+ describe_special(op, desc);
case 1:
case 2:
- return describe_branch(op, desc);
+ describe_branch(op, desc);
case 3:
- return describe_complex_branch(op, desc);
+ describe_complex_branch(op, desc);
}
-
- return false;
}
else
{
- return describe_arithmetic(op, desc);
+ describe_arithmetic(op, desc);
}
- return false;
+ return true;
}
-
-bool dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
+void dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
{
switch ((op >> 10) & 7)
{
@@ -118,58 +112,55 @@ bool dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
// Super-special
switch ((op >> 7) & 7)
{
- case 1: // BAC - TODO: MERGE?
+ case 1: // BAC
{
- //desc.regin[0] = m_acc;
desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- return true;
+ return;
}
case 4: // RTS
{
desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- return true;
+ return;
}
case 5: // OP_MASK
{
// TODO
- return true;
+ return;
}
case 7: // SLEEP
{
- // TODO
- return true;
+ desc.flags |= OPFLAG_END_SEQUENCE | OPFLAG_RETURN_TO_START;
+ return;
}
case 0: // NOP
case 2: // Unused
case 3:
case 6:
- return true;
+ return;
}
break;
}
- case 1: // JUMP - TODO: MERGE?
+ case 1: // JUMP
{
desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
desc.targetpc = op & 0x3ff;
- return true;
+ return;
}
case 2: // JSR
{
desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
desc.targetpc = op & 0x3ff;
- return true;
+ return;
}
case 3: // BFM
{
// TODO: What sort of branch is this?
-// desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
-// desc.targetpc = 0; // FIXME
- return false;
+ return;
}
case 4: // MOVEREG
{
@@ -179,28 +170,29 @@ bool dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
if (op & 0x0010)
desc.flags |= OPFLAG_READS_MEMORY;
- return true;
+ parse_operands(op, desc, 1);
+ return;
}
case 5: // RBASE
{
- return true;
+ return;
}
case 6: // MOVED
{
desc.flags |= OPFLAG_WRITES_MEMORY;
- return true;
+ parse_operands(op, desc, 1);
+ return;
}
case 7: // MOVEI
{
desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY;
- return true;
+ parse_operands(op, desc, 1);
+ return;
}
}
-
- return false;
}
-bool dspp_frontend::describe_branch(uint16_t op, opcode_desc &desc)
+void dspp_frontend::describe_branch(uint16_t op, opcode_desc &desc)
{
const uint32_t select = (op >> 12) & 1;
@@ -218,11 +210,9 @@ bool dspp_frontend::describe_branch(uint16_t op, opcode_desc &desc)
// TODO: Can these be unconditional?
desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
desc.targetpc = op & 0x3ff;
-
- return true;
}
-bool dspp_frontend::describe_complex_branch(uint16_t op, opcode_desc &desc)
+void dspp_frontend::describe_complex_branch(uint16_t op, opcode_desc &desc)
{
switch ((op >> 10) & 7)
{
@@ -257,13 +247,10 @@ bool dspp_frontend::describe_complex_branch(uint16_t op, opcode_desc &desc)
desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
desc.targetpc = op & 0x3ff;
-
- return true;
}
-bool dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
+void dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
{
- #if 0
// Decode the various fields
uint32_t numops = (op >> 13) & 3;
uint32_t muxa = (op >> 10) & 3;
@@ -271,9 +258,6 @@ bool dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
uint32_t alu_op = (op >> 4) & 0xf;
uint32_t barrel_code = op & 0xf;
- int32_t mul_res = 0;
- uint32_t alu_res = 0;
-
// Check for operand overflow
if (numops == 0 && ((muxa == 1) || (muxa == 2) || (muxb == 1) || (muxb == 2)))
numops = 4;
@@ -282,7 +266,6 @@ bool dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
if (barrel_code == 8)
++numops;
- // TODO: We need to know:
// Number of cycles
// Number of bytes
// Registers read
@@ -290,293 +273,82 @@ bool dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
// Does it read memory?
// Does it write memory?
-// parse_operands(numops);
+ parse_operands(op, desc, numops);
- if (muxa == 3 || muxb == 3)
+ if (muxa > 0 || muxb > 0)
{
- uint32_t mul_sel = (op >> 12) & 1;
-
- int32_t op1 = sign_extend16(read_next_operand());
- int32_t op2 = sign_extend16(mul_sel ? read_next_operand() : m_core->m_acc >> 4);
-
- mul_res = (op1 * op2) >> 11;
+ desc.flags |= OPFLAG_READS_MEMORY;
}
- int32_t alu_a, alu_b;
-
- switch (muxa)
- {
- case 0:
- {
- ACCUMULATOR_USED
- alu_a = m_core->m_acc;
- break;
- }
- case 1: case 2:
- {
- alu_a = read_next_operand() << 4;
- break;
- }
- case 3:
- {
- alu_a = mul_res;
- break;
- }
- }
-
- switch (muxb)
- {
- case 0:
- {
- ACCUMULATOR_USED
- alu_b = m_core->m_acc;
- break;
- }
- case 1: case 2:
- {
- alu_b = read_next_operand() << 4;
- break;
- }
- case 3:
- {
- alu_b = mul_res;
- break;
- }
- }
-
- // All flags ar emodifed
- CC_FLAGS_MODIFIED(desc);
-
switch (alu_op)
{
case 0: // _TRA
{
-// alu_res = alu_a;
break;
}
case 1: // _NEG
{
-// alu_res = -alu_b;
break;
}
case 2: // _+
- {
-// alu_res = alu_a + alu_b;
-
-// if ((alu_a & 0x80000) == (alu_b & 0x80000) &&
-// (alu_a & 0x80000) != (alu_res & 0x80000))
-// m_core->m_flags |= DSPI_FLAG_CC_OVER;
-
-// if (alu_res & 0x00100000)
-// m_core->m_flags |= DSPI_FLAG_CC_CARRY;
-
-// CC_V_MODIFIED(desc);
-// CC_C_MODIFIED(desc);
- break;
- }
- case 3: // _+C
- {
-// alu_res = alu_a + (m_core->m_flags & DSPI_FLAG_CC_CARRY) ? (1 << 4) : 0;
-
-// if (alu_res & 0x00100000)
-// m_core->m_flags |= DSPI_FLAG_CC_CARRY;
-
- CC_C_USED(desc);
- CC_C_MODIFIED(desc);
- break;
- }
case 4: // _-
- {
-// alu_res = alu_a - alu_b;
-
-// if ((alu_a & 0x80000) == (~alu_b & 0x80000) &&
-// (alu_a & 0x80000) != (alu_res & 0x80000))
-// m_core->m_flags |= DSPI_FLAG_CC_OVER;
-
-// if (alu_res & 0x00100000)
-// m_core->m_flags |= DSPI_FLAG_CC_CARRY;
-
- CC_C_MODIFIED(desc);
- CC_V_MODIFIED(desc);
- break;
- }
- case 5: // _-B
- {
-// alu_res = alu_a - (m_core->m_flags & DSPI_FLAG_CC_CARRY) ? (1 << 4) : 0;
-
-// if (alu_res & 0x00100000)
-// m_core->m_flags |= DSPI_FLAG_CC_CARRY;
-
- CC_C_USED(desc);
- CC_C_MODIFIED(desc);
- break;
- }
case 6: // _++
- {
-// alu_res = alu_a + 1;
-
-// if (!(alu_a & 0x80000) && (alu_res & 0x80000))
-// m_core->m_flags |= DSPI_FLAG_CC_OVER;
-
- CC_V_MODIFIED(desc);
- break;
- }
case 7: // _--
- {
-// alu_res = alu_a - 1;
-
-// if ((alu_a & 0x80000) && !(alu_res & 0x80000))
-// m_core->m_flags |= DSPI_FLAG_CC_OVER;
-
- CC_V_MODIFIED(desc);
- break;
- }
case 8: // _TRL
- {
- //alu_res = alu_a;
- break;
- }
case 9: // _NOT
- {
- //alu_res = ~alu_a;
- break;
- }
case 10: // _AND
- {
- //alu_res = alu_a & alu_b;
- break;
- }
case 11: // _NAND
- {
- //alu_res = ~(alu_a & alu_b);
- break;
- }
case 12: // _OR
- {
- //alu_res = alu_a | alu_b;
- break;
- }
case 13: // _NOR
- {
- //alu_res = ~(alu_a | alu_b);
- break;
- }
case 14: // _XOR
+ case 15: // _XNOR
{
- //alu_res = alu_a ^ alu_b;
+ CC_C_MODIFIED(desc);
+ CC_V_MODIFIED(desc);
break;
}
- case 15: // _XNOR
+ case 3: // _+C
+ case 5: // _-B
{
- //alu_res = ~(alu_a ^ alu_b);
+ CC_C_USED(desc);
+ CC_C_MODIFIED(desc);
break;
}
}
-
- if (alu_res & 0x00080000)
- m_core->m_flags |= DSPI_FLAG_CC_NEG;
-
- if ((alu_res & 0x000ffff0) == 0)
- m_core->m_flags |= DSPI_FLAG_CC_ZERO;
-
- if ((alu_res & 0x0000000f) == 0)
- m_core->m_flags |= DSPI_FLAG_CC_EXACT;
-
CC_N_MODIFIED(desc);
CC_Z_MODIFIED(desc);
CC_X_MODIFIED(desc);
-
- ACCUMULATOR_MODIFIED_ALWAYS;
-
- // Barrel shift
- static const int32_t shifts[8] = { 0, 1, 2, 3, 4, 5, 8, 16 };
-
- if (barrel_code == 8)
- barrel_code = read_next_operand();
-
- if (barrel_code & 8)
- {
- // Right shift
- uint32_t shift = shifts[(~barrel_code + 1) & 7];
-
- if (alu_op < 8)
- {
- // Arithmetic
- m_core->m_acc = sign_extend20(alu_res) >> shift;
- }
- else
- {
- // Logical
- m_core->m_acc = (alu_res & 0xfffff) >> shift;
- }
- }
- else
- {
- // Left shift
- uint32_t shift = shifts[barrel_code];
-
- if (shift == 16)
- {
- // Clip and saturate
- if (m_core->m_flags & DSPI_FLAG_CC_OVER)
- m_core->m_acc = (m_core->m_flags & DSPI_FLAG_CC_NEG) ? 0x7ffff : 0xfff80000;
- else
- m_core->m_acc = sign_extend20(alu_res);
- }
- else
- {
- m_core->m_acc = sign_extend20(alu_res) << shift;
- }
- }
-
- if (m_core->m_writeback >= 0)
- {
- write_data(m_core->m_writeback, m_core->m_acc >> 4);
- m_core->m_writeback = -1;
- }
- else if (opidx < numops)
- {
- write_next_operand(m_core->m_acc >> 4);
- }
-#endif
- return true;
}
-
-#if 0
-void dspp_device::parse_operands(uint32_t numops)
+void dspp_frontend::parse_operands(uint16_t op, opcode_desc &desc, uint32_t numops)
{
- uint32_t addr, val = 0xBAD;
- uint32_t opidx = 0;
- uint32_t operand = 0;
uint32_t numregs = 0;
-
uint32_t opidx = 0;
while (opidx < numops)
{
- uint16_t op = desc.opptr.w[opidx + 1] = m_dspp->read_op(desc.physpc + opidx * 2);
+ uint16_t operand = desc.opptr.w[opidx + 1] = m_dspp->read_op(desc.physpc + opidx + 1);
- desc.length += 2;
- ++desc.cycles;
+ desc.length++;
+ desc.cycles++;
- if (op & 0x8000)
+ if (operand & 0x8000)
{
// Immediate value
- if ((op & 0xc000) == 0xc000)
+ if ((operand & 0xc000) == 0xc000)
{
- // Nothing?-
+ opidx++;
}
- else if((op & 0xe000) == 0x8000)
+ else if((operand & 0xe000) == 0x8000)
{
- if (op & 0x0400) // Indirect
+ if (operand & 0x0400) // Indirect
desc.flags |= OPFLAG_READS_MEMORY;
- if (op & 0x0800 )// Write Back
+ if (operand & 0x0800 )// Write Back
desc.flags |= OPFLAG_WRITES_MEMORY;
- ++opidx;
+ opidx++;
}
else if ((op & 0xe000) == 0xa000)
{
@@ -596,7 +368,6 @@ void dspp_device::parse_operands(uint32_t numops)
{
uint32_t shift = ((numregs - i) - 1) * 5;
uint32_t regdi = (operand >> shift) & 0x1f;
- // OP USES REGBASE?
if (regdi & 0x0010)
{
@@ -617,9 +388,9 @@ void dspp_device::parse_operands(uint32_t numops)
if (operand & 0x800)
desc.flags |= OPFLAG_WRITES_MEMORY;
}
+ opidx++;
}
numregs = 0;
}
}
}
-#endif
diff --git a/src/devices/cpu/dspp/dsppfe.h b/src/devices/cpu/dspp/dsppfe.h
index a90dc5d0225..b3eb5cb0d4d 100644
--- a/src/devices/cpu/dspp/dsppfe.h
+++ b/src/devices/cpu/dspp/dsppfe.h
@@ -59,10 +59,11 @@ private:
// inlines
// internal helpers
- bool describe_special(uint16_t op, opcode_desc &desc);
- bool describe_branch(uint16_t op, opcode_desc &desc);
- bool describe_complex_branch(uint16_t op, opcode_desc &desc);
- bool describe_arithmetic(uint16_t op, opcode_desc &desc);
+ void describe_special(uint16_t op, opcode_desc &desc);
+ void describe_branch(uint16_t op, opcode_desc &desc);
+ void describe_complex_branch(uint16_t op, opcode_desc &desc);
+ void describe_arithmetic(uint16_t op, opcode_desc &desc);
+ void parse_operands(uint16_t op, opcode_desc &desc, uint32_t numops);
// internal state
dspp_device *m_dspp;