Added highly experimental SHARC recompiler (disabled by default) [Ville Linde]

This commit is contained in:
Ville Linde 2016-05-28 17:46:58 +03:00
parent 9cf8e8ac0a
commit 958731ef5a
13 changed files with 8520 additions and 1311 deletions

View File

@ -221,6 +221,9 @@ if (CPUS["ADSP21062"]~=null) then
MAME_DIR .. "src/devices/cpu/sharc/sharcmem.hxx",
MAME_DIR .. "src/devices/cpu/sharc/sharcops.h",
MAME_DIR .. "src/devices/cpu/sharc/sharcops.hxx",
MAME_DIR .. "src/devices/cpu/sharc/sharcdrc.cpp",
MAME_DIR .. "src/devices/cpu/sharc/sharcfe.cpp",
MAME_DIR .. "src/devices/cpu/sharc/sharcfe.h",
}
end

View File

@ -171,6 +171,7 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdes
desc->delayslots = 0;
desc->skipslots = 0;
desc->flags = 0;
desc->userflags = 0;
desc->cycles = 0;
memset(desc->regin, 0x00, sizeof(desc->regin));
memset(desc->regout, 0x00, sizeof(desc->regout));

View File

@ -113,6 +113,7 @@ struct opcode_desc
UINT8 delayslots; // number of delay slots (for branches)
UINT8 skipslots; // number of skip slots (for branches)
UINT32 flags; // OPFLAG_* opcode flags
UINT32 userflags; // core specific flags
UINT32 cycles; // number of cycles needed to execute
// register usage information

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,8 @@
#ifndef __SHARC_H__
#define __SHARC_H__
#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#define SHARC_INPUT_FLAG0 3
#define SHARC_INPUT_FLAG1 4
@ -21,7 +23,7 @@ enum SHARC_BOOT_MODE
};
struct SHARC_DAG
struct alignas(16) SHARC_DAG
{
UINT32 i[8];
UINT32 m[8];
@ -71,12 +73,73 @@ struct SHARC_DMA_OP
};
// STKY flags
#define AUS 0x1 /* ALU floating-point underflow */
#define AVS 0x2 /* ALU floating-point overflow */
#define AOS 0x4 /* ALU fixed-point overflow */
#define AIS 0x20 /* ALU floating-point invalid operation */
// MODE1 flags
#define MODE1_BR8 0x1 /* Bit-reverse for I8 */
#define MODE1_BR0 0x2 /* Bit-reverse for I0 */
#define MODE1_SRCU 0x4 /* Alternate register select for computational units */
#define MODE1_SRD1H 0x8 /* DAG alternate register select (7-4) */
#define MODE1_SRD1L 0x10 /* DAG alternate register select (3-0) */
#define MODE1_SRD2H 0x20 /* DAG alternate register select (15-12) */
#define MODE1_SRD2L 0x40 /* DAG alternate register select (11-8) */
#define MODE1_SRRFH 0x80 /* Register file alternate select for R(15-8) */
#define MODE1_SRRFL 0x400 /* Register file alternate select for R(7-0) */
#define MODE1_NESTM 0x800 /* Interrupt nesting enable */
#define MODE1_IRPTEN 0x1000 /* Global interrupt enable */
#define MODE1_ALUSAT 0x2000 /* Enable ALU fixed-point saturation */
#define MODE1_SSE 0x4000 /* Enable short word sign extension */
#define MODE1_TRUNCATE 0x8000 /* (1) Floating-point truncation / (0) round to nearest */
#define MODE1_RND32 0x10000 /* (1) 32-bit floating-point rounding / (0) 40-bit rounding */
#define MODE1_CSEL 0x60000 /* CSelect */
// MODE2 flags
#define MODE2_IRQ0E 0x1 /* IRQ0 (1) Edge sens. / (0) Level sens. */
#define MODE2_IRQ1E 0x2 /* IRQ1 (1) Edge sens. / (0) Level sens. */
#define MODE2_IRQ2E 0x4 /* IRQ2 (1) Edge sens. / (0) Level sens. */
#define MODE2_CADIS 0x10 /* Cache disable */
#define MODE2_TIMEN 0x20 /* Timer enable */
#define MODE2_BUSLK 0x40 /* External bus lock */
#define MODE2_FLG0O 0x8000 /* FLAG0 (1) Output / (0) Input */
#define MODE2_FLG1O 0x10000 /* FLAG1 (1) Output / (0) Input */
#define MODE2_FLG2O 0x20000 /* FLAG2 (1) Output / (0) Input */
#define MODE2_FLG3O 0x40000 /* FLAG3 (1) Output / (0) Input */
#define MODE2_CAFRZ 0x80000 /* Cache freeze */
#define SIGN_EXTEND6(x) (((x) & 0x20) ? (0xffffffc0 | (x)) : (x))
#define SIGN_EXTEND24(x) (((x) & 0x800000) ? (0xff000000 | (x)) : (x))
#define MAKE_EXTRACT_MASK(start_bit, length) ((0xffffffff << start_bit) & (((UINT32)0xffffffff) >> (32 - (start_bit + length))))
#define OP_USERFLAG_COUNTER_LOOP 0x00000001
#define OP_USERFLAG_COND_LOOP 0x00000002
#define OP_USERFLAG_COND_FIELD 0x0000003c
#define OP_USERFLAG_COND_FIELD_SHIFT 2
#define OP_USERFLAG_ASTAT_DELAY_COPY_AZ 0x00001000
#define OP_USERFLAG_ASTAT_DELAY_COPY_AN 0x00002000
#define OP_USERFLAG_ASTAT_DELAY_COPY_AC 0x00004000
#define OP_USERFLAG_ASTAT_DELAY_COPY_AV 0x00008000
#define OP_USERFLAG_ASTAT_DELAY_COPY_MV 0x00010000
#define OP_USERFLAG_ASTAT_DELAY_COPY_MN 0x00020000
#define OP_USERFLAG_ASTAT_DELAY_COPY_SV 0x00040000
#define OP_USERFLAG_ASTAT_DELAY_COPY_SZ 0x00080000
#define OP_USERFLAG_ASTAT_DELAY_COPY_BTF 0x00100000
#define OP_USERFLAG_ASTAT_DELAY_COPY 0x001ff000
#define MCFG_SHARC_BOOT_MODE(boot_mode) \
adsp21062_device::set_boot_mode(*device, boot_mode);
class sharc_frontend;
class adsp21062_device : public cpu_device
{
friend class sharc_frontend;
public:
// construction/destruction
adsp21062_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
@ -91,6 +154,92 @@ public:
TIMER_CALLBACK_MEMBER(sharc_iop_delayed_write_callback);
TIMER_CALLBACK_MEMBER(sharc_dma_callback);
void sharc_cfunc_unimplemented();
void sharc_cfunc_read_iop();
void sharc_cfunc_write_iop();
void sharc_cfunc_pcstack_overflow();
void sharc_cfunc_pcstack_underflow();
void sharc_cfunc_loopstack_overflow();
void sharc_cfunc_loopstack_underflow();
void sharc_cfunc_statusstack_overflow();
void sharc_cfunc_statusstack_underflow();
void sharc_cfunc_unimplemented_compute();
void sharc_cfunc_unimplemented_shiftimm();
void sharc_cfunc_write_snoop();
enum ASTAT_FLAGS
{
// ASTAT flags
AZ = 0x1, /* ALU result zero */
AV = 0x2, /* ALU overflow */
AN = 0x4, /* ALU result negative */
AC = 0x8, /* ALU fixed-point carry */
AS = 0x10, /* ALU X input sign */
AI = 0x20, /* ALU floating-point invalid operation */
MN = 0x40, /* Multiplier result negative */
MV = 0x80, /* Multiplier overflow */
MU = 0x100, /* Multiplier underflow */
MI = 0x200, /* Multiplier floating-point invalid operation */
AF = 0x400,
SV = 0x800, /* Shifter overflow */
SZ = 0x1000, /* Shifter result zero */
SS = 0x2000, /* Shifter input sign */
BTF = 0x40000, /* Bit Test Flag */
FLG0 = 0x80000, /* FLAG0 */
FLG1 = 0x100000, /* FLAG1 */
FLG2 = 0x200000, /* FLAG2 */
FLG3 = 0x400000 /* FLAG3 */
};
enum ASTAT_SHIFT
{
AZ_SHIFT = 0,
AV_SHIFT = 1,
AN_SHIFT = 2,
AC_SHIFT = 3,
AS_SHIFT = 4,
AI_SHIFT = 5,
MN_SHIFT = 6,
MV_SHIFT = 7,
MU_SHIFT = 8,
MI_SHIFT = 9,
AF_SHIFT = 10,
SV_SHIFT = 11,
SZ_SHIFT = 12,
SS_SHIFT = 13,
BTF_SHIFT = 18,
FLG0_SHIFT = 19,
FLG1_SHIFT = 20,
FLG2_SHIFT = 21,
FLG3_SHIFT = 22
};
enum MODE1_DELAY_MODE
{
MODE1_WRITE_IMM,
MODE1_WRITE_REG,
MODE1_SET,
MODE1_CLEAR,
MODE1_TOGGLE,
};
enum MEM_ACCESSOR_TYPE
{
MEM_ACCESSOR_PM_READ48,
MEM_ACCESSOR_PM_WRITE48,
MEM_ACCESSOR_PM_READ32,
MEM_ACCESSOR_PM_WRITE32,
MEM_ACCESSOR_DM_READ32,
MEM_ACCESSOR_DM_WRITE32
};
enum
{
EXCEPTION_INTERRUPT = 0,
EXCEPTION_COUNT
};
protected:
// device-level overrides
virtual void device_start() override;
@ -109,10 +258,12 @@ protected:
virtual bool memory_readop(offs_t offset, int size, UINT64 &value) override;
// device_disasm_interface overrides
virtual UINT32 disasm_min_opcode_bytes() const override { return 1; }
virtual UINT32 disasm_max_opcode_bytes() const override { return 40; }
virtual UINT32 disasm_min_opcode_bytes() const override { return 6; }
virtual UINT32 disasm_max_opcode_bytes() const override { return 6; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
direct_read_data *m_direct;
private:
address_space_config m_program_config;
address_space_config m_data_config;
@ -126,94 +277,178 @@ private:
};
static const SHARC_OP s_sharc_opcode_table[];
UINT32 m_pc;
SHARC_REG m_r[16];
SHARC_REG m_reg_alt[16];
UINT64 m_mrf;
UINT64 m_mrb;
UINT32 m_pcstack[32];
UINT32 m_lcstack[6];
UINT32 m_lastack[6];
UINT32 m_lstkp;
UINT32 m_faddr;
UINT32 m_daddr;
UINT32 m_pcstk;
UINT32 m_pcstkp;
SHARC_LADDR m_laddr;
UINT32 m_curlcntr;
UINT32 m_lcntr;
UINT8 m_extdma_shift;
/* Data Address Generator (DAG) */
SHARC_DAG m_dag1; // (DM bus)
SHARC_DAG m_dag2; // (PM bus)
SHARC_DAG m_dag1_alt;
SHARC_DAG m_dag2_alt;
SHARC_DMA_REGS m_dma[12];
/* System registers */
UINT32 m_mode1;
UINT32 m_mode2;
UINT32 m_astat;
UINT32 m_stky;
UINT32 m_irptl;
UINT32 m_imask;
UINT32 m_imaskp;
UINT32 m_ustat1;
UINT32 m_ustat2;
UINT32 m_flag[4];
UINT32 m_syscon;
UINT32 m_sysstat;
struct
struct ASTAT_DRC
{
UINT32 mode1;
UINT32 astat;
} m_status_stack[5];
INT32 m_status_stkp;
union
{
struct
{
UINT32 az;
UINT32 av;
UINT32 an;
UINT32 ac;
UINT32 as;
UINT32 ai;
UINT32 mn;
UINT32 mv;
UINT32 mu;
UINT32 mi;
UINT32 sv;
UINT32 sz;
UINT32 ss;
UINT32 btf;
UINT32 af;
UINT32 cacc;
};
UINT64 flags64[8];
};
};
UINT64 m_px;
struct alignas(16) sharc_internal_state
{
SHARC_REG r[16];
SHARC_REG reg_alt[16];
UINT32 pc;
UINT64 mrf;
UINT64 mrb;
UINT32 pcstack[32];
UINT32 lcstack[6];
UINT32 lastack[6];
UINT32 lstkp;
UINT32 faddr;
UINT32 daddr;
UINT32 pcstk;
UINT32 pcstkp;
SHARC_LADDR laddr;
UINT32 curlcntr;
UINT32 lcntr;
UINT8 extdma_shift;
/* Data Address Generator (DAG) */
SHARC_DAG dag1; // (DM bus)
SHARC_DAG dag2; // (PM bus)
SHARC_DAG dag1_alt;
SHARC_DAG dag2_alt;
SHARC_DMA_REGS dma[12];
/* System registers */
UINT32 mode1;
UINT32 mode2;
UINT32 astat;
UINT32 stky;
UINT32 irptl;
UINT32 imask;
UINT32 imaskp;
UINT32 ustat1;
UINT32 ustat2;
UINT32 flag[4];
UINT32 syscon;
UINT32 sysstat;
struct
{
UINT32 mode1;
UINT32 astat;
} status_stack[5];
INT32 status_stkp;
UINT64 px;
int icount;
UINT64 opcode;
UINT32 nfaddr;
INT32 idle;
INT32 irq_pending;
INT32 active_irq_num;
SHARC_DMA_OP dma_op[12];
UINT32 dma_status;
INT32 interrupt_active;
UINT32 iop_delayed_reg;
UINT32 iop_delayed_data;
emu_timer *delayed_iop_timer;
UINT32 delay_slot1, delay_slot2;
INT32 systemreg_latency_cycles;
INT32 systemreg_latency_reg;
UINT32 systemreg_latency_data;
UINT32 systemreg_previous_data;
UINT32 astat_old;
UINT32 astat_old_old;
UINT32 astat_old_old_old;
UINT32 arg0;
UINT32 arg1;
UINT32 arg2;
UINT32 arg3;
UINT64 arg64;
UINT32 mode1_delay_data;
ASTAT_DRC astat_drc;
ASTAT_DRC astat_drc_copy;
ASTAT_DRC astat_delay_copy;
UINT32 dreg_temp;
UINT32 jmpdest;
float fp0;
float fp1;
UINT32 force_recompile;
};
sharc_internal_state* m_core;
SHARC_BOOT_MODE m_boot_mode;
// UML stuff
drc_cache m_cache;
std::unique_ptr<drcuml_state> m_drcuml;
std::unique_ptr<sharc_frontend> m_drcfe;
uml::parameter m_regmap[16];
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_pm_read48;
uml::code_handle *m_pm_write48;
uml::code_handle *m_pm_read32;
uml::code_handle *m_pm_write32;
uml::code_handle *m_dm_read32;
uml::code_handle *m_dm_write32;
uml::code_handle *m_push_pc;
uml::code_handle *m_pop_pc;
uml::code_handle *m_push_loop;
uml::code_handle *m_pop_loop;
uml::code_handle *m_push_status;
uml::code_handle *m_pop_status;
uml::code_handle *m_exception[EXCEPTION_COUNT]; // exception handlers
uml::code_handle *m_swap_dag1_0_3;
uml::code_handle *m_swap_dag1_4_7;
uml::code_handle *m_swap_dag2_0_3;
uml::code_handle *m_swap_dag2_4_7;
uml::code_handle *m_swap_r0_7;
uml::code_handle *m_swap_r8_15;
bool m_cache_dirty;
UINT16 *m_internal_ram_block0, *m_internal_ram_block1;
address_space *m_program;
address_space *m_data;
opcode_func m_sharc_op[512];
int m_icount;
UINT64 m_opcode;
UINT32 m_nfaddr;
INT32 m_idle;
INT32 m_irq_active;
INT32 m_active_irq_num;
SHARC_BOOT_MODE m_boot_mode;
SHARC_DMA_OP m_dma_op[12];
UINT32 m_dma_status;
INT32 m_interrupt_active;
UINT32 m_iop_delayed_reg;
UINT32 m_iop_delayed_data;
emu_timer *m_delayed_iop_timer;
UINT32 m_delay_slot1, m_delay_slot2;
INT32 m_systemreg_latency_cycles;
INT32 m_systemreg_latency_reg;
UINT32 m_systemreg_latency_data;
UINT32 m_systemreg_previous_data;
UINT32 m_astat_old;
UINT32 m_astat_old_old;
UINT32 m_astat_old_old_old;
UINT16 m_internal_ram[2 * 0x10000]; // 2x 128KB
@ -349,6 +584,59 @@ private:
inline void compute_fmul_dual_fadd_fsub(int fm, int fxm, int fym, int fa, int fs, int fxa, int fya);
void build_opcode_table();
/* internal compiler state */
struct compiler_state
{
UINT32 cycles; /* accumulated cycles */
UINT8 checkints; /* need to check interrupts before next instruction */
uml::code_label labelnum; /* index for local labels */
struct
{
int counter;
int mode;
UINT32 data;
} mode1_delay;
};
void execute_run_drc();
void flush_cache();
void compile_block(offs_t pc);
void alloc_handle(drcuml_state *drcuml, uml::code_handle **handleptr, const char *name);
void static_generate_entry_point();
void static_generate_nocode_handler();
void static_generate_out_of_cycles();
void static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, const char *name, uml::code_handle *&handleptr);
void static_generate_exception(UINT8 exception, const char *name);
void static_generate_push_pc();
void static_generate_pop_pc();
void static_generate_push_loop();
void static_generate_pop_loop();
void static_generate_push_status();
void static_generate_pop_status();
void static_generate_mode1_ops();
void load_fast_iregs(drcuml_block *block);
void save_fast_iregs(drcuml_block *block);
void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, int allow_exception);
int generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_unimplemented_compute(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_compute(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_if_condition(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int condition, int skip_label);
void generate_do_condition(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int condition, int skip_label, ASTAT_DRC &astat);
void generate_shift_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int data, int shiftop, int rn, int rx);
void generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, bool delayslot);
void generate_jump(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, bool delayslot, bool loopabort, bool clearint);
void generate_write_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
void generate_set_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
void generate_clear_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
void generate_toggle_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
void generate_read_ureg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int ureg, bool has_compute);
void generate_write_ureg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int ureg, bool imm, UINT32 data);
void generate_update_circular_buffer(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int g, int i);
void generate_astat_copy(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
bool if_condition_always_true(int condition);
UINT32 do_condition_astat_bits(int condition);
};

