mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
no help = no hyperstone drc, nw
This commit is contained in:
parent
8ace8fd4e0
commit
5d51e91100
@ -13,7 +13,7 @@
|
|||||||
-- Dynamic recompiler objects
|
-- Dynamic recompiler objects
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
if (CPUS["SH"]~=null or CPUS["MIPS"]~=null or CPUS["POWERPC"]~=null or CPUS["RSP"]~=null or CPUS["ARM7"]~=null or CPUS["ADSP21062"]~=null or CPUS["MB86235"]~=null or CPUS["E1"]~=null) then
|
if (CPUS["SH"]~=null or CPUS["MIPS"]~=null or CPUS["POWERPC"]~=null or CPUS["RSP"]~=null or CPUS["ARM7"]~=null or CPUS["ADSP21062"]~=null or CPUS["MB86235"]~=null) then
|
||||||
files {
|
files {
|
||||||
MAME_DIR .. "src/devices/cpu/drcbec.cpp",
|
MAME_DIR .. "src/devices/cpu/drcbec.cpp",
|
||||||
MAME_DIR .. "src/devices/cpu/drcbec.h",
|
MAME_DIR .. "src/devices/cpu/drcbec.h",
|
||||||
@ -808,10 +808,6 @@ if (CPUS["E1"]~=null) then
|
|||||||
files {
|
files {
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/e132xs.cpp",
|
MAME_DIR .. "src/devices/cpu/e132xs/e132xs.cpp",
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/e132xs.h",
|
MAME_DIR .. "src/devices/cpu/e132xs/e132xs.h",
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/e132xsfe.cpp",
|
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/e132xsfe.h",
|
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/e132xsdrc.cpp",
|
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/e132xsdrc_ops.hxx",
|
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/32xsdefs.h",
|
MAME_DIR .. "src/devices/cpu/e132xs/32xsdefs.h",
|
||||||
MAME_DIR .. "src/devices/cpu/e132xs/e132xsop.hxx",
|
MAME_DIR .. "src/devices/cpu/e132xs/e132xsop.hxx",
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,6 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "e132xs.h"
|
#include "e132xs.h"
|
||||||
#include "e132xsfe.h"
|
|
||||||
|
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
|
|
||||||
@ -153,9 +152,6 @@
|
|||||||
//#define VERBOSE 1
|
//#define VERBOSE 1
|
||||||
#include "logmacro.h"
|
#include "logmacro.h"
|
||||||
|
|
||||||
/* size of the execution code cache */
|
|
||||||
#define CACHE_SIZE (32 * 1024 * 1024)
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// INTERNAL ADDRESS MAP
|
// INTERNAL ADDRESS MAP
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -203,27 +199,6 @@ hyperstone_device::hyperstone_device(const machine_config &mconfig, const char *
|
|||||||
, m_program_config("program", ENDIANNESS_BIG, prg_data_width, 32, 0, internal_map)
|
, m_program_config("program", ENDIANNESS_BIG, prg_data_width, 32, 0, internal_map)
|
||||||
, m_io_config("io", ENDIANNESS_BIG, io_data_width, 15)
|
, m_io_config("io", ENDIANNESS_BIG, io_data_width, 15)
|
||||||
, m_icount(0)
|
, m_icount(0)
|
||||||
, m_cache(CACHE_SIZE + sizeof(hyperstone_device))
|
|
||||||
, m_drcuml(nullptr)
|
|
||||||
, m_drcfe(nullptr)
|
|
||||||
, m_drcoptions(0)
|
|
||||||
, m_cache_dirty(0)
|
|
||||||
, m_entry(nullptr)
|
|
||||||
, m_nocode(nullptr)
|
|
||||||
, m_out_of_cycles(nullptr)
|
|
||||||
, m_drc_arg0(0)
|
|
||||||
, m_drc_arg1(0)
|
|
||||||
, m_drc_arg2(0)
|
|
||||||
, m_drc_arg3(0)
|
|
||||||
, m_mem_read8(nullptr)
|
|
||||||
, m_mem_write8(nullptr)
|
|
||||||
, m_mem_read16(nullptr)
|
|
||||||
, m_mem_write16(nullptr)
|
|
||||||
, m_mem_read32(nullptr)
|
|
||||||
, m_mem_write32(nullptr)
|
|
||||||
, m_io_read32(nullptr)
|
|
||||||
, m_io_write32(nullptr)
|
|
||||||
, m_enable_drc(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,12 +992,6 @@ void hyperstone_device::device_start()
|
|||||||
|
|
||||||
void hyperstone_device::init(int scale_mask)
|
void hyperstone_device::init(int scale_mask)
|
||||||
{
|
{
|
||||||
#if ENABLE_E132XS_DRC
|
|
||||||
m_enable_drc = allow_drc();
|
|
||||||
#else
|
|
||||||
m_enable_drc = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(m_global_regs, 0, sizeof(uint32_t) * 32);
|
memset(m_global_regs, 0, sizeof(uint32_t) * 32);
|
||||||
memset(m_local_regs, 0, sizeof(uint32_t) * 64);
|
memset(m_local_regs, 0, sizeof(uint32_t) * 64);
|
||||||
m_op = 0;
|
m_op = 0;
|
||||||
@ -1057,38 +1026,6 @@ void hyperstone_device::init(int scale_mask)
|
|||||||
m_fl_lut[i] = (i ? i : 16);
|
m_fl_lut[i] = (i ? i : 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t umlflags = 0;
|
|
||||||
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 1, 32, 1);
|
|
||||||
|
|
||||||
// add UML symbols-
|
|
||||||
m_drcuml->symbol_add(&m_global_regs[0], sizeof(uint32_t), "pc");
|
|
||||||
m_drcuml->symbol_add(&m_global_regs[1], sizeof(uint32_t), "sr");
|
|
||||||
m_drcuml->symbol_add(&m_icount, sizeof(m_icount), "icount");
|
|
||||||
|
|
||||||
char buf[4];
|
|
||||||
for (int i=0; i < 32; i++)
|
|
||||||
{
|
|
||||||
sprintf(buf, "g%d", i);
|
|
||||||
m_drcuml->symbol_add(&m_global_regs[i], sizeof(uint32_t), buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i < 64; i++)
|
|
||||||
{
|
|
||||||
sprintf(buf, "l%d", i);
|
|
||||||
m_drcuml->symbol_add(&m_local_regs[i], sizeof(uint32_t), buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_drcuml->symbol_add(&m_drc_arg0, sizeof(uint32_t), "arg0");
|
|
||||||
m_drcuml->symbol_add(&m_drc_arg1, sizeof(uint32_t), "arg1");
|
|
||||||
m_drcuml->symbol_add(&m_drc_arg2, sizeof(uint32_t), "arg2");
|
|
||||||
m_drcuml->symbol_add(&m_drc_arg3, sizeof(uint32_t), "arg3");
|
|
||||||
|
|
||||||
/* initialize the front-end helper */
|
|
||||||
m_drcfe = std::make_unique<e132xs_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
|
|
||||||
|
|
||||||
/* mark the cache dirty so it is updated on next execute */
|
|
||||||
m_cache_dirty = true;
|
|
||||||
|
|
||||||
// register our state for the debugger
|
// register our state for the debugger
|
||||||
state_add(STATE_GENPC, "GENPC", m_global_regs[0]).noshow();
|
state_add(STATE_GENPC, "GENPC", m_global_regs[0]).noshow();
|
||||||
state_add(STATE_GENPCBASE, "CURPC", m_global_regs[0]).noshow();
|
state_add(STATE_GENPCBASE, "CURPC", m_global_regs[0]).noshow();
|
||||||
@ -1347,14 +1284,6 @@ void hyperstone_device::device_reset()
|
|||||||
|
|
||||||
void hyperstone_device::device_stop()
|
void hyperstone_device::device_stop()
|
||||||
{
|
{
|
||||||
if (m_drcfe != nullptr)
|
|
||||||
{
|
|
||||||
m_drcfe = nullptr;
|
|
||||||
}
|
|
||||||
if (m_drcuml != nullptr)
|
|
||||||
{
|
|
||||||
m_drcuml = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1521,12 +1450,6 @@ void hyperstone_device::hyperstone_do()
|
|||||||
|
|
||||||
void hyperstone_device::execute_run()
|
void hyperstone_device::execute_run()
|
||||||
{
|
{
|
||||||
if (m_enable_drc)
|
|
||||||
{
|
|
||||||
execute_run_drc();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_intblock < 0)
|
if (m_intblock < 0)
|
||||||
m_intblock = 0;
|
m_intblock = 0;
|
||||||
|
|
||||||
|
@ -5,9 +5,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "cpu/drcfe.h"
|
|
||||||
#include "cpu/drcuml.h"
|
|
||||||
#include "cpu/drcumlsh.h"
|
|
||||||
#include "32xsdasm.h"
|
#include "32xsdasm.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -26,32 +23,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
CONSTANTS
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/* map variables */
|
|
||||||
#define MAPVAR_PC M0
|
|
||||||
#define MAPVAR_CYCLES M1
|
|
||||||
|
|
||||||
/* compilation boundaries -- how far back/forward does the analysis extend? */
|
|
||||||
#define COMPILE_BACKWARDS_BYTES 128
|
|
||||||
#define COMPILE_FORWARDS_BYTES 512
|
|
||||||
#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4))
|
|
||||||
#define COMPILE_MAX_SEQUENCE 64
|
|
||||||
|
|
||||||
/* exit codes */
|
|
||||||
#define EXECUTE_OUT_OF_CYCLES 0
|
|
||||||
#define EXECUTE_MISSING_CODE 1
|
|
||||||
#define EXECUTE_UNMAPPED_CODE 2
|
|
||||||
#define EXECUTE_RESET_CACHE 3
|
|
||||||
|
|
||||||
#define E132XS_STRICT_VERIFY 0x0001 /* verify all instructions */
|
|
||||||
|
|
||||||
#define SINGLE_INSTRUCTION_MODE (1)
|
|
||||||
|
|
||||||
#define ENABLE_E132XS_DRC (0)
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// TYPE DEFINITIONS
|
// TYPE DEFINITIONS
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -374,156 +345,6 @@ private:
|
|||||||
|
|
||||||
void hyperstone_reserved();
|
void hyperstone_reserved();
|
||||||
void hyperstone_do();
|
void hyperstone_do();
|
||||||
|
|
||||||
drc_cache m_cache;
|
|
||||||
std::unique_ptr<drcuml_state> m_drcuml;
|
|
||||||
std::unique_ptr<e132xs_frontend> m_drcfe;
|
|
||||||
uint32_t m_drcoptions;
|
|
||||||
uint8_t m_cache_dirty;
|
|
||||||
|
|
||||||
uml::parameter m_regmap[16];
|
|
||||||
|
|
||||||
uml::code_handle *m_entry;
|
|
||||||
uml::code_handle *m_nocode;
|
|
||||||
uml::code_handle *m_out_of_cycles;
|
|
||||||
|
|
||||||
uint32_t m_drc_arg0;
|
|
||||||
uint32_t m_drc_arg1;
|
|
||||||
uint32_t m_drc_arg2;
|
|
||||||
uint32_t m_drc_arg3;
|
|
||||||
uint32_t m_branch_dest;
|
|
||||||
|
|
||||||
uml::code_handle *m_mem_read8;
|
|
||||||
uml::code_handle *m_mem_write8;
|
|
||||||
uml::code_handle *m_mem_read16;
|
|
||||||
uml::code_handle *m_mem_write16;
|
|
||||||
uml::code_handle *m_mem_read32;
|
|
||||||
uml::code_handle *m_mem_write32;
|
|
||||||
uml::code_handle *m_io_read32;
|
|
||||||
uml::code_handle *m_io_write32;
|
|
||||||
uml::code_handle *m_exception[EXCEPTION_COUNT];
|
|
||||||
|
|
||||||
bool m_enable_drc;
|
|
||||||
|
|
||||||
/* internal compiler state */
|
|
||||||
struct compiler_state
|
|
||||||
{
|
|
||||||
uint32_t m_cycles; /* accumulated cycles */
|
|
||||||
uint8_t m_checkints; /* need to check interrupts before next instruction */
|
|
||||||
uml::code_label m_labelnum; /* index for local labels */
|
|
||||||
};
|
|
||||||
|
|
||||||
void execute_run_drc();
|
|
||||||
void flush_drc_cache();
|
|
||||||
void code_flush_cache();
|
|
||||||
void code_compile_block(offs_t pc);
|
|
||||||
//void load_fast_iregs(drcuml_block *block);
|
|
||||||
//void save_fast_iregs(drcuml_block *block);
|
|
||||||
void static_generate_entry_point();
|
|
||||||
void static_generate_nocode_handler();
|
|
||||||
void static_generate_out_of_cycles();
|
|
||||||
void static_generate_exception(uint32_t exception, const char *name);
|
|
||||||
void static_generate_memory_accessor(int size, int iswrite, bool isio, const char *name, uml::code_handle *&handleptr);
|
|
||||||
void generate_delay_slot_and_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
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);
|
|
||||||
void log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op);
|
|
||||||
bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
void generate_get_trap_addr(drcuml_block *block, uml::code_label &label, uint32_t trapno);
|
|
||||||
void generate_check_delay_pc(drcuml_block *block);
|
|
||||||
void generate_decode_const(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_ignore_immediate_s(drcuml_block *block, const opcode_desc *desc);
|
|
||||||
void generate_decode_pcrel(drcuml_block *block, const opcode_desc *desc);
|
|
||||||
void generate_ignore_pcrel(drcuml_block *block, const opcode_desc *desc);
|
|
||||||
|
|
||||||
void generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
void generate_trap(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr);
|
|
||||||
void generate_int(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr);
|
|
||||||
void generate_exception(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr);
|
|
||||||
void generate_software(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_chk(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_movd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void generate_divsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_xm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mask(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sum(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sums(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_cmp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mov(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_add(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_adds(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_cmpb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_subc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sub(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_subs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_addc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_neg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_negs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_and(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_andn(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_or(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_xor(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_not(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addsi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpbi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_andni(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_ori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_xori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <shift_type HI_N> void generate_shrdi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_shrd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_shr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_shri(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <shift_type HI_N> void generate_sardi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_sard(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_sar(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_sari(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <shift_type HI_N> void generate_shldi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_shld(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_shl(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_shli(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_testlz(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_rol(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_ldxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_ldxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_stxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_stxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void generate_mulsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mul(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_set(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_ldwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_lddr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_ldwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_lddp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_stwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_stdr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_stwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <reg_bank SRC_GLOBAL> void generate_stdp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
template <branch_condition CONDITION, condition_set COND_SET> void generate_b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_br(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <branch_condition CONDITION, condition_set COND_SET> void generate_db(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_dbr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
void generate_frame(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
template <hyperstone_device::reg_bank SRC_GLOBAL> void generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
void generate_trap_op(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_extend(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
|
|
||||||
void generate_reserved(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
void generate_do(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
|
@ -1,983 +0,0 @@
|
|||||||
// license:BSD-3-Clause
|
|
||||||
// copyright-holders:Ryan Holtz
|
|
||||||
|
|
||||||
#include "emu.h"
|
|
||||||
#include "e132xs.h"
|
|
||||||
#include "e132xsfe.h"
|
|
||||||
#include "32xsdefs.h"
|
|
||||||
|
|
||||||
using namespace uml;
|
|
||||||
|
|
||||||
#define DRC_PC mem(m_global_regs)
|
|
||||||
#define DRC_SR mem(&m_global_regs[1])
|
|
||||||
|
|
||||||
void hyperstone_device::execute_run_drc()
|
|
||||||
{
|
|
||||||
drcuml_state *drcuml = m_drcuml.get();
|
|
||||||
int execute_result;
|
|
||||||
|
|
||||||
/* reset the cache if dirty */
|
|
||||||
if (m_cache_dirty)
|
|
||||||
{
|
|
||||||
code_flush_cache();
|
|
||||||
m_cache_dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* execute */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* run as much as we can */
|
|
||||||
execute_result = drcuml->execute(*m_entry);
|
|
||||||
|
|
||||||
/* if we need to recompile, do it */
|
|
||||||
if (execute_result == EXECUTE_MISSING_CODE)
|
|
||||||
{
|
|
||||||
code_compile_block(m_global_regs[0]);
|
|
||||||
}
|
|
||||||
else if (execute_result == EXECUTE_UNMAPPED_CODE)
|
|
||||||
{
|
|
||||||
fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_global_regs[0]);
|
|
||||||
}
|
|
||||||
else if (execute_result == EXECUTE_RESET_CACHE)
|
|
||||||
{
|
|
||||||
code_flush_cache();
|
|
||||||
}
|
|
||||||
} while (execute_result != EXECUTE_OUT_OF_CYCLES);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
C FUNCTION CALLBACKS
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
cfunc_unimplemented - handler for
|
|
||||||
unimplemented opcdes
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
inline void hyperstone_device::ccfunc_unimplemented()
|
|
||||||
{
|
|
||||||
fatalerror("PC=%08X: Unimplemented op %08X\n", PC, m_drc_arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void hyperstone_device::ccfunc_print()
|
|
||||||
{
|
|
||||||
printf("%c: %08X\n", (char)m_drc_arg0, m_drc_arg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cfunc_unimplemented(void *param)
|
|
||||||
{
|
|
||||||
((hyperstone_device *)param)->ccfunc_unimplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cfunc_adjust_timer_interrupt(void *param)
|
|
||||||
{
|
|
||||||
((hyperstone_device *)param)->adjust_timer_interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cfunc_compute_tr(void *param)
|
|
||||||
{
|
|
||||||
((hyperstone_device *)param)->compute_tr();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cfunc_update_timer_prescale(void *param)
|
|
||||||
{
|
|
||||||
((hyperstone_device *)param)->update_timer_prescale();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void cfunc_print(void *param)
|
|
||||||
{
|
|
||||||
((hyperstone_device *)param)->ccfunc_print();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
ccfunc_total_cycles - compute the total number
|
|
||||||
of cycles executed so far
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::ccfunc_total_cycles()
|
|
||||||
{
|
|
||||||
m_numcycles = total_cycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cfunc_total_cycles(void *param)
|
|
||||||
{
|
|
||||||
((hyperstone_device *)param)->ccfunc_total_cycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
CACHE MANAGEMENT
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
flush_drc_cache - outward-facing accessor to
|
|
||||||
code_flush_cache
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::flush_drc_cache()
|
|
||||||
{
|
|
||||||
if (!m_enable_drc)
|
|
||||||
return;
|
|
||||||
m_cache_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
code_flush_cache - flush the cache and
|
|
||||||
regenerate static code
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::code_flush_cache()
|
|
||||||
{
|
|
||||||
/* empty the transient cache contents */
|
|
||||||
m_drcuml->reset();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/* generate the entry point and out-of-cycles handlers */
|
|
||||||
static_generate_entry_point();
|
|
||||||
static_generate_nocode_handler();
|
|
||||||
static_generate_out_of_cycles();
|
|
||||||
|
|
||||||
static_generate_exception(EXCEPTION_IO2, "io2");
|
|
||||||
static_generate_exception(EXCEPTION_IO1, "io1");
|
|
||||||
static_generate_exception(EXCEPTION_INT4, "int4");
|
|
||||||
static_generate_exception(EXCEPTION_INT3, "int3");
|
|
||||||
static_generate_exception(EXCEPTION_INT2, "int2");
|
|
||||||
static_generate_exception(EXCEPTION_INT1, "int1");
|
|
||||||
static_generate_exception(EXCEPTION_IO3, "io3");
|
|
||||||
static_generate_exception(EXCEPTION_TIMER, "timer");
|
|
||||||
static_generate_exception(EXCEPTION_RESERVED1, "reserved1");
|
|
||||||
static_generate_exception(EXCEPTION_TRACE, "trace");
|
|
||||||
static_generate_exception(EXCEPTION_PARITY_ERROR, "parity_error");
|
|
||||||
static_generate_exception(EXCEPTION_EXTENDED_OVERFLOW, "extended_overflow");
|
|
||||||
static_generate_exception(EXCEPTION_RANGE_ERROR, "range_error");
|
|
||||||
static_generate_exception(EXCEPTION_RESERVED2, "reserved2");
|
|
||||||
static_generate_exception(EXCEPTION_RESET, "reset");
|
|
||||||
static_generate_exception(EXCEPTION_ERROR_ENTRY, "error_entry");
|
|
||||||
|
|
||||||
/* add subroutines for memory accesses */
|
|
||||||
static_generate_memory_accessor(1, false, false, "read8", m_mem_read8);
|
|
||||||
static_generate_memory_accessor(1, true, false, "write8", m_mem_write8);
|
|
||||||
static_generate_memory_accessor(2, false, false, "read16", m_mem_read16);
|
|
||||||
static_generate_memory_accessor(2, true, false, "write16", m_mem_write16);
|
|
||||||
static_generate_memory_accessor(4, false, false, "read32", m_mem_read32);
|
|
||||||
static_generate_memory_accessor(4, true, false, "write32", m_mem_write32);
|
|
||||||
static_generate_memory_accessor(4, false, true, "ioread32", m_io_read32);
|
|
||||||
static_generate_memory_accessor(4, true, true, "iowrite32", m_io_write32);
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (drcuml_block::abort_compilation &)
|
|
||||||
{
|
|
||||||
fatalerror("Unable to generate static E132XS code\n"); fflush(stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the entry point for a determinated trap */
|
|
||||||
void hyperstone_device::generate_get_trap_addr(drcuml_block *block, uml::code_label &label, uint32_t trapno)
|
|
||||||
{
|
|
||||||
int no_mem3;
|
|
||||||
UML_MOV(block, I0, trapno);
|
|
||||||
UML_CMP(block, mem(&m_trap_entry), 0xffffff00);
|
|
||||||
UML_JMPc(block, uml::COND_NE, no_mem3 = label++);
|
|
||||||
UML_SUB(block, I0, 63, I0);
|
|
||||||
|
|
||||||
UML_LABEL(block, no_mem3);
|
|
||||||
UML_SHL(block, I0, I0, 2);
|
|
||||||
UML_OR(block, I0, I0, mem(&m_trap_entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
code_compile_block - compile a block of the
|
|
||||||
given mode at the specified pc
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::code_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;
|
|
||||||
drcuml_block *block;
|
|
||||||
|
|
||||||
g_profiler.start(PROFILER_DRC_COMPILE);
|
|
||||||
|
|
||||||
/* get a description of this sequence */
|
|
||||||
desclist = m_drcfe->describe_code(pc);
|
|
||||||
|
|
||||||
bool succeeded = false;
|
|
||||||
while (!succeeded)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
/* start the block */
|
|
||||||
block = drcuml->begin_block(4096);
|
|
||||||
|
|
||||||
/* loop until we get through all instruction sequences */
|
|
||||||
for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next())
|
|
||||||
{
|
|
||||||
const opcode_desc *curdesc;
|
|
||||||
uint32_t nextpc;
|
|
||||||
|
|
||||||
/* add a code log entry */
|
|
||||||
if (drcuml->logging())
|
|
||||||
block->append_comment("-------------------------");
|
|
||||||
|
|
||||||
/* determine the last instruction in this sequence */
|
|
||||||
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
|
|
||||||
if (seqlast->flags & OPFLAG_END_SEQUENCE)
|
|
||||||
break;
|
|
||||||
assert(seqlast != nullptr);
|
|
||||||
|
|
||||||
/* if we don't have a hash for this mode/pc, or if we are overriding all, add one */
|
|
||||||
if (override || !drcuml->hash_exists(0, seqhead->pc))
|
|
||||||
UML_HASH(block, 0, seqhead->pc);
|
|
||||||
|
|
||||||
/* if we already have a hash, and this is the first sequence, assume that we */
|
|
||||||
/* are recompiling due to being out of sync and allow future overrides */
|
|
||||||
else if (seqhead == desclist)
|
|
||||||
{
|
|
||||||
override = true;
|
|
||||||
UML_HASH(block, 0, seqhead->pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* otherwise, redispatch to that fixed PC and skip the rest of the processing */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UML_LABEL(block, seqhead->pc | 0x80000000);
|
|
||||||
UML_HASHJMP(block, 0, seqhead->pc, *m_nocode);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* validate this code block if we're not pointing into ROM */
|
|
||||||
if (m_program->get_write_ptr(seqhead->physpc) != nullptr)
|
|
||||||
generate_checksum_block(block, &compiler, seqhead, seqlast);
|
|
||||||
|
|
||||||
/* label this instruction, if it may be jumped to locally */
|
|
||||||
if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
|
|
||||||
UML_LABEL(block, seqhead->pc | 0x80000000);
|
|
||||||
|
|
||||||
/* iterate over instructions in the sequence and compile them */
|
|
||||||
for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
|
|
||||||
{
|
|
||||||
generate_sequence_instruction(block, &compiler, curdesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* count off cycles and go there */
|
|
||||||
generate_update_cycles(block, &compiler, nextpc); // <subtract cycles>
|
|
||||||
|
|
||||||
/* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */
|
|
||||||
if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc)
|
|
||||||
{
|
|
||||||
UML_HASHJMP(block, 0, nextpc, *m_nocode); // hashjmp <mode>,nextpc,nocode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end the sequence */
|
|
||||||
block->end();
|
|
||||||
g_profiler.stop();
|
|
||||||
succeeded = true;
|
|
||||||
}
|
|
||||||
catch (drcuml_block::abort_compilation &)
|
|
||||||
{
|
|
||||||
code_flush_cache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
STATIC CODEGEN
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
epc - compute the exception PC from a
|
|
||||||
descriptor
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static inline uint32_t epc(const opcode_desc *desc)
|
|
||||||
{
|
|
||||||
return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 3) : desc->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
alloc_handle - allocate a handle if not
|
|
||||||
already allocated
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static inline void alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name)
|
|
||||||
{
|
|
||||||
if (*handleptr == nullptr)
|
|
||||||
*handleptr = drcuml->handle_alloc(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
static_generate_exception - generate an
|
|
||||||
exception handler
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::static_generate_exception(uint32_t exception, const char *name)
|
|
||||||
{
|
|
||||||
code_handle *&exception_handle = m_exception[exception];
|
|
||||||
drcuml_state *drcuml = m_drcuml.get();
|
|
||||||
drcuml_block *block = drcuml->begin_block(1024);
|
|
||||||
|
|
||||||
/* add a global entry for this */
|
|
||||||
alloc_handle(drcuml, &exception_handle, name);
|
|
||||||
UML_HANDLE(block, *exception_handle);
|
|
||||||
|
|
||||||
uml::code_label label = 1;
|
|
||||||
generate_get_trap_addr(block, label, exception);
|
|
||||||
UML_ROLAND(block, I1, DRC_SR, 7, 0x7f);
|
|
||||||
UML_ROLAND(block, I2, DRC_SR, 11, 0xf);
|
|
||||||
UML_TEST(block, I2, 0xf);
|
|
||||||
UML_MOVc(block, uml::COND_Z, I2, 16);
|
|
||||||
UML_ADD(block, I1, I1, I2);
|
|
||||||
|
|
||||||
UML_AND(block, DRC_SR, DRC_SR, 0xffe7ffff);
|
|
||||||
UML_OR(block, DRC_SR, DRC_SR, mem(&m_instruction_length));
|
|
||||||
|
|
||||||
UML_MOV(block, I4, DRC_SR);
|
|
||||||
UML_ROLINS(block, DRC_SR, 2, 21, 0x01e00000);
|
|
||||||
UML_ROLINS(block, DRC_SR, I1, 25, 0xfe000000);
|
|
||||||
|
|
||||||
UML_AND(block, I3, I1, 0x3f);
|
|
||||||
UML_AND(block, I1, DRC_PC, ~1);
|
|
||||||
UML_ROLAND(block, I2, DRC_SR, 14, 1);
|
|
||||||
UML_OR(block, I1, I1, I2);
|
|
||||||
UML_STORE(block, (void *)m_local_regs, I3, I1, SIZE_DWORD, SCALE_x4);
|
|
||||||
UML_ADD(block, I3, I3, 1);
|
|
||||||
UML_AND(block, I3, I3, 0x3f);
|
|
||||||
UML_STORE(block, (void *)m_local_regs, I3, I4, SIZE_DWORD, SCALE_x4);
|
|
||||||
|
|
||||||
UML_AND(block, DRC_SR, DRC_SR, ~(M_MASK | T_MASK));
|
|
||||||
UML_OR(block, DRC_SR, DRC_SR, (L_MASK | S_MASK));
|
|
||||||
|
|
||||||
UML_MOV(block, DRC_PC, I0);
|
|
||||||
UML_SUB(block, mem(&m_icount), mem(&m_icount), 2);
|
|
||||||
UML_EXHc(block, COND_S, *m_out_of_cycles, 0);
|
|
||||||
|
|
||||||
UML_HASHJMP(block, 0, I0, *m_nocode);// hashjmp <mode>,i0,nocode
|
|
||||||
|
|
||||||
block->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
generate_entry_point - generate a
|
|
||||||
static entry point
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::static_generate_entry_point()
|
|
||||||
{
|
|
||||||
drcuml_state *drcuml = m_drcuml.get();
|
|
||||||
drcuml_block *block;
|
|
||||||
|
|
||||||
/* begin generating */
|
|
||||||
block = drcuml->begin_block(20);
|
|
||||||
|
|
||||||
/* forward references */
|
|
||||||
alloc_handle(drcuml, &m_nocode, "nocode");
|
|
||||||
|
|
||||||
alloc_handle(drcuml, &m_entry, "entry");
|
|
||||||
UML_HANDLE(block, *m_entry);
|
|
||||||
|
|
||||||
/* load fast integer registers */
|
|
||||||
//load_fast_iregs(block);
|
|
||||||
|
|
||||||
/* generate a hash jump via the current mode and PC */
|
|
||||||
UML_HASHJMP(block, 0, mem(&m_global_regs[0]), *m_nocode);
|
|
||||||
block->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
static_generate_nocode_handler - generate an
|
|
||||||
exception handler for "out of code"
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::static_generate_nocode_handler()
|
|
||||||
{
|
|
||||||
drcuml_state *drcuml = m_drcuml.get();
|
|
||||||
drcuml_block *block;
|
|
||||||
|
|
||||||
/* begin generating */
|
|
||||||
block = drcuml->begin_block(10);
|
|
||||||
|
|
||||||
/* generate a hash jump via the current mode and PC */
|
|
||||||
alloc_handle(drcuml, &m_nocode, "nocode");
|
|
||||||
UML_HANDLE(block, *m_nocode);
|
|
||||||
UML_GETEXP(block, I0);
|
|
||||||
UML_MOV(block, mem(&PC), I0);
|
|
||||||
//save_fast_iregs(block);
|
|
||||||
UML_EXIT(block, EXECUTE_MISSING_CODE);
|
|
||||||
|
|
||||||
block->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
static_generate_out_of_cycles - generate an
|
|
||||||
out of cycles exception handler
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::static_generate_out_of_cycles()
|
|
||||||
{
|
|
||||||
drcuml_state *drcuml = m_drcuml.get();
|
|
||||||
drcuml_block *block;
|
|
||||||
|
|
||||||
/* begin generating */
|
|
||||||
block = drcuml->begin_block(10);
|
|
||||||
|
|
||||||
/* generate a hash jump via the current mode and PC */
|
|
||||||
alloc_handle(drcuml, &m_out_of_cycles, "out_of_cycles");
|
|
||||||
UML_HANDLE(block, *m_out_of_cycles);
|
|
||||||
UML_GETEXP(block, I0);
|
|
||||||
UML_MOV(block, mem(&m_global_regs[0]), I0);
|
|
||||||
//save_fast_iregs(block);
|
|
||||||
UML_EXIT(block, EXECUTE_OUT_OF_CYCLES);
|
|
||||||
|
|
||||||
block->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------
|
|
||||||
static_generate_memory_accessor
|
|
||||||
------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::static_generate_memory_accessor(int size, int iswrite, bool isio, const char *name, code_handle *&handleptr)
|
|
||||||
{
|
|
||||||
/* on entry, address is in I0; data for writes is in I1 */
|
|
||||||
/* on exit, read result is in I1 */
|
|
||||||
/* routine trashes I0-I1 */
|
|
||||||
drcuml_state *drcuml = m_drcuml.get();
|
|
||||||
drcuml_block *block;
|
|
||||||
|
|
||||||
/* begin generating */
|
|
||||||
block = drcuml->begin_block(1024);
|
|
||||||
|
|
||||||
/* add a global entry for this */
|
|
||||||
alloc_handle(drcuml, &handleptr, name);
|
|
||||||
UML_HANDLE(block, *handleptr);
|
|
||||||
|
|
||||||
// write:
|
|
||||||
switch (size)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
if (iswrite)
|
|
||||||
UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM);
|
|
||||||
else
|
|
||||||
UML_READ(block, I1, I0, SIZE_BYTE, SPACE_PROGRAM);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
if (iswrite)
|
|
||||||
UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM);
|
|
||||||
else
|
|
||||||
UML_READ(block, I1, I0, SIZE_WORD, SPACE_PROGRAM);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
if (iswrite)
|
|
||||||
UML_WRITE(block, I0, I1, SIZE_DWORD, isio ? SPACE_IO : SPACE_PROGRAM);
|
|
||||||
else
|
|
||||||
UML_READ(block, I1, I0, SIZE_DWORD, isio ? SPACE_IO : SPACE_PROGRAM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
UML_RET(block);
|
|
||||||
|
|
||||||
block->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
CODE GENERATION
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
generate_update_cycles - generate code to
|
|
||||||
subtract cycles from the icount and generate
|
|
||||||
an exception if out
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param)
|
|
||||||
{
|
|
||||||
/* account for cycles */
|
|
||||||
if (compiler->m_cycles > 0)
|
|
||||||
{
|
|
||||||
UML_SUB(block, mem(&m_icount), mem(&m_icount), MAPVAR_CYCLES);
|
|
||||||
UML_MAPVAR(block, MAPVAR_CYCLES, 0);
|
|
||||||
UML_EXHc(block, COND_S, *m_out_of_cycles, param);
|
|
||||||
}
|
|
||||||
compiler->m_cycles = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
generate_checksum_block - generate code to
|
|
||||||
validate a sequence of opcodes
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast)
|
|
||||||
{
|
|
||||||
const opcode_desc *curdesc;
|
|
||||||
if (m_drcuml->logging())
|
|
||||||
{
|
|
||||||
block->append_comment("[Validation for %08X]", seqhead->pc);
|
|
||||||
}
|
|
||||||
/* loose verify or single instruction: just compare and fail */
|
|
||||||
if (!(m_drcoptions & E132XS_STRICT_VERIFY) || seqhead->next() == nullptr)
|
|
||||||
{
|
|
||||||
if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
|
|
||||||
{
|
|
||||||
uint32_t sum = seqhead->opptr.w[0];
|
|
||||||
void *base = m_direct->read_ptr(seqhead->physpc);
|
|
||||||
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2);
|
|
||||||
|
|
||||||
if (seqhead->delay.first() != nullptr && seqhead->physpc != seqhead->delay.first()->physpc)
|
|
||||||
{
|
|
||||||
base = m_direct->read_ptr(seqhead->delay.first()->physpc);
|
|
||||||
assert(base != nullptr);
|
|
||||||
UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2);
|
|
||||||
UML_ADD(block, I0, I0, I1);
|
|
||||||
|
|
||||||
sum += seqhead->delay.first()->opptr.w[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
UML_CMP(block, I0, sum);
|
|
||||||
UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* full verification; sum up everything */
|
|
||||||
{
|
|
||||||
void *base = m_direct->read_ptr(seqhead->physpc);
|
|
||||||
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2);
|
|
||||||
uint32_t sum = seqhead->opptr.w[0];
|
|
||||||
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
|
|
||||||
if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
|
|
||||||
{
|
|
||||||
base = m_direct->read_ptr(curdesc->physpc);
|
|
||||||
assert(base != nullptr);
|
|
||||||
UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2);
|
|
||||||
UML_ADD(block, I0, I0, I1);
|
|
||||||
sum += curdesc->opptr.w[0];
|
|
||||||
|
|
||||||
if (curdesc->delay.first() != nullptr && (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->physpc != curdesc->delay.first()->physpc)))
|
|
||||||
{
|
|
||||||
base = m_direct->read_ptr(curdesc->delay.first()->physpc);
|
|
||||||
assert(base != nullptr);
|
|
||||||
UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2);
|
|
||||||
UML_ADD(block, I0, I0, I1);
|
|
||||||
|
|
||||||
sum += curdesc->delay.first()->opptr.w[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UML_CMP(block, I0, sum);
|
|
||||||
UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
log_add_disasm_comment - add a comment
|
|
||||||
including disassembly of a MIPS instruction
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op)
|
|
||||||
{
|
|
||||||
if (m_drcuml->logging())
|
|
||||||
{
|
|
||||||
block->append_comment("%08X: %08x", pc, op);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------
|
|
||||||
generate_delay_slot_and_branch
|
|
||||||
------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::generate_delay_slot_and_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
|
||||||
{
|
|
||||||
compiler_state compiler_temp = *compiler;
|
|
||||||
|
|
||||||
/* fetch the target register if dynamic, in case it is modified by the delay slot */
|
|
||||||
if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
|
|
||||||
{
|
|
||||||
UML_MOV(block, mem(&m_branch_dest), DRC_PC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->delayslots)
|
|
||||||
{
|
|
||||||
/* compile the delay slot using temporary compiler state */
|
|
||||||
assert(desc->delay.first() != nullptr);
|
|
||||||
generate_sequence_instruction(block, &compiler_temp, desc->delay.first()); // <next instruction>
|
|
||||||
UML_MOV(block, mem(&m_branch_dest), DRC_PC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
|
|
||||||
UML_JMP(block, desc->targetpc | 0x80000000);
|
|
||||||
else
|
|
||||||
UML_HASHJMP(block, 0, desc->targetpc, *m_nocode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
generate_update_cycles(block, &compiler_temp, mem(&m_branch_dest));
|
|
||||||
UML_HASHJMP(block, 0, mem(&m_branch_dest), *m_nocode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update the label */
|
|
||||||
compiler->m_labelnum = compiler_temp.m_labelnum;
|
|
||||||
|
|
||||||
/* reset the mapvar to the current cycles */
|
|
||||||
UML_MAPVAR(block, MAPVAR_CYCLES, compiler->m_cycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
generate_sequence_instruction - generate code
|
|
||||||
for a single instruction in a sequence
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
void hyperstone_device::generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
|
||||||
{
|
|
||||||
offs_t expc;
|
|
||||||
|
|
||||||
/* add an entry for the log */
|
|
||||||
if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
|
|
||||||
log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]);
|
|
||||||
|
|
||||||
/* set the PC map variable */
|
|
||||||
expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 3 : desc->pc;
|
|
||||||
UML_MAPVAR(block, MAPVAR_PC, expc);
|
|
||||||
|
|
||||||
/* accumulate total cycles */
|
|
||||||
compiler->m_cycles += desc->cycles;
|
|
||||||
|
|
||||||
/* update the icount map variable */
|
|
||||||
UML_MAPVAR(block, MAPVAR_CYCLES, compiler->m_cycles);
|
|
||||||
|
|
||||||
/* if we are debugging, call the debugger */
|
|
||||||
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
|
|
||||||
{
|
|
||||||
UML_MOV(block, DRC_PC, desc->pc);
|
|
||||||
//save_fast_iregs(block);
|
|
||||||
UML_DEBUG(block, desc->pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
|
|
||||||
{
|
|
||||||
/* compile the instruction */
|
|
||||||
if (!generate_opcode(block, compiler, desc))
|
|
||||||
{
|
|
||||||
UML_MOV(block, DRC_PC, desc->pc);
|
|
||||||
UML_MOV(block, mem(&m_drc_arg0), desc->opptr.w[0]);
|
|
||||||
UML_CALLC(block, cfunc_unimplemented, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "e132xsdrc_ops.hxx"
|
|
||||||
|
|
||||||
bool hyperstone_device::generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
|
|
||||||
{
|
|
||||||
uint32_t op = (uint32_t)desc->opptr.w[0];
|
|
||||||
|
|
||||||
UML_MOV(block, I0, op);
|
|
||||||
UML_AND(block, I7, DRC_SR, H_MASK);
|
|
||||||
UML_ADD(block, DRC_PC, DRC_PC, 2);
|
|
||||||
UML_MOV(block, mem(&m_instruction_length), (1 << 19));
|
|
||||||
|
|
||||||
switch (op >> 8)
|
|
||||||
{
|
|
||||||
case 0x00: generate_chk<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x01: generate_chk<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x02: generate_chk<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x03: generate_chk<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x04: generate_movd<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x05: generate_movd<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x06: generate_movd<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x07: generate_movd<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x08: generate_divsu<GLOBAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x09: generate_divsu<GLOBAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x0a: generate_divsu<LOCAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x0b: generate_divsu<LOCAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x0c: generate_divsu<GLOBAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x0d: generate_divsu<GLOBAL, LOCAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x0e: generate_divsu<LOCAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x0f: generate_divsu<LOCAL, LOCAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0x10: generate_xm<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x11: generate_xm<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x12: generate_xm<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x13: generate_xm<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x14: generate_mask<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x15: generate_mask<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x16: generate_mask<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x17: generate_mask<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x18: generate_sum<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x19: generate_sum<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x1a: generate_sum<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x1b: generate_sum<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x1c: generate_sums<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x1d: generate_sums<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x1e: generate_sums<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x1f: generate_sums<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x20: generate_cmp<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x21: generate_cmp<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x22: generate_cmp<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x23: generate_cmp<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x24: generate_mov<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x25: generate_mov<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x26: generate_mov<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x27: generate_mov<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x28: generate_add<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x29: generate_add<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x2a: generate_add<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x2b: generate_add<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x2c: generate_adds<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x2d: generate_adds<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x2e: generate_adds<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x2f: generate_adds<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x30: generate_cmpb<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x31: generate_cmpb<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x32: generate_cmpb<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x33: generate_cmpb<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x34: generate_andn<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x35: generate_andn<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x36: generate_andn<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x37: generate_andn<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x38: generate_or<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x39: generate_or<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x3a: generate_or<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x3b: generate_or<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x3c: generate_xor<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x3d: generate_xor<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x3e: generate_xor<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x3f: generate_xor<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x40: generate_subc<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x41: generate_subc<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x42: generate_subc<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x43: generate_subc<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x44: generate_not<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x45: generate_not<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x46: generate_not<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x47: generate_not<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x48: generate_sub<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x49: generate_sub<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x4a: generate_sub<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x4b: generate_sub<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x4c: generate_subs<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x4d: generate_subs<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x4e: generate_subs<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x4f: generate_subs<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x50: generate_addc<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x51: generate_addc<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x52: generate_addc<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x53: generate_addc<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x54: generate_and<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x55: generate_and<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x56: generate_and<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x57: generate_and<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x58: generate_neg<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x59: generate_neg<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x5a: generate_neg<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x5b: generate_neg<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x5c: generate_negs<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x5d: generate_negs<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x5e: generate_negs<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x5f: generate_negs<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x60: generate_cmpi<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x61: generate_cmpi<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x62: generate_cmpi<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x63: generate_cmpi<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x64: generate_movi<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x65: generate_movi<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x66: generate_movi<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x67: generate_movi<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x68: generate_addi<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x69: generate_addi<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x6a: generate_addi<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x6b: generate_addi<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x6c: generate_addsi<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x6d: generate_addsi<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x6e: generate_addsi<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x6f: generate_addsi<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x70: generate_cmpbi<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x71: generate_cmpbi<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x72: generate_cmpbi<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x73: generate_cmpbi<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x74: generate_andni<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x75: generate_andni<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x76: generate_andni<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x77: generate_andni<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x78: generate_ori<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x79: generate_ori<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x7a: generate_ori<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x7b: generate_ori<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x7c: generate_xori<GLOBAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x7d: generate_xori<GLOBAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x7e: generate_xori<LOCAL, SIMM>(block, compiler, desc); break;
|
|
||||||
case 0x7f: generate_xori<LOCAL, LIMM>(block, compiler, desc); break;
|
|
||||||
case 0x80: generate_shrdi<N_LO>(block, compiler, desc); break;
|
|
||||||
case 0x81: generate_shrdi<N_HI>(block, compiler, desc); break;
|
|
||||||
case 0x82: generate_shrd(block, compiler, desc); break;
|
|
||||||
case 0x83: generate_shr(block, compiler, desc); break;
|
|
||||||
case 0x84: generate_sardi<N_LO>(block, compiler, desc); break;
|
|
||||||
case 0x85: generate_sardi<N_HI>(block, compiler, desc); break;
|
|
||||||
case 0x86: generate_sard(block, compiler, desc); break;
|
|
||||||
case 0x87: generate_sar(block, compiler, desc); break;
|
|
||||||
case 0x88: generate_shldi<N_LO>(block, compiler, desc); break;
|
|
||||||
case 0x89: generate_shldi<N_HI>(block, compiler, desc); break;
|
|
||||||
case 0x8a: generate_shld(block, compiler, desc); break;
|
|
||||||
case 0x8b: generate_shl(block, compiler, desc); break;
|
|
||||||
case 0x8c: generate_reserved(block, compiler, desc); break;
|
|
||||||
case 0x8d: generate_reserved(block, compiler, desc); break;
|
|
||||||
case 0x8e: generate_testlz(block, compiler, desc); break;
|
|
||||||
case 0x8f: generate_rol(block, compiler, desc); break;
|
|
||||||
case 0x90: generate_ldxx1<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x91: generate_ldxx1<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x92: generate_ldxx1<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x93: generate_ldxx1<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x94: generate_ldxx2<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x95: generate_ldxx2<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x96: generate_ldxx2<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x97: generate_ldxx2<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x98: generate_stxx1<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x99: generate_stxx1<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x9a: generate_stxx1<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x9b: generate_stxx1<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x9c: generate_stxx2<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x9d: generate_stxx2<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0x9e: generate_stxx2<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0x9f: generate_stxx2<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xa0: generate_shri<N_LO, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xa1: generate_shri<N_HI, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xa2: generate_shri<N_LO, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xa3: generate_shri<N_HI, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xa4: generate_sari<N_LO, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xa5: generate_sari<N_HI, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xa6: generate_sari<N_LO, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xa7: generate_sari<N_HI, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xa8: generate_shli<N_LO, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xa9: generate_shli<N_HI, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xaa: generate_shli<N_LO, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xab: generate_shli<N_HI, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xac: generate_reserved(block, compiler, desc); break;
|
|
||||||
case 0xad: generate_reserved(block, compiler, desc); break;
|
|
||||||
case 0xae: generate_reserved(block, compiler, desc); break;
|
|
||||||
case 0xaf: generate_reserved(block, compiler, desc); break;
|
|
||||||
case 0xb0: generate_mulsu<GLOBAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb1: generate_mulsu<GLOBAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb2: generate_mulsu<LOCAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb3: generate_mulsu<LOCAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb4: generate_mulsu<GLOBAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb5: generate_mulsu<GLOBAL, LOCAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb6: generate_mulsu<LOCAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb7: generate_mulsu<LOCAL, LOCAL, IS_SIGNED>(block, compiler, desc); break;
|
|
||||||
case 0xb8: generate_set<N_LO, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xb9: generate_set<N_HI, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xba: generate_set<N_LO, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xbb: generate_set<N_HI, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xbc: generate_mul<GLOBAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xbd: generate_mul<GLOBAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xbe: generate_mul<LOCAL, GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xbf: generate_mul<LOCAL, LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xc0: generate_software(block, compiler, desc); break; // fadd
|
|
||||||
case 0xc1: generate_software(block, compiler, desc); break; // faddd
|
|
||||||
case 0xc2: generate_software(block, compiler, desc); break; // fsub
|
|
||||||
case 0xc3: generate_software(block, compiler, desc); break; // fsubd
|
|
||||||
case 0xc4: generate_software(block, compiler, desc); break; // fmul
|
|
||||||
case 0xc5: generate_software(block, compiler, desc); break; // fmuld
|
|
||||||
case 0xc6: generate_software(block, compiler, desc); break; // fdiv
|
|
||||||
case 0xc7: generate_software(block, compiler, desc); break; // fdivd
|
|
||||||
case 0xc8: generate_software(block, compiler, desc); break; // fcmp
|
|
||||||
case 0xc9: generate_software(block, compiler, desc); break; // fcmpd
|
|
||||||
case 0xca: generate_software(block, compiler, desc); break; // fcmpu
|
|
||||||
case 0xcb: generate_software(block, compiler, desc); break; // fcmpud
|
|
||||||
case 0xcc: generate_software(block, compiler, desc); break; // fcvt
|
|
||||||
case 0xcd: generate_software(block, compiler, desc); break; // fcvtd
|
|
||||||
case 0xce: generate_extend(block, compiler, desc); break;
|
|
||||||
case 0xcf: generate_do(block, compiler, desc); break;
|
|
||||||
case 0xd0: generate_ldwr<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xd1: generate_ldwr<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xd2: generate_lddr<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xd3: generate_lddr<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xd4: generate_ldwp<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xd5: generate_ldwp<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xd6: generate_lddp<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xd7: generate_lddp<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xd8: generate_stwr<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xd9: generate_stwr<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xda: generate_stdr<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xdb: generate_stdr<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xdc: generate_stwp<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xdd: generate_stwp<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xde: generate_stdp<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xdf: generate_stdp<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xe0: generate_db<COND_V, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xe1: generate_db<COND_V, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xe2: generate_db<COND_Z, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xe3: generate_db<COND_Z, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xe4: generate_db<COND_C, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xe5: generate_db<COND_C, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xe6: generate_db<COND_CZ, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xe7: generate_db<COND_CZ, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xe8: generate_db<COND_N, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xe9: generate_db<COND_N, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xea: generate_db<COND_NZ, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xeb: generate_db<COND_NZ, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xec: generate_dbr(block, compiler, desc); break;
|
|
||||||
case 0xed: generate_frame(block, compiler, desc); break;
|
|
||||||
case 0xee: generate_call<GLOBAL>(block, compiler, desc); break;
|
|
||||||
case 0xef: generate_call<LOCAL>(block, compiler, desc); break;
|
|
||||||
case 0xf0: generate_b<COND_V, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xf1: generate_b<COND_V, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xf2: generate_b<COND_Z, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xf3: generate_b<COND_Z, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xf4: generate_b<COND_C, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xf5: generate_b<COND_C, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xf6: generate_b<COND_CZ, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xf7: generate_b<COND_CZ, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xf8: generate_b<COND_N, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xf9: generate_b<COND_N, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xfa: generate_b<COND_NZ, IS_SET>(block, compiler, desc); break;
|
|
||||||
case 0xfb: generate_b<COND_NZ, IS_CLEAR>(block, compiler, desc); break;
|
|
||||||
case 0xfc: generate_br(block, compiler, desc); break;
|
|
||||||
case 0xfd: generate_trap_op(block, compiler, desc); break;
|
|
||||||
case 0xfe: generate_trap_op(block, compiler, desc); break;
|
|
||||||
case 0xff: generate_trap_op(block, compiler, desc); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
UML_AND(block, DRC_SR, DRC_SR, ~ILC_MASK);
|
|
||||||
UML_OR(block, DRC_SR, DRC_SR, mem(&m_instruction_length));
|
|
||||||
|
|
||||||
int done;
|
|
||||||
UML_AND(block, I0, DRC_SR, (T_MASK | P_MASK));
|
|
||||||
UML_CMP(block, I0, (T_MASK | P_MASK));
|
|
||||||
UML_JMPc(block, uml::COND_NE, done = compiler->m_labelnum++);
|
|
||||||
UML_TEST(block, mem(&m_delay_slot), 1);
|
|
||||||
UML_EXHc(block, uml::COND_E, *m_exception[EXCEPTION_TRACE], 0);
|
|
||||||
|
|
||||||
UML_LABEL(block, done);
|
|
||||||
UML_XOR(block, DRC_SR, DRC_SR, I7);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,34 +0,0 @@
|
|||||||
// license:BSD-3-Clause
|
|
||||||
// copyright-holders:Ryan Holtz
|
|
||||||
#ifndef MAME_CPU_E132XS_E132XSFE_H
|
|
||||||
#define MAME_CPU_E132XS_E132XSFE_H
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "e132xs.h"
|
|
||||||
#include "cpu/drcfe.h"
|
|
||||||
|
|
||||||
class e132xs_frontend : public drc_frontend
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
e132xs_frontend(hyperstone_device *e132xs, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
|
|
||||||
void flush();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// required overrides
|
|
||||||
virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline uint32_t imm_length(opcode_desc &desc, uint16_t op);
|
|
||||||
inline uint16_t read_word(opcode_desc &desc);
|
|
||||||
inline uint16_t read_imm1(opcode_desc &desc);
|
|
||||||
inline uint16_t read_imm2(opcode_desc &desc);
|
|
||||||
inline uint32_t read_ldstxx_imm(opcode_desc &desc);
|
|
||||||
inline uint32_t read_limm(opcode_desc &desc, uint16_t op);
|
|
||||||
inline int32_t decode_pcrel(opcode_desc &desc, uint16_t op);
|
|
||||||
inline int32_t decode_call(opcode_desc &desc);
|
|
||||||
|
|
||||||
hyperstone_device *m_cpu;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* MAME_CPU_E132XS_E132XSFE_H */
|
|
Loading…
Reference in New Issue
Block a user