Search
lxdream.org :: lxdream/src/test/testsh4x86.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/test/testsh4x86.c
changeset 1263:b3de98d19faf
prev1189:1540105786c8
next1302:765e514f99a6
author nkeynes
date Tue Mar 06 09:04:34 2012 +1000 (7 years ago)
permissions -rw-r--r--
last change Break host disassembly bits out of sh4x86.in, and move the generic disasm
bits from x86dasm to xlat.
file annotate diff log raw
nkeynes@363
     1
/**
nkeynes@586
     2
 * $Id$
nkeynes@363
     3
 *
nkeynes@363
     4
 * Test cases for the SH4 => x86 translator core. Takes as
nkeynes@363
     5
 * input a binary SH4 object (and VMA), generates the
nkeynes@363
     6
 * corresponding x86 code, and outputs the disassembly.
nkeynes@363
     7
 *
nkeynes@363
     8
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@363
     9
 *
nkeynes@363
    10
 * This program is free software; you can redistribute it and/or modify
nkeynes@363
    11
 * it under the terms of the GNU General Public License as published by
nkeynes@363
    12
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@363
    13
 * (at your option) any later version.
nkeynes@363
    14
 *
nkeynes@363
    15
 * This program is distributed in the hope that it will be useful,
nkeynes@363
    16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@363
    17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@363
    18
 * GNU General Public License for more details.
nkeynes@363
    19
 */
nkeynes@363
    20
nkeynes@363
    21
#include <stdio.h>
nkeynes@363
    22
#include <stdarg.h>
nkeynes@363
    23
#include <getopt.h>
nkeynes@365
    24
#include <sys/stat.h>
nkeynes@990
    25
#include <string.h>
nkeynes@990
    26
nkeynes@1263
    27
#include "xlat/xlatdasm.h"
nkeynes@363
    28
#include "sh4/sh4trans.h"
nkeynes@363
    29
#include "sh4/sh4core.h"
nkeynes@586
    30
#include "sh4/sh4mmio.h"
nkeynes@963
    31
#include "sh4/mmu.h"
nkeynes@586
    32
nkeynes@820
    33
struct dreamcast_module sh4_module;
nkeynes@586
    34
struct mmio_region mmio_region_MMU;
nkeynes@820
    35
struct mmio_region mmio_region_PMM;
nkeynes@586
    36
struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];
nkeynes@586
    37
int sh4_breakpoint_count = 0;
nkeynes@1263
    38
gboolean sh4_profile_blocks = FALSE;
nkeynes@363
    39
nkeynes@363
    40
#define MAX_INS_SIZE 32
nkeynes@363
    41
nkeynes@930
    42
nkeynes@930
    43
struct mem_region_fn **sh4_address_space = (void *)0x12345432;
nkeynes@945
    44
struct mem_region_fn **sh4_user_address_space = (void *)0x12345678;
nkeynes@363
    45
char *option_list = "s:o:d:h";
nkeynes@363
    46
struct option longopts[1] = { { NULL, 0, 0, 0 } };
nkeynes@363
    47
nkeynes@363
    48
char *input_file = NULL;
nkeynes@363
    49
char *diff_file = NULL;
nkeynes@363
    50
char *output_file = NULL;
nkeynes@602
    51
gboolean sh4_starting;
nkeynes@363
    52
uint32_t start_addr = 0x8C010000;
nkeynes@365
    53
uint32_t sh4_cpu_period = 5;
nkeynes@934
    54
unsigned char dc_main_ram[4096];
nkeynes@934
    55
unsigned char dc_boot_rom[4096];
nkeynes@363
    56
FILE *in;
nkeynes@363
    57
nkeynes@363
    58
char *inbuf;
nkeynes@365
    59
nkeynes@1263
    60
struct xlat_symbol local_symbols[] = {
nkeynes@919
    61
    { "sh4r+128", ((char *)&sh4r)+128 },
nkeynes@919
    62
    { "sh4_cpu_period", &sh4_cpu_period },
nkeynes@945
    63
    { "sh4_address_space", (void *)0x12345432 },
nkeynes@945
    64
    { "sh4_user_address_space", (void *)0x12345678 },
nkeynes@919
    65
    { "sh4_write_fpscr", sh4_write_fpscr },
nkeynes@919
    66
    { "sh4_write_sr", sh4_write_sr },
nkeynes@919
    67
    { "sh4_read_sr", sh4_read_sr },
nkeynes@919
    68
    { "sh4_sleep", sh4_sleep },
nkeynes@919
    69
    { "sh4_fsca", sh4_fsca },
nkeynes@919
    70
    { "sh4_ftrv", sh4_ftrv },
nkeynes@919
    71
    { "sh4_switch_fr_banks", sh4_switch_fr_banks },
nkeynes@919
    72
    { "sh4_execute_instruction", sh4_execute_instruction },
nkeynes@919
    73
    { "signsat48", signsat48 },
nkeynes@919
    74
    { "xlat_get_code_by_vma", xlat_get_code_by_vma },
nkeynes@919
    75
    { "xlat_get_code", xlat_get_code }
nkeynes@365
    76
};
nkeynes@363
    77