View File

@ -21,80 +21,80 @@ void adsp21062_device::schedule_chained_dma_op(int channel, UINT32 dma_chain_ptr
UINT32 ext_modifier = dm_read32(op_ptr - 6);
UINT32 ext_count = dm_read32(op_ptr - 7);
if (m_dma_op[channel].active)
if (m_core->dma_op[channel].active)
{
fatalerror("schedule_chained_dma_op: DMA operation already scheduled at %08X!\n", m_pc);
fatalerror("schedule_chained_dma_op: DMA operation already scheduled at %08X!\n", m_core->pc);
}
if (chained_direction) // Transmit to external
{
m_dma_op[channel].dst = ext_index;
m_dma_op[channel].dst_modifier = ext_modifier;
m_dma_op[channel].dst_count = ext_count;
m_dma_op[channel].src = int_index;
m_dma_op[channel].src_modifier = int_modifier;
m_dma_op[channel].src_count = int_count;
m_core->dma_op[channel].dst = ext_index;
m_core->dma_op[channel].dst_modifier = ext_modifier;
m_core->dma_op[channel].dst_count = ext_count;
m_core->dma_op[channel].src = int_index;
m_core->dma_op[channel].src_modifier = int_modifier;
m_core->dma_op[channel].src_count = int_count;
}
else // Receive from external
{
m_dma_op[channel].src = ext_index;
m_dma_op[channel].src_modifier = ext_modifier;
m_dma_op[channel].src_count = ext_count;
m_dma_op[channel].dst = int_index;
m_dma_op[channel].dst_modifier = int_modifier;
m_dma_op[channel].dst_count = int_count;
m_core->dma_op[channel].src = ext_index;
m_core->dma_op[channel].src_modifier = ext_modifier;
m_core->dma_op[channel].src_count = ext_count;
m_core->dma_op[channel].dst = int_index;
m_core->dma_op[channel].dst_modifier = int_modifier;
m_core->dma_op[channel].dst_count = int_count;
}
m_dma_op[channel].pmode = 0;
m_dma_op[channel].chain_ptr = chain_ptr;
m_dma_op[channel].chained_direction = chained_direction;
m_core->dma_op[channel].pmode = 0;
m_core->dma_op[channel].chain_ptr = chain_ptr;
m_core->dma_op[channel].chained_direction = chained_direction;
m_dma_op[channel].active = true;
m_core->dma_op[channel].active = true;
int cycles = m_dma_op[channel].src_count / 4;
m_dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
int cycles = m_core->dma_op[channel].src_count / 4;
m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
// enable busy flag
m_dma_status |= (1 << channel);
m_core->dma_status |= (1 << channel);
}
void adsp21062_device::schedule_dma_op(int channel, UINT32 src, UINT32 dst, int src_modifier, int dst_modifier, int src_count, int dst_count, int pmode)
{
if (m_dma_op[channel].active)
if (m_core->dma_op[channel].active)
{
fatalerror("schedule_dma_op: DMA operation already scheduled at %08X!\n", m_pc);
fatalerror("schedule_dma_op: DMA operation already scheduled at %08X!\n", m_core->pc);
}
m_dma_op[channel].src = src;
m_dma_op[channel].dst = dst;
m_dma_op[channel].src_modifier = src_modifier;
m_dma_op[channel].dst_modifier = dst_modifier;
m_dma_op[channel].src_count = src_count;
m_dma_op[channel].dst_count = dst_count;
m_dma_op[channel].pmode = pmode;
m_dma_op[channel].chain_ptr = 0;
m_core->dma_op[channel].src = src;
m_core->dma_op[channel].dst = dst;
m_core->dma_op[channel].src_modifier = src_modifier;
m_core->dma_op[channel].dst_modifier = dst_modifier;
m_core->dma_op[channel].src_count = src_count;
m_core->dma_op[channel].dst_count = dst_count;
m_core->dma_op[channel].pmode = pmode;
m_core->dma_op[channel].chain_ptr = 0;
m_dma_op[channel].active = true;
m_core->dma_op[channel].active = true;
int cycles = src_count / 4;
m_dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
// enable busy flag
m_dma_status |= (1 << channel);
m_core->dma_status |= (1 << channel);
}
void adsp21062_device::dma_op(int channel)
{
int i;
UINT32 src = m_dma_op[channel].src;
UINT32 dst = m_dma_op[channel].dst;
int src_modifier = m_dma_op[channel].src_modifier;
int dst_modifier = m_dma_op[channel].dst_modifier;
int src_count = m_dma_op[channel].src_count;
//int dst_count = m_dma_op[channel].dst_count;
int pmode = m_dma_op[channel].pmode;
UINT32 src = m_core->dma_op[channel].src;
UINT32 dst = m_core->dma_op[channel].dst;
int src_modifier = m_core->dma_op[channel].src_modifier;
int dst_modifier = m_core->dma_op[channel].dst_modifier;
int src_count = m_core->dma_op[channel].src_count;
//int dst_count = m_core->dma_op[channel].dst_count;
int pmode = m_core->dma_op[channel].pmode;
//printf("dma_op: %08X, %08X, %08X, %08X, %08X, %08X, %d\n", src, dst, src_modifier, dst_modifier, src_count, dst_count, pmode);
//printf("dma_op: %08X, %08X, %08X, %08X, %08X, %d\n", src, dst, src_modifier, dst_modifier, src_count, pmode);
switch (pmode)
{
@ -148,19 +148,19 @@ void adsp21062_device::dma_op(int channel)
if (channel == 6)
{
m_irptl |= (1 << (channel+10));
m_core->irptl |= (1 << (channel+10));
/* DMA interrupt */
if (m_imask & (1 << (channel+10)))
if (m_core->imask & (1 << (channel+10)))
{
m_irq_active |= 1 << (channel+10);
m_core->irq_pending |= 1 << (channel+10);
}
}
// clear busy flag
m_dma_status &= ~(1 << channel);
m_core->dma_status &= ~(1 << channel);
m_dma_op[channel].active = false;
m_core->dma_op[channel].active = false;
}
void adsp21062_device::sharc_dma_exec(int channel)
@ -170,16 +170,16 @@ void adsp21062_device::sharc_dma_exec(int channel)
UINT32 src_modifier, dst_modifier;
int chen, tran, dtype, pmode, /*mswf, master,*/ ishake, intio/*, ext, flsh*/;
chen = (m_dma[channel].control >> 1) & 0x1;
tran = (m_dma[channel].control >> 2) & 0x1;
dtype = (m_dma[channel].control >> 5) & 0x1;
pmode = (m_dma[channel].control >> 6) & 0x3;
//mswf = (m_dma[channel].control >> 8) & 0x1;
//master = (m_dma[channel].control >> 9) & 0x1;
ishake = (m_dma[channel].control >> 10) & 0x1;
intio = (m_dma[channel].control >> 11) & 0x1;
//ext = (m_dma[channel].control >> 12) & 0x1;
//flsh = (m_dma[channel].control >> 13) & 0x1;
chen = (m_core->dma[channel].control >> 1) & 0x1;
tran = (m_core->dma[channel].control >> 2) & 0x1;
dtype = (m_core->dma[channel].control >> 5) & 0x1;
pmode = (m_core->dma[channel].control >> 6) & 0x3;
//mswf = (m_core->dma[channel].control >> 8) & 0x1;
//master = (m_core->dma[channel].control >> 9) & 0x1;
ishake = (m_core->dma[channel].control >> 10) & 0x1;
intio = (m_core->dma[channel].control >> 11) & 0x1;
//ext = (m_core->dma[channel].control >> 12) & 0x1;
//flsh = (m_core->dma[channel].control >> 13) & 0x1;
if (ishake)
fatalerror("SHARC: dma_exec: handshake not supported\n");
@ -189,7 +189,7 @@ void adsp21062_device::sharc_dma_exec(int channel)
if (chen) // Chained DMA
{
UINT32 dma_chain_ptr = m_dma[channel].chain_ptr & 0x1ffff;
UINT32 dma_chain_ptr = m_core->dma[channel].chain_ptr & 0x1ffff;
schedule_chained_dma_op(channel, dma_chain_ptr, tran);
}
@ -197,21 +197,21 @@ void adsp21062_device::sharc_dma_exec(int channel)
{
if (tran) // Transmit to external
{
dst = m_dma[channel].ext_index;
dst_modifier = m_dma[channel].ext_modifier;
dst_count = m_dma[channel].ext_count;
src = (m_dma[channel].int_index & 0x1ffff) | 0x20000;
src_modifier = m_dma[channel].int_modifier;
src_count = m_dma[channel].int_count;
dst = m_core->dma[channel].ext_index;
dst_modifier = m_core->dma[channel].ext_modifier;
dst_count = m_core->dma[channel].ext_count;
src = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000;
src_modifier = m_core->dma[channel].int_modifier;
src_count = m_core->dma[channel].int_count;
}
else // Receive from external
{
src = m_dma[channel].ext_index;
src_modifier = m_dma[channel].ext_modifier;
src_count = m_dma[channel].ext_count;
dst = (m_dma[channel].int_index & 0x1ffff) | 0x20000;
dst_modifier = m_dma[channel].int_modifier;
dst_count = m_dma[channel].int_count;
src = m_core->dma[channel].ext_index;
src_modifier = m_core->dma[channel].ext_modifier;
src_count = m_core->dma[channel].ext_count;
dst = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000;
dst_modifier = m_core->dma[channel].int_modifier;
dst_count = m_core->dma[channel].int_count;
}
if (dtype)
@ -228,19 +228,19 @@ TIMER_CALLBACK_MEMBER(adsp21062_device::sharc_dma_callback)
{
int channel = param;
m_dma_op[channel].timer->adjust(attotime::never, 0);
m_core->dma_op[channel].timer->adjust(attotime::never, 0);
m_irptl |= (1 << (channel+10));
m_core->irptl |= (1 << (channel+10));
// DMA interrupt
if (m_imask & (1 << (channel+10)))
if (m_core->imask & (1 << (channel+10)))
{
m_irq_active |= 1 << (channel+10);
m_core->irq_pending |= 1 << (channel+10);
}
dma_op(channel);
if (m_dma_op[channel].chain_ptr != 0)
if (m_core->dma_op[channel].chain_ptr != 0)
{
schedule_chained_dma_op(channel, m_dma_op[channel].chain_ptr, m_dma_op[channel].chained_direction);
schedule_chained_dma_op(channel, m_core->dma_op[channel].chain_ptr, m_core->dma_op[channel].chained_direction);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -88,14 +88,14 @@ static void compute(UINT32 opcode)
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
{
print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, rs, rxa+8, rya+12);
print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12);
break;
}
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
{
print("F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, rs, rxa+8, rya+12);
print("F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12);
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
// license:BSD-3-Clause
// copyright-holders:Ville Linde
/******************************************************************************
Front-end for SHARC recompiler
******************************************************************************/
#pragma once
#include "sharc.h"
#include "cpu/drcfe.h"
#ifndef __SHARCFE_H__
#define __SHARCFE_H__
class sharc_frontend : public drc_frontend
{
public:
sharc_frontend(adsp21062_device *sharc, UINT32 window_start, UINT32 window_end, UINT32 max_sequence);
void flush();
enum UREG_ACCESS
{
UREG_READ,
UREG_WRITE
};
enum LOOP_TYPE
{
LOOP_TYPE_COUNTER,
LOOP_TYPE_CONDITIONAL
};
enum LOOP_ENTRY_TYPE
{
LOOP_ENTRY_START = 0x1,
LOOP_ENTRY_EVALUATION = 0x2,
LOOP_ENTRY_ASTAT_CHECK = 0x4,
};
struct LOOP_ENTRY
{
UINT16 entrytype;
UINT8 looptype;
UINT8 condition;
UINT32 start_pc;
};
struct LOOP_DESCRIPTOR
{
UINT32 start_pc;
UINT32 end_pc;
UINT32 astat_check_pc;
LOOP_TYPE type;
int condition;
};
protected:
// required overrides
virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
private:
bool describe_compute(opcode_desc &desc, UINT64 opcode);
bool describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCESS access);
bool describe_shiftop_imm(opcode_desc &desc, int shiftop, int rn, int rx);
void describe_if_condition(opcode_desc &desc, int condition);
void insert_loop(const LOOP_DESCRIPTOR &loopdesc);
void add_loop_entry(UINT32 pc, UINT8 type, UINT32 start_pc, UINT8 looptype, UINT8 condition);
bool is_loop_evaluation(UINT32 pc);
bool is_loop_start(UINT32 pc);
bool is_astat_delay_check(UINT32 pc);
adsp21062_device *m_sharc;
std::unique_ptr<LOOP_ENTRY[]> m_loopmap;
};
#endif /* __SHARCFE_H__ */

View File

@ -20,12 +20,13 @@ UINT32 adsp21062_device::pm_read32(UINT32 address)
(m_internal_ram_block1[addr + 1]);
}
else {
fatalerror("SHARC: PM Bus Read32 %08X at %08X\n", address, m_pc);
fatalerror("SHARC: PM Bus Read32 %08X at %08X\n", address, m_core->pc);
}
}
void adsp21062_device::pm_write32(UINT32 address, UINT32 data)
{
// printf("PM Write32 %08X, %08X at %08X\n", data, address, m_core->pc);
if (address >= 0x20000 && address < 0x28000)
{
UINT32 addr = (address & 0x7fff) * 3;
@ -44,7 +45,8 @@ void adsp21062_device::pm_write32(UINT32 address, UINT32 data)
return;
}
else {
fatalerror("SHARC: PM Bus Write32 %08X, %08X at %08X\n", address, data, m_pc);
debugger_break(machine());
//fatalerror("SHARC: PM Bus Write32 %08X, %08X at %08X\n", address, data, m_core->pc);
}
}
@ -68,7 +70,7 @@ UINT64 adsp21062_device::pm_read48(UINT32 address)
((UINT64)(m_internal_ram_block1[addr + 2]) << 0);
}
else {
fatalerror("SHARC: PM Bus Read48 %08X at %08X\n", address, m_pc);
fatalerror("SHARC: PM Bus Read48 %08X at %08X\n", address, m_core->pc);
}
return 0;
@ -76,6 +78,7 @@ UINT64 adsp21062_device::pm_read48(UINT32 address)
void adsp21062_device::pm_write48(UINT32 address, UINT64 data)
{
// printf("PM Write48 %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), address, m_core->pc);
if ((address >= 0x20000 && address < 0x28000))
{
UINT32 addr = (address & 0x7fff) * 3;
@ -96,7 +99,7 @@ void adsp21062_device::pm_write48(UINT32 address, UINT64 data)
return;
}
else {
fatalerror("SHARC: PM Bus Write48 %08X, %04X%08X at %08X\n", address, (UINT16)(data >> 32),(UINT32)data, m_pc);
fatalerror("SHARC: PM Bus Write48 %08X, %04X%08X at %08X\n", address, (UINT16)(data >> 32),(UINT32)data, m_core->pc);
}
}
@ -128,7 +131,7 @@ UINT32 adsp21062_device::dm_read32(UINT32 address)
UINT32 addr = address & 0xffff;
UINT16 r = m_internal_ram_block0[addr ^ 1];
if (m_mode1 & 0x4000)
if (m_core->mode1 & 0x4000)
{
// sign-extend
return (INT32)(INT16)(r);
@ -144,7 +147,7 @@ UINT32 adsp21062_device::dm_read32(UINT32 address)
UINT32 addr = address & 0xffff;
UINT16 r = m_internal_ram_block1[addr ^ 1];
if (m_mode1 & 0x4000)
if (m_core->mode1 & 0x4000)
{
// sign-extend
return (INT32)(INT16)(r);

File diff suppressed because it is too large Load Diff