32x drc functional on ARM, random adjustments

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@824 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2009-10-22 20:16:32 +00:00
parent 274f95a9a9
commit 553c3eaa3a
12 changed files with 86 additions and 63 deletions

View file

@ -10,6 +10,7 @@
do { \ do { \
*(u32 *)ptr = x; \ *(u32 *)ptr = x; \
ptr = (void *)((u8 *)ptr + sizeof(u32)); \ ptr = (void *)((u8 *)ptr + sizeof(u32)); \
COUNT_OP; \
} while (0) } while (0)
#define EMIT(x) EMIT_PTR(tcache_ptr, x) #define EMIT(x) EMIT_PTR(tcache_ptr, x)
@ -170,29 +171,26 @@
static void emith_op_imm(int cond, int op, int r, unsigned int imm) static void emith_op_imm(int cond, int op, int r, unsigned int imm)
{ {
u32 v, ror2; int ror2, rn = r;
u32 v;
if (imm == 0 && op != A_OP_MOV) if (op == A_OP_MOV)
rn = 0;
else if (imm == 0)
return; return;
/* shift down to get starting rot2 */ for (v = imm, ror2 = 0; v != 0 || op == A_OP_MOV; v >>= 8, ror2 -= 8/2) {
for (v = imm, ror2 = 0; v && !(v & 3); v >>= 2) /* shift down to get 'best' rot2 */
ror2++; for (; v && !(v & 3); v >>= 2)
ror2 = 16 - ror2; ror2--;
EOP_C_DOP_IMM(cond, op, 0, op == A_OP_MOV ? 0 : r, r, ror2 & 0x0f, v & 0xff); EOP_C_DOP_IMM(cond, op, 0, rn, r, ror2 & 0x0f, v & 0xff);
if (op == A_OP_MOV)
op = A_OP_ORR;
v >>= 8; if (op == A_OP_MOV) {
if (v & 0xff) op = A_OP_ORR;
EOP_C_DOP_IMM(cond, op, 0, r, r, (ror2 - 8/2) & 0x0f, v & 0xff); rn = r;
v >>= 8; }
if (v & 0xff) }
EOP_C_DOP_IMM(cond, op, 0, r, r, (ror2 - 16/2) & 0x0f, v & 0xff);
v >>= 8;
if (v & 0xff)
EOP_C_DOP_IMM(cond, op, 0, r, r, (ror2 - 24/2) & 0x0f, v & 0xff);
} }
#define is_offset_24(val) \ #define is_offset_24(val) \
@ -227,14 +225,6 @@ static int emith_xbranch(int cond, void *target, int is_call)
return (u32 *)tcache_ptr - start_ptr; return (u32 *)tcache_ptr - start_ptr;
} }
static void handle_caches(void)
{
#ifdef ARM
extern void cache_flush_d_inval_i(const void *start_addr, const void *end_addr);
cache_flush_d_inval_i(tcache, tcache_ptr);
#endif
}
#define EMITH_CONDITIONAL(code, is_nonzero) { \ #define EMITH_CONDITIONAL(code, is_nonzero) { \
u32 val, cond, *ptr; \ u32 val, cond, *ptr; \

View file

@ -1,12 +1,5 @@
#include <stdarg.h> #include <stdarg.h>
#if (DRC_DEBUG & 1)
#define COUNT_OP \
host_insn_count++
#else
#define COUNT_OP
#endif
enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI }; enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
#define CONTEXT_REG xBP #define CONTEXT_REG xBP

View file

