filename | src/test/testsh4x86.c |
changeset | 385:766eca01ef4d |
prev | 374:8f80a795513e |
next | 499:14b86c78d111 |
author | nkeynes |
date | Wed Oct 17 11:26:45 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Split config management out to config.[ch] Manage config filename Check home dir + sysconfdir for conf file Initial work on a path settings dialog |
file | annotate | diff | log | raw |
nkeynes@363 | 1 | /** |
nkeynes@385 | 2 | * $Id: testsh4x86.c,v 1.5 2007-09-16 07:01:35 nkeynes Exp $ |
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@365 | 25 | #include "x86dasm/x86dasm.h" |
nkeynes@363 | 26 | #include "sh4/sh4trans.h" |
nkeynes@363 | 27 | #include "sh4/sh4core.h" |
nkeynes@363 | 28 | |
nkeynes@363 | 29 | #define MAX_INS_SIZE 32 |
nkeynes@363 | 30 | |
nkeynes@363 | 31 | char *option_list = "s:o:d:h"; |
nkeynes@363 | 32 | struct option longopts[1] = { { NULL, 0, 0, 0 } }; |
nkeynes@363 | 33 | |
nkeynes@363 | 34 | char *input_file = NULL; |
nkeynes@363 | 35 | char *diff_file = NULL; |
nkeynes@363 | 36 | char *output_file = NULL; |
nkeynes@363 | 37 | uint32_t start_addr = 0x8C010000; |
nkeynes@365 | 38 | uint32_t sh4_cpu_period = 5; |
nkeynes@363 | 39 | FILE *in; |
nkeynes@363 | 40 | |
nkeynes@363 | 41 | char *inbuf; |
nkeynes@365 | 42 | |
nkeynes@365 | 43 | struct x86_symbol local_symbols[] = { |
nkeynes@365 | 44 | { "_sh4_read_byte", sh4_read_byte }, |
nkeynes@365 | 45 | { "_sh4_read_word", sh4_read_word }, |
nkeynes@365 | 46 | { "_sh4_read_long", sh4_read_long }, |
nkeynes@365 | 47 | { "_sh4_write_byte", sh4_write_byte }, |
nkeynes@365 | 48 | { "_sh4_write_word", sh4_write_word }, |
nkeynes@365 | 49 | { "_sh4_write_long", sh4_write_long } |
nkeynes@365 | 50 | }; |
nkeynes@363 | 51 | |
nkeynes@363 | 52 | int32_t sh4_read_byte( uint32_t addr ) |
nkeynes@363 | 53 | { |
nkeynes@363 | 54 | return *(uint8_t *)(inbuf+(addr-start_addr)); |
nkeynes@363 | 55 | } |
nkeynes@363 | 56 | int32_t sh4_read_word( uint32_t addr ) |
nkeynes@363 | 57 | { |
nkeynes@363 | 58 | return *(uint16_t *)(inbuf+(addr-start_addr)); |
nkeynes@363 | 59 | } |
nkeynes@363 | 60 | int32_t sh4_read_long( uint32_t addr ) |
nkeynes@363 | 61 | { |
nkeynes@363 | 62 | return *(uint32_t *)(inbuf+(addr-start_addr)); |
nkeynes@363 | 63 | } |
nkeynes@363 | 64 | // Stubs |
nkeynes@363 | 65 | gboolean sh4_execute_instruction( ) { } |
nkeynes@363 | 66 | void sh4_accept_interrupt() {} |
nkeynes@363 | 67 | void sh4_set_breakpoint( uint32_t pc, int type ) { } |
nkeynes@363 | 68 | gboolean sh4_clear_breakpoint( uint32_t pc, int type ) { } |
nkeynes@363 | 69 | int sh4_get_breakpoint( uint32_t pc ) { } |
nkeynes@363 | 70 | void event_execute() {} |
nkeynes@363 | 71 | void TMU_run_slice( uint32_t nanos ) {} |
nkeynes@363 | 72 | void SCIF_run_slice( uint32_t nanos ) {} |
nkeynes@363 | 73 | void sh4_write_byte( uint32_t addr, uint32_t val ) {} |
nkeynes@363 | 74 | void sh4_write_word( uint32_t addr, uint32_t val ) {} |
nkeynes@363 | 75 | void sh4_write_long( uint32_t addr, uint32_t val ) {} |
nkeynes@369 | 76 | void sh4_flush_store_queue( uint32_t addr ) {} |
nkeynes@374 | 77 | void sh4_write_sr( uint32_t val ) { } |
nkeynes@385 | 78 | void syscall_invoke( uint32_t val ) { } |
nkeynes@374 | 79 | uint32_t sh4_read_sr( void ) { } |
nkeynes@365 | 80 | gboolean sh4_raise_exception( int exc ) {} |
nkeynes@363 | 81 | |
nkeynes@363 | 82 | void usage() |
nkeynes@363 | 83 | { |
nkeynes@363 | 84 | fprintf( stderr, "Usage: testsh4x86 [options] <input bin file>\n"); |
nkeynes@363 | 85 | fprintf( stderr, "Options:\n"); |
nkeynes@363 | 86 | fprintf( stderr, " -d <filename> Diff results against contents of file\n" ); |
nkeynes@363 | 87 | fprintf( stderr, " -h Display this help message\n" ); |
nkeynes@363 | 88 | fprintf( stderr, " -o <filename> Output disassembly to file [stdout]\n" ); |
nkeynes@363 | 89 | fprintf( stderr, " -s <addr> Specify start address of binary [8C010000]\n" ); |
nkeynes@363 | 90 | } |
nkeynes@363 | 91 | |
nkeynes@363 | 92 | void emit( void *ptr, int level, const gchar *source, const char *msg, ... ) |
nkeynes@363 | 93 | { |
nkeynes@363 | 94 | va_list ap; |
nkeynes@363 | 95 | va_start( ap, msg ); |
nkeynes@363 | 96 | vfprintf( stderr, msg, ap ); |
nkeynes@363 | 97 | fprintf( stderr, "\n" ); |
nkeynes@363 | 98 | va_end(ap); |
nkeynes@363 | 99 | } |
nkeynes@363 | 100 | |
nkeynes@363 | 101 | |
nkeynes@363 | 102 | struct sh4_registers sh4r; |
nkeynes@363 | 103 | |
nkeynes@363 | 104 | |
nkeynes@363 | 105 | int main( int argc, char *argv[] ) |
nkeynes@363 | 106 | { |
nkeynes@363 | 107 | struct stat st; |
nkeynes@363 | 108 | int opt; |
nkeynes@363 | 109 | while( (opt = getopt_long( argc, argv, option_list, longopts, NULL )) != -1 ) { |
nkeynes@363 | 110 | switch( opt ) { |
nkeynes@363 | 111 | case 'd': |
nkeynes@363 | 112 | diff_file = optarg; |
nkeynes@363 | 113 | break; |
nkeynes@363 | 114 | case 'o': |
nkeynes@363 | 115 | output_file = optarg; |
nkeynes@363 | 116 | break; |
nkeynes@363 | 117 | case 's': |
nkeynes@363 | 118 | start_addr = strtoul(optarg, NULL, 0); |
nkeynes@363 | 119 | break; |
nkeynes@363 | 120 | case 'h': |
nkeynes@363 | 121 | usage(); |
nkeynes@363 | 122 | exit(0); |
nkeynes@363 | 123 | } |
nkeynes@363 | 124 | } |
nkeynes@363 | 125 | if( optind < argc ) { |
nkeynes@363 | 126 | input_file = argv[optind++]; |
nkeynes@363 | 127 | } else { |
nkeynes@363 | 128 | usage(); |
nkeynes@363 | 129 | exit(1); |
nkeynes@363 | 130 | } |
nkeynes@363 | 131 | |
nkeynes@363 | 132 | in = fopen( input_file, "ro" ); |
nkeynes@363 | 133 | if( in == NULL ) { |
nkeynes@363 | 134 | perror( "Unable to open input file" ); |
nkeynes@363 | 135 | exit(2); |
nkeynes@363 | 136 | } |
nkeynes@363 | 137 | fstat( fileno(in), &st ); |
nkeynes@363 | 138 | inbuf = malloc( st.st_size ); |
nkeynes@363 | 139 | fread( inbuf, st.st_size, 1, in ); |
nkeynes@363 | 140 | |
nkeynes@365 | 141 | xlat_cache_init(); |
nkeynes@363 | 142 | uint32_t pc; |
nkeynes@365 | 143 | uint8_t *buf = sh4_translate_basic_block( start_addr ); |
nkeynes@365 | 144 | uint32_t buflen = xlat_get_block_size(buf); |
nkeynes@365 | 145 | x86_disasm_init( buf, 0x8c010000, buflen ); |
nkeynes@365 | 146 | x86_set_symtab( local_symbols, 6 ); |
nkeynes@363 | 147 | for( pc = 0x8c010000; pc < 0x8c010000 + buflen; ) { |
nkeynes@363 | 148 | char buf[256]; |
nkeynes@363 | 149 | char op[256]; |
nkeynes@363 | 150 | uint32_t pc2 = x86_disasm_instruction( pc, buf, sizeof(buf), op ); |
nkeynes@363 | 151 | fprintf( stdout, "%08X: %-20s %s\n", pc, op, buf ); |
nkeynes@363 | 152 | pc = pc2; |
nkeynes@363 | 153 | } |
nkeynes@363 | 154 | } |
.