mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
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:
parent
274f95a9a9
commit
553c3eaa3a
12 changed files with 86 additions and 63 deletions
|
@ -10,6 +10,7 @@
|
|||
do { \
|
||||
*(u32 *)ptr = x; \
|
||||
ptr = (void *)((u8 *)ptr + sizeof(u32)); \
|
||||
COUNT_OP; \
|
||||
} while (0)
|
||||
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
|
||||
/* shift down to get starting rot2 */
|
||||
for (v = imm, ror2 = 0; v && !(v & 3); v >>= 2)
|
||||
ror2++;
|
||||
ror2 = 16 - ror2;
|
||||
for (v = imm, ror2 = 0; v != 0 || op == A_OP_MOV; v >>= 8, ror2 -= 8/2) {
|
||||
/* shift down to get 'best' rot2 */
|
||||
for (; v && !(v & 3); v >>= 2)
|
||||
ror2--;
|
||||
|
||||
EOP_C_DOP_IMM(cond, op, 0, op == A_OP_MOV ? 0 : r, r, ror2 & 0x0f, v & 0xff);
|
||||
if (op == A_OP_MOV)
|
||||
op = A_OP_ORR;
|
||||
EOP_C_DOP_IMM(cond, op, 0, rn, r, ror2 & 0x0f, v & 0xff);
|
||||
|
||||
v >>= 8;
|
||||
if (v & 0xff)
|
||||
EOP_C_DOP_IMM(cond, op, 0, r, r, (ror2 - 8/2) & 0x0f, v & 0xff);
|
||||
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);
|
||||
if (op == A_OP_MOV) {
|
||||
op = A_OP_ORR;
|
||||
rn = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
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) { \
|
||||
u32 val, cond, *ptr; \
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
#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 };
|
||||
|
||||
#define CONTEXT_REG xBP
|
||||
|
|
|
@ -14,16 +14,22 @@
|
|||
#define DRC_DEBUG 0
|
||||
#endif
|
||||
|
||||
#if DRC_DEBUG
|
||||
#define dbg(l,...) { \
|
||||
if ((l) & DRC_DEBUG) \
|
||||
elprintf(EL_STATUS, ##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#if DRC_DEBUG
|
||||
#include "mame/sh2dasm.h"
|
||||
#include <platform/linux/host_dasm.h>
|
||||
static int insns_compiled, hash_collisions, host_insn_count;
|
||||
#define COUNT_OP \
|
||||
host_insn_count++
|
||||
#else // !DRC_DEBUG
|
||||
#define COUNT_OP
|
||||
#define dbg(...)
|
||||
#endif
|
||||
|
||||
#if (DRC_DEBUG & 2)
|
||||
static u8 *tcache_dsm_ptrs[3];
|
||||
static char sh2dasm_buff[64];
|
||||
|
@ -111,12 +117,12 @@ extern void sh2_drc_entry(SH2 *sh2, void *block);
|
|||
extern void sh2_drc_exit(void);
|
||||
|
||||
// tmp
|
||||
extern void __attribute__((regparm(2))) sh2_do_op(SH2 *sh2, int opcode);
|
||||
static void __attribute__((regparm(1))) sh2_test_irq(SH2 *sh2);
|
||||
extern void REGPARM(2) sh2_do_op(SH2 *sh2, int opcode);
|
||||
static void REGPARM(1) sh2_test_irq(SH2 *sh2);
|
||||
|
||||
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],
|
||||
block_counts[tcid], block_max_counts[tcid]);
|
||||
|
||||
|
@ -469,6 +475,10 @@ end_block:
|
|||
emith_jump(sh2_drc_exit);
|
||||
tcache_ptrs[tcache_id] = tcache_ptr;
|
||||
|
||||
#ifdef ARM
|
||||
cache_flush_d_inval_i(block_entry, tcache_ptr);
|
||||
#endif
|
||||
|
||||
do_host_disasm(tcache_id);
|
||||
dbg(1, " block #%d,%d tcache %d/%d, insns %d -> %d %.3f",
|
||||
tcache_id, block_counts[tcache_id],
|
||||
|
@ -476,6 +486,10 @@ end_block:
|
|||
insns_compiled, host_insn_count, (double)host_insn_count / insns_compiled);
|
||||
if ((sh2->pc & 0xc6000000) == 0x02000000) // ROM
|
||||
dbg(1, " hash collisions %d/%d", hash_collisions, block_counts[tcache_id]);
|
||||
#if (DRC_DEBUG & 2)
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
return block_entry;
|
||||
/*
|
||||
unimplemented:
|
||||
|
@ -592,7 +606,7 @@ void sh2_execute(SH2 *sh2, int cycles)
|
|||
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))
|
||||
{
|
||||
|
@ -634,9 +648,23 @@ static void block_stats(void)
|
|||
(double)maxb->refcount / total * 100.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
|
||||
|
||||
void sh2_drc_flush_all(void)
|
||||
{
|
||||
block_stats();
|
||||
flush_tcache(0);
|
||||
flush_tcache(1);
|
||||
flush_tcache(2);
|
||||
}
|
||||
|
||||
int sh2_drc_init(SH2 *sh2)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
// tmp
|
||||
PicoOpt |= POPT_DIS_VDP_FIFO;
|
||||
|
||||
#if (DRC_DEBUG & 2)
|
||||
for (i = 0; i < ARRAY_SIZE(block_tables); i++)
|
||||
tcache_dsm_ptrs[i] = tcache_bases[i];
|
||||
|
@ -678,9 +709,7 @@ int sh2_drc_init(SH2 *sh2)
|
|||
void sh2_drc_finish(SH2 *sh2)
|
||||
{
|
||||
if (block_tables[0] != NULL) {
|
||||
#if (DRC_DEBUG & 1)
|
||||
block_stats();
|
||||
#endif
|
||||
free(block_tables[0]);
|
||||
memset(block_tables, 0, sizeof(block_tables));
|
||||
|
||||
|
|
|
@ -104,8 +104,14 @@ void sh2_execute(SH2 *sh2_, int cycles)
|
|||
|
||||
#else // DRC_TMP
|
||||
|
||||
#ifdef __i386__
|
||||
#define REGPARM(x) __attribute__((regparm(x)))
|
||||
#else
|
||||
#define REGPARM(x)
|
||||
#endif
|
||||
|
||||
// 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->pc += 2;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue