diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/cpu/drcbex64.c | 2 | ||||
-rw-r--r-- | src/emu/cpu/drcbex86.c | 2 | ||||
-rw-r--r-- | src/emu/cpu/drcuml.c | 115 | ||||
-rw-r--r-- | src/emu/cpu/drcuml.h | 10 | ||||
-rw-r--r-- | src/emu/cpu/powerpc/ppcdrc.c | 32 |
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) } |