Search
lxdream.org :: lxdream/src/sh4/sh4x86.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 1091:186558374345
prev1067:d3c00ffccfcd
next1092:7c4ffe27e7b5
author nkeynes
date Tue Dec 15 08:46:37 2009 +1000 (11 years ago)
permissions -rw-r--r--
last change Add side-by-side x86+sh4 disassembly output
Print SH4 state information and disassembly of the current block when
crashing.
Fix delay slot instruction in conditional branch not being marked as a
delay-slot instruction in the branch-not-taken path.
Rename REG_* defines in cpu.h to avoid conflict with translation defs
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.in Sun Jul 05 13:54:48 2009 +1000
1.2 +++ b/src/sh4/sh4x86.in Tue Dec 15 08:46:37 2009 +1000
1.3 @@ -27,12 +27,14 @@
1.4
1.5 #include "lxdream.h"
1.6 #include "sh4/sh4core.h"
1.7 +#include "sh4/sh4dasm.h"
1.8 #include "sh4/sh4trans.h"
1.9 #include "sh4/sh4stat.h"
1.10 #include "sh4/sh4mmio.h"
1.11 #include "sh4/mmu.h"
1.12 #include "xlat/xltcache.h"
1.13 #include "xlat/x86/x86op.h"
1.14 +#include "x86dasm/x86dasm.h"
1.15 #include "clock.h"
1.16
1.17 #define DEFAULT_BACKPATCH_SIZE 4096
1.18 @@ -107,6 +109,25 @@
1.19 static uint32_t save_fcw; /* save value for fpu control word */
1.20 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
1.21
1.22 +static struct x86_symbol x86_symbol_table[] = {
1.23 + { "sh4r+128", ((char *)&sh4r)+128 },
1.24 + { "sh4_cpu_period", &sh4_cpu_period },
1.25 + { "sh4_address_space", NULL },
1.26 + { "sh4_user_address_space", NULL },
1.27 + { "sh4_write_fpscr", sh4_write_fpscr },
1.28 + { "sh4_write_sr", sh4_write_sr },
1.29 + { "sh4_read_sr", sh4_read_sr },
1.30 + { "sh4_sleep", sh4_sleep },
1.31 + { "sh4_fsca", sh4_fsca },
1.32 + { "sh4_ftrv", sh4_ftrv },
1.33 + { "sh4_switch_fr_banks", sh4_switch_fr_banks },
1.34 + { "sh4_execute_instruction", sh4_execute_instruction },
1.35 + { "signsat48", signsat48 },
1.36 + { "xlat_get_code_by_vma", xlat_get_code_by_vma },
1.37 + { "xlat_get_code", xlat_get_code }
1.38 +};
1.39 +
1.40 +
1.41 gboolean is_sse3_supported()
1.42 {
1.43 uint32_t features;
1.44 @@ -122,8 +143,57 @@
1.45 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
1.46 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
1.47 sh4_x86.sse3_enabled = is_sse3_supported();
1.48 + x86_symbol_table[2].ptr = sh4_address_space;
1.49 + x86_symbol_table[3].ptr = sh4_user_address_space;
1.50 + x86_disasm_init();
1.51 + x86_set_symtab( x86_symbol_table, sizeof(x86_symbol_table)/sizeof(struct x86_symbol) );
1.52 }
1.53
1.54 +/**
1.55 + * Disassemble the given translated code block, and it's source SH4 code block
1.56 + * side-by-side. The current native pc will be marked if non-null.
1.57 + */
1.58 +void sh4_translate_disasm_block( FILE *out, void *code, sh4addr_t source_start, void *native_pc )
1.59 +{
1.60 + char buf[256];
1.61 + char op[256];
1.62 +
1.63 + uintptr_t target_start = (uintptr_t)code, target_pc;
1.64 + uintptr_t target_end = target_start + xlat_get_code_size(code);
1.65 + uint32_t source_pc = source_start;
1.66 + uint32_t source_end = source_pc;
1.67 + xlat_recovery_record_t source_recov_table = XLAT_RECOVERY_TABLE(code);
1.68 + xlat_recovery_record_t source_recov_end = source_recov_table + XLAT_BLOCK_FOR_CODE(code)->recover_table_size;
1.69 +
1.70 + for( target_pc = target_start; target_pc < target_end; ) {
1.71 + uintptr_t pc2 = x86_disasm_instruction( target_pc, buf, sizeof(buf), op );
1.72 + fprintf( out, "%c%08X: %-20s %-40s", (target_pc == (uintptr_t)native_pc ? '*' : ' '),
1.73 + (unsigned int)target_pc, op, buf );
1.74 +
1.75 + if( source_recov_table < source_recov_end &&
1.76 + target_pc >= (target_start + source_recov_table->xlat_offset) ) {
1.77 + source_recov_table++;
1.78 + if( source_end < (source_start + (source_recov_table->sh4_icount)*2) )
1.79 + source_end = source_start + (source_recov_table->sh4_icount)*2;
1.80 + }
1.81 +
1.82 + if( source_pc < source_end ) {
1.83 + uint32_t source_pc2 = sh4_disasm_instruction( source_pc, buf, sizeof(buf), op );
1.84 + fprintf( out, " %08X: %s %s\n", source_pc, op, buf );
1.85 + source_pc = source_pc2;
1.86 + } else {
1.87 + fprintf( out, "\n" );
1.88 + }
1.89 +
1.90 + target_pc = pc2;
1.91 + }
1.92 +
1.93 + while( source_pc < source_end ) {
1.94 + uint32_t source_pc2 = sh4_disasm_instruction( source_pc, buf, sizeof(buf), op );
1.95 + fprintf( out, "%*c %08X: %s %s\n", 72,' ', source_pc, op, buf );
1.96 + source_pc = source_pc2;
1.97 + }
1.98 +}
1.99
1.100 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
1.101 {
1.102 @@ -1697,6 +1767,7 @@
1.103 uint32_t *patch = ((uint32_t *)xlat_output)-1;
1.104 int save_tstate = sh4_x86.tstate;
1.105 sh4_translate_instruction(pc+2);
1.106 + sh4_x86.in_delay_slot = DELAY_PC; /* Cleared by sh4_translate_instruction */
1.107 exit_block_rel( target, pc+4 );
1.108
1.109 // not taken
1.110 @@ -1834,6 +1905,7 @@
1.111
1.112 int save_tstate = sh4_x86.tstate;
1.113 sh4_translate_instruction(pc+2);
1.114 + sh4_x86.in_delay_slot = DELAY_PC; /* Cleared by sh4_translate_instruction */
1.115 exit_block_rel( disp + pc + 4, pc+4 );
1.116 // not taken
1.117 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
.