diff options
author | 2011-01-16 00:35:56 +0000 | |
---|---|---|
committer | 2011-01-16 00:35:56 +0000 | |
commit | b85af379a8d81f07b207a1f7eb2bb3b0e2f0108a (patch) | |
tree | e30d4958c66965590dae23bef1db112dec441431 /src/emu/cpu/sh4 | |
parent | 74bbf1d033d67b5aedd8f1bf8b9caf1ea4fdba59 (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.c | 69 | ||||
-rw-r--r-- | src/emu/cpu/sh4/sh4.h | 14 | ||||
-rw-r--r-- | src/emu/cpu/sh4/sh4comn.c | 64 | ||||
-rw-r--r-- | src/emu/cpu/sh4/sh4comn.h | 113 | ||||
-rw-r--r-- | src/emu/cpu/sh4/sh4dasm.c | 2 |
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; |