summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/drcbex64.c2
-rw-r--r--src/emu/cpu/drcbex86.c2
-rw-r--r--src/emu/cpu/drcuml.c115
-rw-r--r--src/emu/cpu/drcuml.h10
-rw-r--r--src/emu/cpu/powerpc/ppcdrc.c32
5 files changed, 139 insertions, 22 deletions
diff --git a/src/emu/cpu/drcbex64.c b/src/emu/cpu/drcbex64.c
index 5584d6a775d..45ada02e69d 100644
--- a/src/emu/cpu/drcbex64.c
+++ b/src/emu/cpu/drcbex64.c
@@ -914,7 +914,7 @@ static void drcbex64_generate(drcbe_state *drcbe, drcuml_block *block, const drc
if (drcbe->log != NULL)
{
char dasm[256];
- drcuml_disasm(inst, dasm, drcbe->cache);
+ drcuml_disasm(inst, dasm, drcbe->drcuml);
x86log_add_comment(drcbe->log, dst, "%s", dasm);
}
diff --git a/src/emu/cpu/drcbex86.c b/src/emu/cpu/drcbex86.c
index 5ac228cc0ef..78b34eb146f 100644
--- a/src/emu/cpu/drcbex86.c
+++ b/src/emu/cpu/drcbex86.c
@@ -721,7 +721,7 @@ static void drcbex86_generate(drcbe_state *drcbe, drcuml_block *block, const drc
if (drcbe->log != NULL)
{
char dasm[256];
- drcuml_disasm(inst, dasm, drcbe->cache);
+ drcuml_disasm(inst, dasm, drcbe->drcuml);
x86log_add_comment(drcbe->log, dst, "%s", dasm);
}
diff --git a/src/emu/cpu/drcuml.c b/src/emu/cpu/drcuml.c
index 0282833d1f5..c00cc1eb515 100644
--- a/src/emu/cpu/drcuml.c
+++ b/src/emu/cpu/drcuml.c
@@ -119,6 +119,17 @@
TYPE DEFINITIONS
***************************************************************************/
+/* structure describing a UML symbol */
+typedef struct _drcuml_symbol drcuml_symbol;
+struct _drcuml_symbol
+{
+ drcuml_symbol * next; /* link to the next symbol */
+ drccodeptr base; /* base of the symbol */
+ UINT32 length; /* length of the symbol */
+ char symname[1]; /* name of the symbol */
+};
+
+
/* structure describing UML generation state */
struct _drcuml_state
{
@@ -128,6 +139,8 @@ struct _drcuml_state
drcbe_state * bestate; /* pointer to the back-end state */
drcuml_codehandle * handlelist; /* head of linked list of handles */
FILE * umllog; /* handle to the UML logfile */
+ drcuml_symbol * symlist; /* head of linked list of symbols */
+ drcuml_symbol ** symtailptr; /* pointer to tail of linked list of symbols */
};
@@ -158,12 +171,12 @@ struct _drcuml_codehandle
typedef struct _bevalidate_test bevalidate_test;
struct _bevalidate_test
{
- drcuml_opcode opcode;
- UINT8 size;
- UINT8 destmask;
- UINT8 iflags;
- UINT8 flags;
- UINT64 param[4];
+ drcuml_opcode opcode;
+ UINT8 size;
+ UINT8 destmask;
+ UINT8 iflags;
+ UINT8 flags;
+ UINT64 param[4];
};
@@ -517,6 +530,7 @@ drcuml_state *drcuml_alloc(drccache *cache, UINT32 flags, int modes, int addrbit
/* initialize the state */
drcuml->cache = cache;
drcuml->beintf = (flags & DRCUML_OPTION_USE_C) ? &drcbe_c_be_interface : &NATIVE_DRC;
+ drcuml->symtailptr = &drcuml->symlist;
/* if we're to log, create the logfile */
if (flags & DRCUML_OPTION_LOG_UML)
@@ -610,6 +624,14 @@ void drcuml_free(drcuml_state *drcuml)
free(block->inst);
free(block);
}
+
+ /* free all the symbols */
+ while (drcuml->symlist != NULL)
+ {
+ drcuml_symbol *sym = drcuml->symlist;
+ drcuml->symlist = sym->next;
+ free(sym);
+ }
/* close any files */
if (drcuml->umllog != NULL)
@@ -981,6 +1003,62 @@ const char *drcuml_handle_name(const drcuml_codehandle *handle)
***************************************************************************/
/*-------------------------------------------------
+ drcuml_symbol_add - add a symbol to the
+ internal symbol table
+-------------------------------------------------*/
+
+void drcuml_symbol_add(drcuml_state *drcuml, void *base, UINT32 length, const char *name)
+{
+ drcuml_symbol *symbol;
+
+ /* allocate memory to hold the symbol */
+ symbol = malloc(sizeof(*symbol) + strlen(name));
+ if (symbol == NULL)
+ fatalerror("Out of memory allocating symbol in drcuml_symbol_add");
+
+ /* fill in the structure */
+ symbol->next = NULL;
+ symbol->base = (drccodeptr)base;
+ symbol->length = length;
+ strcpy(symbol->symname, name);
+
+ /* add to the tail of the list */
+ *drcuml->symtailptr = symbol;
+ drcuml->symtailptr = &symbol->next;
+}
+
+
+/*-------------------------------------------------
+ drcuml_symbol_find - look up a symbol from the
+ internal symbol table or return NULL if not
+ found
+-------------------------------------------------*/
+
+const char *drcuml_symbol_find(drcuml_state *drcuml, void *base, UINT32 *offset)
+{
+ drccodeptr search = base;
+ drcuml_symbol *symbol;
+
+ /* simple linear search */
+ for (symbol = drcuml->symlist; symbol != NULL; symbol = symbol->next)
+ if (search >= symbol->base && search < symbol->base + symbol->length)
+ {
+ /* if no offset pointer, only match perfectly */
+ if (offset == NULL && search != symbol->base)
+ continue;
+
+ /* return the offset and name */
+ if (offset != NULL)
+ *offset = search - symbol->base;
+ return symbol->symname;
+ }
+
+ /* not found; return NULL */
+ return NULL;
+}
+
+
+/*-------------------------------------------------
drcuml_log_printf - directly printf to the UML
log if generated
-------------------------------------------------*/
@@ -1034,7 +1112,7 @@ void drcuml_add_comment(drcuml_block *block, const char *format, ...)
instruction to the given buffer
-------------------------------------------------*/
-void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drccache *cache)
+void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drcuml_state *drcuml)
{
static const char *conditions[] = { "z", "nz", "s", "ns", "c", "nc", "v", "nv", "u", "nu", "a", "be", "g", "le", "l", "ge" };
static const char *pound_size[] = { "?", "?", "?", "?", "s", "?", "?", "?", "d" };
@@ -1066,6 +1144,8 @@ void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drccache *cache
{
const drcuml_parameter *param = &inst->param[pnum];
UINT16 typemask = opinfo->param[pnum].typemask;
+ const char *symbol;
+ UINT32 symoffset;
/* start with a comma for all except the first parameter */
if (pnum != 0)
@@ -1145,9 +1225,18 @@ void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drccache *cache
else if (typemask == PTYPES_STR)
dest += sprintf(dest, "%s", (const char *)(FPTR)param->value);
+ /* symbol */
+ else if (drcuml != NULL && (symbol = drcuml_symbol_find(drcuml, (drccodeptr)(FPTR)param->value, &symoffset)) != NULL)
+ {
+ if (symoffset == 0)
+ dest += sprintf(dest, "[%s]", symbol);
+ else
+ dest += sprintf(dest, "[%s+$%X]", symbol, symoffset);
+ }
+
/* cache memory */
- else if (cache != NULL && drccache_contains_pointer(cache, (void *)(FPTR)param->value))
- dest += sprintf(dest, "[+$%X]", (drccodeptr)(FPTR)param->value - drccache_near(cache));
+ else if (drcuml != NULL && drccache_contains_pointer(drcuml->cache, (void *)(FPTR)param->value))
+ dest += sprintf(dest, "[+$%X]", (drccodeptr)(FPTR)param->value - drccache_near(drcuml->cache));
/* general memory */
else
@@ -1580,8 +1669,8 @@ static void simplify_instruction_with_no_flags(drcuml_block *block, drcuml_instr
if (memcmp(&orig, inst, sizeof(orig)) != 0)
{
char disasm1[256], disasm2[256];
- drcuml_disasm(&orig, disasm1, block->drcuml->cache);
- drcuml_disasm(inst, disasm2, block->drcuml->cache);
+ drcuml_disasm(&orig, disasm1, block->drcuml);
+ drcuml_disasm(inst, disasm2, block->drcuml);
mame_printf_debug("Simplified: %-50.50s -> %s\n", disasm1, disasm2);
}
#endif
@@ -1635,7 +1724,7 @@ static void disassemble_block(drcuml_block *block)
else
{
char dasm[256];
- drcuml_disasm(&block->inst[instnum], dasm, block->drcuml->cache);
+ drcuml_disasm(&block->inst[instnum], dasm, block->drcuml);
/* include the first accumulated comment with this line */
if (firstcomment != -1)
@@ -2212,7 +2301,7 @@ static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_st
char disasm[256];
/* disassemble the test instruction */
- drcuml_disasm(testinst, disasm, drcuml->cache);
+ drcuml_disasm(testinst, disasm, drcuml);
/* output a description of what went wrong */
printf("\n");
diff --git a/src/emu/cpu/drcuml.h b/src/emu/cpu/drcuml.h
index 0d82141303e..76a7f4e2149 100644
--- a/src/emu/cpu/drcuml.h
+++ b/src/emu/cpu/drcuml.h
@@ -491,13 +491,19 @@ const char *drcuml_handle_name(const drcuml_codehandle *handle);
/* ----- code logging ----- */
/* directly printf to the UML log if generated */
-void drcuml_log_printf(drcuml_state *state, const char *format, ...) ATTR_PRINTF(2,3);
+void drcuml_log_printf(drcuml_state *drcuml, const char *format, ...) ATTR_PRINTF(2,3);
+
+/* add a symbol to the internal symbol table */
+void drcuml_symbol_add(drcuml_state *drcuml, void *base, UINT32 length, const char *name);
+
+/* look up a symbol from the internal symbol table or return NULL if not found */
+const char *drcuml_symbol_find(drcuml_state *drcuml, void *base, UINT32 *offset);
/* attach a comment to the current output location in the specified block */
void drcuml_add_comment(drcuml_block *block, const char *format, ...) ATTR_PRINTF(2,3);
/* disassemble a UML instruction to the given buffer */
-void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drccache *cache);
+void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drcuml_state *state);
#endif
diff --git a/src/emu/cpu/powerpc/ppcdrc.c b/src/emu/cpu/powerpc/ppcdrc.c
index af0f3c5f76a..7f554d9c477 100644
--- a/src/emu/cpu/powerpc/ppcdrc.c
+++ b/src/emu/cpu/powerpc/ppcdrc.c
@@ -586,6 +586,30 @@ static void ppcdrc_init(powerpc_flavor flavor, UINT8 cap, int tb_divisor, int cl
ppc->impstate->drcuml = drcuml_alloc(cache, flags, 8, 32, 2);
if (ppc->impstate->drcuml == NULL)
fatalerror("Error initializing the UML");
+
+ /* add symbols for our stuff */
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->pc, sizeof(ppc->pc), "pc");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->icount, sizeof(ppc->icount), "icount");
+ for (regnum = 0; regnum < 32; regnum++)
+ {
+ char buf[10];
+ sprintf(buf, "r%d", regnum);
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->r[regnum], sizeof(ppc->r[regnum]), buf);
+ sprintf(buf, "fpr%d", regnum);
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->f[regnum], sizeof(ppc->r[regnum]), buf);
+ }
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->cr, sizeof(ppc->cr), "cr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->fpscr, sizeof(ppc->fpscr), "fpscr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->msr, sizeof(ppc->msr), "msr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->sr, sizeof(ppc->sr), "sr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr[SPR_XER], sizeof(ppc->spr[SPR_XER]), "xer");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr[SPR_LR], sizeof(ppc->spr[SPR_LR]), "lr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr[SPR_CTR], sizeof(ppc->spr[SPR_CTR]), "ctr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr, sizeof(ppc->spr), "spr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->dcr, sizeof(ppc->dcr), "dcr");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->param0, sizeof(ppc->param0), "param0");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->param1, sizeof(ppc->param1), "param1");
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->irq_pending, sizeof(ppc->irq_pending), "irq_pending");
/* initialize the front-end helper */
if (SINGLE_INSTRUCTION_MODE)
@@ -2080,8 +2104,8 @@ static void generate_compute_flags(drcuml_block *block, int updatecr, UINT32 xer
/* tricky case: both */
UML_GETFLGS(block, IREG(0), DRCUML_FLAG_S | DRCUML_FLAG_Z | xerflags); // getflgs i0,sz|xerflags
- if (invertcarry)
- UML_XOR(block, IREG(2), IREG(2), IMM(DRCUML_FLAG_C)); // xor i2,i2,FLAG_C
+ if (invertcarry && (xermask & XER_CA))
+ UML_XOR(block, IREG(0), IREG(0), IMM(DRCUML_FLAG_C)); // xor i0,i0,FLAG_C
UML_LOAD(block, IREG(0), ppc->impstate->sz_cr_table, IREG(0), DWORD); // load i0,sz_cr_table,i0,dword
UML_AND(block, IREG(1), SPR32(SPR_XER), IMM(~xermask)); // and i1,[xer],~xermask
UML_SHL(block, IREG(2), IREG(0), IMM(4)); // shl i2,i0,4
@@ -2091,9 +2115,7 @@ static void generate_compute_flags(drcuml_block *block, int updatecr, UINT32 xer
UML_MOV(block, SPR32(SPR_XER), IREG(1)); // mov [xer],i1
UML_SHR(block, IREG(1), IREG(1), IMM(3)); // shr i1,i1,3
UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
- UML_AND(block, IREG(1), CR32, IMM(~CRMASK(0))); // and i1,[cr],~crmask(0)
- UML_AND(block, IREG(0), IREG(0), IMM(CRMASK(0))); // and i0,i0,crmask(0)
- UML_OR(block, CR32, IREG(0), IREG(1)); // or cr32,i0,i1
+ UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(0))); // rolins [cr],i0,0,crmask(0)
}