Search
lxdream.org :: lxdream/src/sh4/sh4dasm.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4dasm.in
changeset 1300:d18488c8668b
prev1190:2e66e9053037
author nkeynes
date Fri May 29 18:47:05 2015 +1000 (6 years ago)
permissions -rw-r--r--
last change Fix test case
file annotate diff log raw
1.1 --- a/src/sh4/sh4dasm.in Fri Dec 02 18:14:27 2011 +1000
1.2 +++ b/src/sh4/sh4dasm.in Fri May 29 18:47:05 2015 +1000
1.3 @@ -21,6 +21,8 @@
1.4 #include "sh4/mmu.h"
1.5 #include "mem.h"
1.6
1.7 +#include <string.h>
1.8 +
1.9 #define UNIMP(ir) snprintf( buf, len, "??? " )
1.10
1.11 uint32_t sh4_disasm_instruction( sh4vma_t pc, char *buf, int len, char *opcode )
1.12 @@ -275,6 +277,74 @@
1.13 }
1.14
1.15
1.16 +static struct sh4_symbol *sh4_symbol_table = NULL;
1.17 +static unsigned sh4_symbol_table_size = 0;
1.18 +static sh4_symtab_destroy_cb sh4_symbol_table_cb = NULL;
1.19 +
1.20 +
1.21 +static void swap_symbol( struct sh4_symbol *a, struct sh4_symbol *b ) {
1.22 + struct sh4_symbol tmp;
1.23 + if( a == b )
1.24 + return;
1.25 + memcpy( &tmp, a, sizeof( struct sh4_symbol ) );
1.26 + memcpy( a, b, sizeof( struct sh4_symbol ) );
1.27 + memcpy( b, &tmp, sizeof( struct sh4_symbol ) );
1.28 +}
1.29 +
1.30 +static unsigned sort_symtab( struct sh4_symbol *table, unsigned numSymtabEntries ) {
1.31 + /* Implement via simple selection sort for now; usually we don't have very
1.32 + * large symbol tables.
1.33 + */
1.34 + for( unsigned i = 0; i < numSymtabEntries; i++ ) {
1.35 + struct sh4_symbol *next_entry = &table[i];
1.36 + for( unsigned j = i + 1; j < numSymtabEntries; ) {
1.37 + if( table[j].address < next_entry->address ) {
1.38 + next_entry = &table[j];
1.39 + j++;
1.40 + } else if( table[j].address == next_entry->address ) {
1.41 + /* Duplicate - kill it */
1.42 + swap_symbol( &table[j], &table[--numSymtabEntries] );
1.43 + } else {
1.44 + j++;
1.45 + }
1.46 + }
1.47 + swap_symbol( &table[i], next_entry );
1.48 + }
1.49 + return numSymtabEntries;
1.50 +}
1.51 +
1.52 +const char *sh4_disasm_get_symbol( sh4addr_t addr )
1.53 +{
1.54 + int l = 0, h = sh4_symbol_table_size;
1.55 + while( l != h ) {
1.56 + int i = l + (h-l)/2;
1.57 + int iaddr = sh4_symbol_table[i].address;
1.58 + if( iaddr == addr ) {
1.59 + return sh4_symbol_table[i].name;
1.60 + } else if( iaddr > addr ) {
1.61 + h = i;
1.62 + } else { /* iaddr < addr */
1.63 + l = i+1;
1.64 + }
1.65 + }
1.66 + return NULL;
1.67 +}
1.68 +
1.69 +void sh4_set_symbol_table( struct sh4_symbol *table, unsigned size, sh4_symtab_destroy_cb callback )
1.70 +{
1.71 + if( sh4_symbol_table_cb != NULL ) {
1.72 + sh4_symbol_table_cb(sh4_symbol_table, sh4_symbol_table_size);
1.73 + }
1.74 + sh4_symbol_table = table;
1.75 + sh4_symbol_table_cb = callback;
1.76 + if( table == NULL ) {
1.77 + sh4_symbol_table_size = 0;
1.78 + } else {
1.79 + sh4_symbol_table_size = sort_symtab(table, size);
1.80 + }
1.81 +}
1.82 +
1.83 +
1.84 void sh4_disasm_region( FILE *f, int from, int to )
1.85 {
1.86 int pc;
1.87 @@ -285,6 +355,10 @@
1.88 buf[0] = '\0';
1.89 sh4_disasm_instruction( pc,
1.90 buf, sizeof(buf), opcode );
1.91 + const char *sym = sh4_disasm_get_symbol( pc );
1.92 + if( sym != 0 ) {
1.93 + fprintf( f, "%s:\n", sym );
1.94 + }
1.95 fprintf( f, " %08x: %s %s\n", pc, opcode, buf );
1.96 }
1.97 }
.