nkeynes@363
    78
// Stubs
nkeynes@802
    79
gboolean sh4_execute_instruction( ) { return TRUE; }
nkeynes@363
    80
void sh4_accept_interrupt() {}
nkeynes@586
    81
void sh4_set_breakpoint( uint32_t pc, breakpoint_type_t type ) { }
nkeynes@802
    82
gboolean sh4_clear_breakpoint( uint32_t pc, breakpoint_type_t type ) { return TRUE; }
nkeynes@775
    83
gboolean dreamcast_is_running() { return FALSE; }
nkeynes@802
    84
int sh4_get_breakpoint( uint32_t pc ) { return 0; }
nkeynes@948
    85
void sh4_finalize_instruction() { }
nkeynes@740
    86
void sh4_core_exit( int exit_code ){}
nkeynes@1091
    87
void sh4_crashdump() {}
nkeynes@363
    88
void event_execute() {}
nkeynes@363
    89
void TMU_run_slice( uint32_t nanos ) {}
nkeynes@968
    90
void CCN_set_cache_control( int val ) { }
nkeynes@884
    91
void PMM_write_control( int ctr, uint32_t val ) { }
nkeynes@363
    92
void SCIF_run_slice( uint32_t nanos ) {}
nkeynes@905
    93
void FASTCALL sh4_write_fpscr( uint32_t val ) { }
nkeynes@905
    94
void FASTCALL sh4_write_sr( uint32_t val ) { }
nkeynes@905
    95
uint32_t FASTCALL sh4_read_sr( void ) { return 0; }
nkeynes@905
    96
void FASTCALL sh4_sleep() { }
nkeynes@905
    97
void FASTCALL sh4_fsca( uint32_t angle, float *fr ) { }
nkeynes@905
    98
void FASTCALL sh4_ftrv( float *fv ) { }
nkeynes@905
    99
void FASTCALL signsat48(void) { }
nkeynes@669
   100
void sh4_switch_fr_banks() { }
nkeynes@918
   101
void mem_copy_to_sh4( sh4addr_t addr, sh4ptr_t src, size_t size ) { }
nkeynes@602
   102
gboolean sh4_has_page( sh4vma_t vma ) { return TRUE; }
nkeynes@385
   103
void syscall_invoke( uint32_t val ) { }
nkeynes@586
   104
void dreamcast_stop() {} 
nkeynes@586
   105
void dreamcast_reset() {}
nkeynes@951
   106
void FASTCALL sh4_raise_reset( int exc ) { }
nkeynes@951
   107
void FASTCALL sh4_raise_exception( int exc ) { }
nkeynes@951
   108
void FASTCALL sh4_raise_tlb_exception( int exc, sh4vma_t vma ) { }
nkeynes@951
   109
void FASTCALL sh4_raise_tlb_multihit( sh4vma_t vma) { }
nkeynes@951
   110
void FASTCALL sh4_raise_trap( int exc ) { }
nkeynes@939
   111
void FASTCALL sh4_flush_store_queue( sh4addr_t addr ) { }
nkeynes@939
   112
void FASTCALL sh4_flush_store_queue_mmu( sh4addr_t addr, void *exc ) { }
nkeynes@1189
   113
void sh4_handle_pending_events() { }
nkeynes@802
   114
uint32_t sh4_sleep_run_slice(uint32_t nanosecs) { return nanosecs; }
nkeynes@802
   115
gboolean gui_error_dialog( const char *fmt, ... ) { return TRUE; }
nkeynes@939
   116
gboolean FASTCALL mmu_update_icache( sh4vma_t addr ) { return TRUE; }
nkeynes@939
   117
void MMU_ldtlb() { }
nkeynes@1112
   118
void event_schedule(int event, uint32_t nanos) { }
nkeynes@586
   119
struct sh4_icache_struct sh4_icache;
nkeynes@930
   120
struct mem_region_fn mem_region_unmapped;
nkeynes@1091
   121
const struct cpu_desc_struct sh4_cpu_desc;
nkeynes@1091
   122
sh4addr_t FASTCALL mmu_vma_to_phys_disasm( sh4vma_t vma ) { return vma; }
nkeynes@363
   123
nkeynes@363
   124