@ -14,16 +14,22 @@
#define DRC_DEBUG 0 #define DRC_DEBUG 0
#endif #endif
#if DRC_DEBUG
#define dbg(l,...) { \ #define dbg(l,...) { \
if ((l) & DRC_DEBUG) \ if ((l) & DRC_DEBUG) \
elprintf(EL_STATUS, ##__VA_ARGS__); \ elprintf(EL_STATUS, ##__VA_ARGS__); \
} }
#if DRC_DEBUG
#include "mame/sh2dasm.h" #include "mame/sh2dasm.h"
#include <platform/linux/host_dasm.h> #include <platform/linux/host_dasm.h>
static int insns_compiled, hash_collisions, host_insn_count; static int insns_compiled, hash_collisions, host_insn_count;
#define COUNT_OP \
host_insn_count++
#else // !DRC_DEBUG
#define COUNT_OP
#define dbg(...)
#endif #endif
#if (DRC_DEBUG & 2) #if (DRC_DEBUG & 2)
static u8 *tcache_dsm_ptrs[3]; static u8 *tcache_dsm_ptrs[3];
static char sh2dasm_buff[64]; static char sh2dasm_buff[64];
@ -111,12 +117,12 @@ extern void sh2_drc_entry(SH2 *sh2, void *block);
extern void sh2_drc_exit(void); extern void sh2_drc_exit(void);
// tmp // tmp
extern void __attribute__((regparm(2))) sh2_do_op(SH2 *sh2, int opcode); extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
static void __attribute__((regparm(1))) sh2_test_irq(SH2 *sh2); static void REGPARM(1) sh2_test_irq(SH2 *sh2);
static void flush_tcache(int tcid) static void flush_tcache(int tcid)
{ {
printf("tcache #%d flush! (%d/%d, bds %d/%d)\n", tcid, dbg(1, "tcache #%d flush! (%d/%d, bds %d/%d)", tcid,
tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid], tcache_ptrs[tcid] - tcache_bases[tcid], tcache_sizes[tcid],
block_counts[tcid], block_max_counts[tcid]); block_counts[tcid], block_max_counts[tcid]);
@ -469,6 +475,10 @@ end_block:
emith_jump(sh2_drc_exit); emith_jump(sh2_drc_exit);
tcache_ptrs[tcache_id] = tcache_ptr; tcache_ptrs[tcache_id] = tcache_ptr;
#ifdef ARM
cache_flush_d_inval_i(block_entry, tcache_ptr);
#endif
do_host_disasm(tcache_id); do_host_disasm(tcache_id);
dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f", dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
tcache_id, block_counts[tcache_id], tcache_id, block_counts[tcache_id],
@ -476,6 +486,10 @@ end_block:
insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled); insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
dbg(1, " hash collisions %d/%d", hash_collisions, block_counts[tcache_id]); dbg(1, " hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
#if (DRC_DEBUG & 2)
fflush(stdout);
#endif
return block_entry; return block_entry;
/* /*
unimplemented: unimplemented:
@ -592,7 +606,7 @@ void sh2_execute(SH2 *sh2, int cycles)
sh2->cycles_done += cycles - ((signed int)sh2->sr >> 12); sh2->cycles_done += cycles - ((signed int)sh2->sr >> 12);
} }
static void __attribute__((regparm(1))) sh2_test_irq(SH2 *sh2) static void REGPARM(1) sh2_test_irq(SH2 *sh2)
{ {
if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f)) if (sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
{ {
@ -634,9 +648,23 @@ static void block_stats(void)
(double)maxb->refcount / total * 100.0); (double)maxb->refcount / total * 100.0);
maxb->refcount = 0; maxb->refcount = 0;
} }
for (b = 0; b < ARRAY_SIZE(block_tables); b++)
for (i = 0; i < block_counts[b]; i++)
block_tables[b][i].refcount = 0;
} }
#else
#define block_stats()
#endif #endif
void sh2_drc_flush_all(void)
{
block_stats();
flush_tcache(0);
flush_tcache(1);
flush_tcache(2);
}
int sh2_drc_init(SH2 *sh2) int sh2_drc_init(SH2 *sh2)
{ {
if (block_tables[0] == NULL) { if (block_tables[0] == NULL) {
@ -657,6 +685,9 @@ int sh2_drc_init(SH2 *sh2)
tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1]; tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
} }
// tmp
PicoOpt |= POPT_DIS_VDP_FIFO;
#if (DRC_DEBUG & 2) #if (DRC_DEBUG & 2)
for (i = 0; i < ARRAY_SIZE(block_tables); i++) for (i = 0; i < ARRAY_SIZE(block_tables); i++)
tcache_dsm_ptrs[i] = tcache_bases[i]; tcache_dsm_ptrs[i] = tcache_bases[i];
@ -678,9 +709,7 @@ int sh2_drc_init(SH2 *sh2)
void sh2_drc_finish(SH2 *sh2) void sh2_drc_finish(SH2 *sh2)
{ {
if (block_tables[0] != NULL) { if (block_tables[0] != NULL) {
#if (DRC_DEBUG & 1)
block_stats(); block_stats();
#endif
free(block_tables[0]); free(block_tables[0]);
memset(block_tables, 0, sizeof(block_tables)); memset(block_tables, 0, sizeof(block_tables));

View file

@ -104,8 +104,14 @@ void sh2_execute(SH2 *sh2_, int cycles)
#else // DRC_TMP #else // DRC_TMP
#ifdef __i386__
#define REGPARM(x) __attribute__((regparm(x)))
#else
#define REGPARM(x)
#endif
// tmp // tmp
void __attribute__((regparm(2))) sh2_do_op(SH2 *sh2_, int opcode) void REGPARM(2) sh2_do_op(SH2 *sh2_, int opcode)
{ {
sh2 = sh2_; sh2 = sh2_;
sh2->pc += 2; sh2->pc += 2;

View file

@ -735,7 +735,7 @@ static void PicoWrite8_32x_on(u32 a, u32 d)
static void PicoWrite16_32x_on(u32 a, u32 d) static void PicoWrite16_32x_on(u32 a, u32 d)
{ {
if ((a & 0xfc00) == 0x5000) if ((a & 0xfc00) == 0x5000)
elprintf(EL_UIO, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); elprintf(EL_32X, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
if ((a & 0xffc0) == 0x5100) { // a15100 if ((a & 0xffc0) == 0x5100) { // a15100
p32x_reg_write16(a, d); p32x_reg_write16(a, d);

View file

@ -35,6 +35,7 @@ void ssp_drc_next_patch(void){}
void ssp_drc_end(void){} void ssp_drc_end(void){}
#endif #endif
#define COUNT_OP
#include "../../../cpu/drc/emit_arm.c" #include "../../../cpu/drc/emit_arm.c"
// ----------------------------------------------------- // -----------------------------------------------------
@ -1787,7 +1788,9 @@ void *ssp_translate_block(int pc)
exit(0); exit(0);
#endif #endif
handle_caches(); #ifdef ARM
cache_flush_d_inval_i(tcache, tcache_ptr);
#endif
return block_start; return block_start;
} }

View file

@ -957,7 +957,7 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
if (xcycles >= timer_b_next_oflow) \ if (xcycles >= timer_b_next_oflow) \
ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 2 ym2612.OPN.ST.status |= (ym2612.OPN.ST.mode >> 2) & 2
static u32 MEMH_FUNC ym2612_read_local_z80(void) static u32 ym2612_read_local_z80(void)
{ {
int xcycles = z80_cyclesDone() << 8; int xcycles = z80_cyclesDone() << 8;
@ -1055,14 +1055,14 @@ void ym2612_unpack_state(void)
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// z80 memhandlers // z80 memhandlers
static unsigned char MEMH_FUNC z80_md_vdp_read(unsigned short a) static unsigned char z80_md_vdp_read(unsigned short a)
{ {
// TODO? // TODO?
elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, 0xff); elprintf(EL_ANOMALY, "z80 invalid r8 [%06x] %02x", a, 0xff);
return 0xff; return 0xff;
} }
static unsigned char MEMH_FUNC z80_md_bank_read(unsigned short a) static unsigned char z80_md_bank_read(unsigned short a)
{ {
unsigned int addr68k; unsigned int addr68k;
unsigned char ret; unsigned char ret;
@ -1076,13 +1076,13 @@ static unsigned char MEMH_FUNC z80_md_bank_read(unsigned short a)
return ret; return ret;
} }
static void MEMH_FUNC z80_md_ym2612_write(unsigned int a, unsigned char data) static void z80_md_ym2612_write(unsigned int a, unsigned char data)
{ {
if (PicoOpt & POPT_EN_FM) if (PicoOpt & POPT_EN_FM)
emustatus |= ym2612_write_local(a, data, 1) & 1; emustatus |= ym2612_write_local(a, data, 1) & 1;
} }
static void MEMH_FUNC z80_md_vdp_br_write(unsigned int a, unsigned char data) static void z80_md_vdp_br_write(unsigned int a, unsigned char data)
{ {
// TODO: allow full VDP access // TODO: allow full VDP access
if ((a&0xfff9) == 0x7f11) // 7f11 7f13 7f15 7f17 if ((a&0xfff9) == 0x7f11) // 7f11 7f13 7f15 7f17
@ -1103,7 +1103,7 @@ static void MEMH_FUNC z80_md_vdp_br_write(unsigned int a, unsigned char data)
elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data); elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
} }
static void MEMH_FUNC z80_md_bank_write(unsigned int a, unsigned char data) static void z80_md_bank_write(unsigned int a, unsigned char data)
{ {
unsigned int addr68k; unsigned int addr68k;

View file

@ -789,10 +789,10 @@ extern void lprintf(const char *fmt, ...);
#define cdprintf(x...) #define cdprintf(x...)
#endif #endif
#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 #ifdef __i386__
#define MEMH_FUNC __attribute__((aligned(4))) #define REGPARM(x) __attribute__((regparm(x)))
#else #else
#define MEMH_FUNC #define REGPARM(x)
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__

View file

@ -169,7 +169,7 @@ static void write_bank(unsigned short a, unsigned char d)
} }
} }
static void MEMH_FUNC xwrite(unsigned int a, unsigned char d) static void xwrite(unsigned int a, unsigned char d)
{ {
elprintf(EL_IO, "z80 write [%04x] %02x", a, d); elprintf(EL_IO, "z80 write [%04x] %02x", a, d);
if (a >= 0xc000) if (a >= 0xc000)

View file

@ -15,14 +15,15 @@ amalgamate = 0
use_sh2drc = 1 use_sh2drc = 1
drc_debug = 1 drc_debug = 1
-include Makefile.local
ifeq "$(debug_cyclone)" "1" ifeq "$(debug_cyclone)" "1"
use_cyclone = 1 use_cyclone = 1
use_musashi = 1 use_musashi = 1
endif endif
ifeq "$(use_musashi)" "1" ifeq "$(use_musashi)" "1"
# due to CPU stop flag acces
asm_cdpico = 0 asm_cdpico = 0
asm_memory = 0
asm_cdmemory = 0 asm_cdmemory = 0
else else
use_cyclone = 1 use_cyclone = 1
@ -119,8 +120,8 @@ DEFINES += DRC_SH2 DRC_TMP
OBJS += cpu/sh2/mame/sh2pico.o OBJS += cpu/sh2/mame/sh2pico.o
OBJS += cpu/sh2/compiler.o OBJS += cpu/sh2/compiler.o
OBJS += cpu/sh2/stub_arm.o OBJS += cpu/sh2/stub_arm.o
ifeq "$(drc_debug)" "1" ifdef drc_debug
DEFINES += DRC_DEBUG=1 DEFINES += DRC_DEBUG=$(drc_debug)
OBJS += cpu/sh2/mame/sh2dasm.o OBJS += cpu/sh2/mame/sh2dasm.o
OBJS += platform/linux/host_dasm.o OBJS += platform/linux/host_dasm.o
LDFLAGS += -lbfd -lopcodes -liberty LDFLAGS += -lbfd -lopcodes -liberty

View file

@ -22,13 +22,13 @@ CFLAGS += -ggdb -Wall -falign-functions=2
endif endif
DEFINES = _UNZIP_SUPPORT IO_STATS IN_EVDEV DEFINES = _UNZIP_SUPPORT IO_STATS IN_EVDEV
CFLAGS += -I../.. -I. CFLAGS += -I../.. -I.
LDFLAGS += -lpthread LDFLAGS += -lm -lpng
ifeq "$(ARCH)" "arm" ifeq "$(ARCH)" "arm"
CFLAGS += -mcpu=arm920t CFLAGS += -mcpu=arm920t
DEFINES += ARM DEFINES += ARM
else
LDFLAGS += -lX11
endif endif
LDFLAGS += -lpthread
LDFLAGS += -lX11
CC = $(CROSS)gcc CC = $(CROSS)gcc
@ -95,8 +95,8 @@ DEFINES += DRC_SH2 DRC_TMP
OBJS += cpu/sh2/mame/sh2pico.o OBJS += cpu/sh2/mame/sh2pico.o
OBJS += cpu/sh2/compiler.o OBJS += cpu/sh2/compiler.o
OBJS += cpu/sh2/stub_$(ARCH).o OBJS += cpu/sh2/stub_$(ARCH).o
ifeq "$(drc_debug)" "1" ifdef drc_debug
DEFINES += DRC_DEBUG=1 DEFINES += DRC_DEBUG=$(drc_debug)
OBJS += cpu/sh2/mame/sh2dasm.o OBJS += cpu/sh2/mame/sh2dasm.o
OBJS += host_dasm.o OBJS += host_dasm.o
LDFLAGS += -lbfd -lopcodes -liberty LDFLAGS += -lbfd -lopcodes -liberty
@ -132,7 +132,7 @@ tidy:
PicoDrive : $(OBJS) PicoDrive : $(OBJS)
@echo ">>>" $@ @echo ">>>" $@
$(CC) $(CFLAGS) $^ $(LDFLAGS) -lm -lpng -Wl,-Map=PicoDrive.map -o $@ $(CC) $(CFLAGS) $^ $(LDFLAGS) -Wl,-Map=PicoDrive.map -o $@
mkdirs: mkdirs:
@mkdir -p $(DIRS) @mkdir -p $(DIRS)

View file

@ -37,7 +37,7 @@ remove_useless_symbols (asymbol **symbols, long count)
{ {
asymbol *sym = *in_ptr++; asymbol *sym = *in_ptr++;
if (sym->name == NULL || sym->name[0] == '\0') if (sym->name == NULL || sym->name[0] == '\0' || sym->name[0] == '$')
continue; continue;
if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
continue; continue;
@ -53,6 +53,7 @@ remove_useless_symbols (asymbol **symbols, long count)
*/ */
*out_ptr++ = sym; *out_ptr++ = sym;
} }
return out_ptr - symbols; return out_ptr - symbols;
} }