summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/sh4
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2011-01-16 00:35:56 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2011-01-16 00:35:56 +0000
commitb85af379a8d81f07b207a1f7eb2bb3b0e2f0108a (patch)
treee30d4958c66965590dae23bef1db112dec441431 /src/emu/cpu/sh4
parent74bbf1d033d67b5aedd8f1bf8b9caf1ea4fdba59 (diff)
SH4: cleanup and better common/interpreter separation [R. Belmont]
Diffstat (limited to 'src/emu/cpu/sh4')
-rw-r--r--src/emu/cpu/sh4/sh4.c69
-rw-r--r--src/emu/cpu/sh4/sh4.h14
-rw-r--r--src/emu/cpu/sh4/sh4comn.c64
-rw-r--r--src/emu/cpu/sh4/sh4comn.h113
-rw-r--r--src/emu/cpu/sh4/sh4dasm.c2
5 files changed, 189 insertions, 73 deletions
diff --git a/src/emu/cpu/sh4/sh4.c b/src/emu/cpu/sh4/sh4.c
index f4a9d2f04c7..d97187e2a39 100644
--- a/src/emu/cpu/sh4/sh4.c
+++ b/src/emu/cpu/sh4/sh4.c
@@ -28,14 +28,9 @@
#include "sh4regs.h"
#include "sh4comn.h"
-CPU_DISASSEMBLE( sh4 );
+#ifndef USE_SH4DRC
-INLINE sh4_state *get_safe_token(device_t *device)
-{
- assert(device != NULL);
- assert(device->type() == SH4);
- return (sh4_state *)downcast<legacy_cpu_device *>(device)->token();
-}
+CPU_DISASSEMBLE( sh4 );
/* Called for unimplemented opcodes */
static void TODO(sh4_state *sh4)
@@ -2079,27 +2074,6 @@ INLINE void LDCSPC(sh4_state *sh4, UINT32 m)
sh4->spc = sh4->r[m];
}
-static UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address)
-{
- if (!sh4->sh4_mmu_enabled)
- return address;
- else
- {
- int i;
- UINT32 topaddr = address&0xfff00000;
-
- for (i=0;i<64;i++)
- {
- UINT32 topcmp = sh4->sh4_tlb_address[i]&0xfff00000;
- if (topcmp==topaddr)
- return (address&0x000fffff) | ((sh4->sh4_tlb_data[i])&0xfff00000);
- }
-
- }
-
- return address;
-}
-
/* PREF @Rn */
INLINE void PREFM(sh4_state *sh4, UINT32 n)
{
@@ -3622,43 +3596,6 @@ static ADDRESS_MAP_START( sh4_internal_map, ADDRESS_SPACE_PROGRAM, 64 )
ADDRESS_MAP_END
#endif
-
-static READ64_HANDLER( sh4_tlb_r )
-{
- sh4_state *sh4 = get_safe_token(space->cpu);
-
- int offs = offset*8;
-
- if (offs >= 0x01000000)
- {
- UINT8 i = (offs>>8)&63;
- return sh4->sh4_tlb_data[i];
- }
- else
- {
- UINT8 i = (offs>>8)&63;
- return sh4->sh4_tlb_address[i];
- }
-}
-
-static WRITE64_HANDLER( sh4_tlb_w )
-{
- sh4_state *sh4 = get_safe_token(space->cpu);
-
- int offs = offset*8;
-
- if (offs >= 0x01000000)
- {
- UINT8 i = (offs>>8)&63;
- sh4->sh4_tlb_data[i] = data&0xffffffff;
- }
- else
- {
- UINT8 i = (offs>>8)&63;
- sh4->sh4_tlb_address[i] = data&0xffffffff;
- }
-}
-
/*When OC index mode is on (CCR.OIX = 1)*/
static ADDRESS_MAP_START( sh4_internal_map, ADDRESS_SPACE_PROGRAM, 64 )
AM_RANGE(0x1C000000, 0x1C000FFF) AM_RAM AM_MIRROR(0x01FFF000)
@@ -3884,3 +3821,5 @@ CPU_GET_INFO( sh4 )
}
DEFINE_LEGACY_CPU_DEVICE(SH4, sh4);
+
+#endif // USE_SH4DRC
diff --git a/src/emu/cpu/sh4/sh4.h b/src/emu/cpu/sh4/sh4.h
index 203965b11cb..87853626900 100644
--- a/src/emu/cpu/sh4/sh4.h
+++ b/src/emu/cpu/sh4/sh4.h
@@ -100,5 +100,19 @@ void sh4_set_irln_input(device_t *device, int value);
void sh4_set_ftcsr_callback(device_t *device, sh4_ftcsr_callback callback);
void sh4_dma_ddt(device_t *device, struct sh4_ddt_dma *s);
+/***************************************************************************
+ COMPILER-SPECIFIC OPTIONS
+***************************************************************************/
+
+#define SH4DRC_STRICT_VERIFY 0x0001 /* verify all instructions */
+#define SH4DRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */
+#define SH4DRC_STRICT_PCREL 0x0004 /* do actual loads on MOVLI/MOVWI instead of collapsing to immediates */
+
+#define SH4DRC_COMPATIBLE_OPTIONS (SH4DRC_STRICT_VERIFY | SH4DRC_FLUSH_PC | SH4DRC_STRICT_PCREL)
+#define SH4DRC_FASTEST_OPTIONS (0)
+
+void sh4drc_set_options(device_t *device, UINT32 options);
+void sh4drc_add_pcflush(device_t *device, offs_t address);
+
#endif /* __SH4_H__ */
diff --git a/src/emu/cpu/sh4/sh4comn.c b/src/emu/cpu/sh4/sh4comn.c
index 438378c5a68..0180bfca84c 100644
--- a/src/emu/cpu/sh4/sh4comn.c
+++ b/src/emu/cpu/sh4/sh4comn.c
@@ -30,13 +30,6 @@ static const UINT16 tcnt[] = { TCNT0, TCNT1, TCNT2 };
static const UINT16 tcor[] = { TCOR0, TCOR1, TCOR2 };
static const UINT16 tcr[] = { TCR0, TCR1, TCR2 };
-INLINE sh4_state *get_safe_token(device_t *device)
-{
- assert(device != NULL);
- assert(device->type() == SH4);
- return (sh4_state *)downcast<legacy_cpu_device *>(device)->token();
-}
-
void sh4_change_register_bank(sh4_state *sh4, int to)
{
int s;
@@ -1314,3 +1307,60 @@ void sh4_dma_ddt(device_t *device, struct sh4_ddt_dma *s)
}
}
+UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address)
+{
+ if (!sh4->sh4_mmu_enabled)
+ return address;
+ else
+ {
+ int i;
+ UINT32 topaddr = address&0xfff00000;
+
+ for (i=0;i<64;i++)
+ {
+ UINT32 topcmp = sh4->sh4_tlb_address[i]&0xfff00000;
+ if (topcmp==topaddr)
+ return (address&0x000fffff) | ((sh4->sh4_tlb_data[i])&0xfff00000);
+ }
+
+ }
+
+ return address;
+}
+
+READ64_HANDLER( sh4_tlb_r )
+{
+ sh4_state *sh4 = get_safe_token(space->cpu);
+
+ int offs = offset*8;
+
+ if (offs >= 0x01000000)
+ {
+ UINT8 i = (offs>>8)&63;
+ return sh4->sh4_tlb_data[i];
+ }
+ else
+ {
+ UINT8 i = (offs>>8)&63;
+ return sh4->sh4_tlb_address[i];
+ }
+}
+
+WRITE64_HANDLER( sh4_tlb_w )
+{
+ sh4_state *sh4 = get_safe_token(space->cpu);
+
+ int offs = offset*8;
+
+ if (offs >= 0x01000000)
+ {
+ UINT8 i = (offs>>8)&63;
+ sh4->sh4_tlb_data[i] = data&0xffffffff;
+ }
+ else
+ {
+ UINT8 i = (offs>>8)&63;
+ sh4->sh4_tlb_address[i] = data&0xffffffff;
+ }
+}
+
diff --git a/src/emu/cpu/sh4/sh4comn.h b/src/emu/cpu/sh4/sh4comn.h
index 810fe094cc8..d627316338e 100644
--- a/src/emu/cpu/sh4/sh4comn.h
+++ b/src/emu/cpu/sh4/sh4comn.h
@@ -18,6 +18,17 @@
#define VERBOSE 0
+#ifdef USE_SH4DRC
+#include "cpu/drcfe.h"
+#include "cpu/drcuml.h"
+#include "cpu/drcumlsh.h"
+
+class sh4_frontend;
+#endif
+
+#define CPU_TYPE_SH3 (2)
+#define CPU_TYPE_SH4 (3)
+
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
#define EXPPRI(pl,po,p,n) (((4-(pl)) << 24) | ((15-(po)) << 16) | ((p) << 8) | (255-(n)))
@@ -99,8 +110,88 @@ typedef struct
UINT32 sh4_tlb_data[64];
UINT8 sh4_mmu_enabled;
+#ifdef USE_SH4DRC
+ int icount;
+ int cpu_type;
+
+ int pcfsel; // last pcflush entry set
+ int maxpcfsel; // highest valid pcflush entry
+ UINT32 pcflushes[16]; // pcflush entries
+
+ drc_cache * cache; /* pointer to the DRC code cache */
+ drcuml_state * drcuml; /* DRC UML generator state */
+ sh4_frontend * drcfe; /* pointer to the DRC front-end class */
+ UINT32 drcoptions; /* configurable DRC options */
+
+ /* internal stuff */
+ UINT8 cache_dirty; /* true if we need to flush the cache */
+
+ /* parameters for subroutines */
+ UINT64 numcycles; /* return value from gettotalcycles */
+ UINT32 arg0; /* print_debug argument 1 */
+ UINT32 arg1; /* print_debug argument 2 */
+ UINT32 irq; /* irq we're taking */
+
+ /* register mappings */
+ drcuml_parameter regmap[16]; /* parameter to register mappings for all 16 integer registers */
+
+ drcuml_codehandle * entry; /* entry point */
+ drcuml_codehandle * read8; /* read byte */
+ drcuml_codehandle * write8; /* write byte */
+ drcuml_codehandle * read16; /* read half */
+ drcuml_codehandle * write16; /* write half */
+ drcuml_codehandle * read32; /* read word */
+ drcuml_codehandle * write32; /* write word */
+
+ drcuml_codehandle * interrupt; /* interrupt */
+ drcuml_codehandle * nocode; /* nocode */
+ drcuml_codehandle * out_of_cycles; /* out of cycles exception handler */
+
+ UINT32 prefadr;
+ UINT32 target;
+#endif
} sh4_state;
+#ifdef USE_SH4DRC
+class sh4_frontend : public drc_frontend
+{
+public:
+ sh4_frontend(sh4_state &state, UINT32 window_start, UINT32 window_end, UINT32 max_sequence);
+
+protected:
+ virtual bool describe(opcode_desc &desc, const opcode_desc *prev);
+
+private:
+ bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+ bool describe_group_2(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+ bool describe_group_3(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+ bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+ bool describe_group_6(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+ bool describe_group_8(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+ bool describe_group_12(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+ bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
+
+ sh4_state &m_context;
+};
+
+INLINE sh4_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == SH3 ||
+ device->type() == SH4);
+ return *(sh4_state **)downcast<legacy_cpu_device *>(device)->token();
+}
+#else
+INLINE sh4_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == SH3 ||
+ device->type() == SH4);
+ return (sh4_state *)downcast<legacy_cpu_device *>(device)->token();
+}
+#endif
+
+
enum
{
ICF = 0x00800000,
@@ -135,6 +226,24 @@ enum
#define Rn ((opcode>>8)&15)
#define Rm ((opcode>>4)&15)
+#define REGFLAG_R(n) (1 << (n))
+#define REGFLAG_FR(n) (1 << (n))
+#define REGFLAG_XR(n) (1 << (n))
+
+/* register flags 1 */
+#define REGFLAG_PR (1 << 0)
+#define REGFLAG_MACL (1 << 1)
+#define REGFLAG_MACH (1 << 2)
+#define REGFLAG_GBR (1 << 3)
+#define REGFLAG_VBR (1 << 4)
+#define REGFLAG_SR (1 << 5)
+#define REGFLAG_SGR (1 << 6)
+#define REGFLAG_FPUL (1 << 7)
+#define REGFLAG_FPSCR (1 << 8)
+#define REGFLAG_DBR (1 << 9)
+#define REGFLAG_SSR (1 << 10)
+#define REGFLAG_SPC (1 << 11)
+
void sh4_exception_recompute(sh4_state *sh4); // checks if there is any interrupt with high enough priority
void sh4_exception_request(sh4_state *sh4, int exception); // start requesting an exception
void sh4_exception_unrequest(sh4_state *sh4, int exception); // stop requesting an exception
@@ -150,6 +259,10 @@ void sh4_set_irq_line(sh4_state *sh4, int irqline, int state); // set state of e
void sh4_swap_fp_couples(sh4_state *sh4);
#endif
void sh4_common_init(device_t *device);
+UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address);
+
+READ64_HANDLER( sh4_tlb_r );
+WRITE64_HANDLER( sh4_tlb_w );
INLINE void sh4_check_pending_irq(sh4_state *sh4, const char *message) // look for highest priority active exception and handle it
{
diff --git a/src/emu/cpu/sh4/sh4dasm.c b/src/emu/cpu/sh4/sh4dasm.c
index a71334a51d7..4ec1f8fcd9f 100644
--- a/src/emu/cpu/sh4/sh4dasm.c
+++ b/src/emu/cpu/sh4/sh4dasm.c
@@ -783,7 +783,7 @@ static UINT32 op1111(char *buffer, UINT32 pc, UINT16 opcode)
return 0;
}
-static unsigned DasmSH4(char *buffer, unsigned pc, UINT16 opcode)
+unsigned DasmSH4(char *buffer, unsigned pc, UINT16 opcode)
{
UINT32 flags;