void usage()
nkeynes@363
   125
{
nkeynes@363
   126
    fprintf( stderr, "Usage: testsh4x86 [options] <input bin file>\n");
nkeynes@363
   127
    fprintf( stderr, "Options:\n");
nkeynes@363
   128
    fprintf( stderr, "  -d <filename>  Diff results against contents of file\n" );
nkeynes@363
   129
    fprintf( stderr, "  -h             Display this help message\n" );
nkeynes@363
   130
    fprintf( stderr, "  -o <filename>  Output disassembly to file [stdout]\n" );
nkeynes@363
   131
    fprintf( stderr, "  -s <addr>      Specify start address of binary [8C010000]\n" );
nkeynes@363
   132
}
nkeynes@363
   133
nkeynes@363
   134
void emit( void *ptr, int level, const gchar *source, const char *msg, ... )
nkeynes@363
   135
{
nkeynes@363
   136
    va_list ap;
nkeynes@363
   137
    va_start( ap, msg );
nkeynes@363
   138
    vfprintf( stderr, msg, ap );
nkeynes@363
   139
    fprintf( stderr, "\n" );
nkeynes@363
   140
    va_end(ap);
nkeynes@363
   141
}
nkeynes@363
   142
nkeynes@363
   143
nkeynes@363
   144
struct sh4_registers sh4r;
nkeynes@363
   145
nkeynes@363
   146
nkeynes@363
   147
int main( int argc, char *argv[] )
nkeynes@363
   148
{
nkeynes@363
   149
    struct stat st;
nkeynes@363
   150
    int opt;
nkeynes@363
   151
    while( (opt = getopt_long( argc, argv, option_list, longopts, NULL )) != -1 ) {
nkeynes@363
   152
	switch( opt ) {
nkeynes@363
   153
	case 'd':
nkeynes@363
   154
	    diff_file = optarg;
nkeynes@363
   155
	    break;
nkeynes@363
   156
	case 'o':
nkeynes@363
   157
	    output_file = optarg;
nkeynes@363
   158
	    break;
nkeynes@363
   159
	case 's':
nkeynes@363
   160
	    start_addr = strtoul(optarg, NULL, 0);
nkeynes@363
   161
	    break;
nkeynes@363
   162
	case 'h':
nkeynes@363
   163
	    usage();
nkeynes@363
   164
	    exit(0);
nkeynes@363
   165
	}
nkeynes@363
   166
    }
nkeynes@363
   167
    if( optind < argc ) {
nkeynes@363
   168
	input_file = argv[optind++];
nkeynes@363
   169
    } else {
nkeynes@363
   170
	usage();
nkeynes@363
   171
	exit(1);
nkeynes@363
   172
    }
nkeynes@363
   173
nkeynes@919
   174
    mmio_region_MMU.mem = malloc(4096);
nkeynes@919
   175
    memset( mmio_region_MMU.mem, 0, 4096 );
nkeynes@919
   176
nkeynes@929
   177
    ((uint32_t *)mmio_region_MMU.mem)[4] = 1;
nkeynes@929
   178
nkeynes@363
   179
    in = fopen( input_file, "ro" );
nkeynes@363
   180
    if( in == NULL ) {
nkeynes@363
   181
	perror( "Unable to open input file" );
nkeynes@363
   182
	exit(2);
nkeynes@363
   183
    }
nkeynes@363
   184
    fstat( fileno(in), &st );
nkeynes@363
   185
    inbuf = malloc( st.st_size );
nkeynes@363
   186
    fread( inbuf, st.st_size, 1, in );
nkeynes@919
   187
    sh4_icache.mask = 0xFFFFF000;
nkeynes@919
   188
    sh4_icache.page_vma = start_addr & 0xFFFFF000;
nkeynes@919
   189
    sh4_icache.page = (unsigned char *)(inbuf - (sh4_icache.page_vma&0xFFF));
nkeynes@919
   190
    sh4_icache.page_ppa = start_addr & 0xFFFFF000;
nkeynes@363
   191
nkeynes@365
   192
    xlat_cache_init();
nkeynes@925
   193
    uintptr_t pc;
nkeynes@365
   194
    uint8_t *buf = sh4_translate_basic_block( start_addr );
nkeynes@919
   195
    uint32_t buflen = xlat_get_code_size(buf);
nkeynes@1263
   196
    xlat_disasm_init( local_symbols, sizeof(local_symbols)/sizeof(struct xlat_symbol) );
nkeynes@968
   197
    for( pc = (uintptr_t)buf; pc < ((uintptr_t)buf) + buflen;  ) {
nkeynes@363
   198
	char buf[256];
nkeynes@363
   199
	char op[256];
nkeynes@1263
   200
	uintptr_t pc2 = xlat_disasm_instruction( pc, buf, sizeof(buf), op );
nkeynes@990
   201
	fprintf( stdout, "%p: %s\n", (void *)pc, buf );
nkeynes@363
   202
	pc = pc2;
nkeynes@363
   203
    }
nkeynes@802
   204
    return 0;
nkeynes@363
   205
}
.