--- BasiliskII/src/uae_cpu/newcpu.cpp 2002/09/01 16:32:02 1.14 +++ BasiliskII/src/uae_cpu/newcpu.cpp 2005/06/11 06:43:24 1.21 @@ -22,6 +22,8 @@ extern int intlev(void); // From baisili #include "memory.h" #include "readcpu.h" #include "newcpu.h" +#include "compiler/compemu.h" +#include "fpu/fpu.h" #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) B2_mutex *spcflags_lock = NULL; @@ -32,8 +34,7 @@ B2_mutex *spcflags_lock = NULL; #include "mon_disass.h" #endif -int quit_program = 0; -const int debugging = 0; +bool quit_program = false; struct flag_struct regflags; /* Opcode of faulting instruction */ @@ -50,22 +51,18 @@ int movem_index1[256]; int movem_index2[256]; int movem_next[256]; -int fpp_movem_index1[256]; -int fpp_movem_index2[256]; -int fpp_movem_next[256]; - cpuop_func *cpufunctbl[65536]; -#define FLIGHT_RECORDER 0 - #if FLIGHT_RECORDER struct rec_step { + uae_u32 pc; +#if FLIGHT_RECORDER >= 2 uae_u32 d[8]; uae_u32 a[8]; - uae_u32 pc; +#endif }; -const int LOG_SIZE = 8192; +const int LOG_SIZE = 32768; static rec_step log[LOG_SIZE]; static int log_ptr = -1; // First time initialization @@ -75,12 +72,18 @@ static const char *log_filename(void) return name ? name : "log.68k"; } -static void record_step(uaecptr pc) +void m68k_record_step(uaecptr pc) { - for (int i = 0; i < 8; i++) { - log[log_ptr].d[i] = m68k_dreg(regs, i); - log[log_ptr].a[i] = m68k_areg(regs, i); +#if FLIGHT_RECORDER >= 2 + /* XXX: if LSB is set, we are recording from generated code and we + don't support registers recording yet. */ + if ((pc & 1) == 0) { + for (int i = 0; i < 8; i++) { + log[log_ptr].d[i] = m68k_dreg(regs, i); + log[log_ptr].a[i] = m68k_areg(regs, i); + } } +#endif log[log_ptr].pc = pc; log_ptr = (log_ptr + 1) % LOG_SIZE; } @@ -92,19 +95,34 @@ static void dump_log(void) return; for (int i = 0; i < LOG_SIZE; i++) { int j = (i + log_ptr) % LOG_SIZE; - fprintf(f, "pc %08x\n", log[j].pc); - fprintf(f, "d0 %08x d1 %08x d2 %08x d3 %08x\n", log[j].d[0], log[j].d[1], log[j].d[2], log[j].d[3]); - fprintf(f, "d4 %08x d5 %08x d6 %08x d7 %08x\n", log[j].d[4], log[j].d[5], log[j].d[6], log[j].d[7]); - fprintf(f, "a0 %08x a1 %08x a2 %08x a3 %08x\n", log[j].a[0], log[j].a[1], log[j].a[2], log[j].a[3]); - fprintf(f, "a4 %08x a5 %08x a6 %08x a7 %08x\n", log[j].a[4], log[j].a[5], log[j].a[6], log[j].a[7]); + uae_u32 pc = log[j].pc & ~1; + fprintf(f, "pc %08x", pc); +#if FLIGHT_RECORDER >= 2 + fprintf(f, "\n"); + if ((log[j].pc & 1) == 0) { + fprintf(f, "d0 %08x d1 %08x d2 %08x d3 %08x\n", log[j].d[0], log[j].d[1], log[j].d[2], log[j].d[3]); + fprintf(f, "d4 %08x d5 %08x d6 %08x d7 %08x\n", log[j].d[4], log[j].d[5], log[j].d[6], log[j].d[7]); + fprintf(f, "a0 %08x a1 %08x a2 %08x a3 %08x\n", log[j].a[0], log[j].a[1], log[j].a[2], log[j].a[3]); + fprintf(f, "a4 %08x a5 %08x a6 %08x a7 %08x\n", log[j].a[4], log[j].a[5], log[j].a[6], log[j].a[7]); + } +#else + fprintf(f, " | "); +#endif #if ENABLE_MON - disass_68k(f, log[j].pc); + disass_68k(f, pc); #endif } fclose(f); } #endif +#if ENABLE_MON +static void dump_regs(void) +{ + m68k_dumpstate(NULL); +} +#endif + #define COUNT_INSTRS 0 #if COUNT_INSTRS @@ -168,11 +186,11 @@ static __inline__ unsigned int cft_map ( #endif } -cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; +void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM; -cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode) +void REGPARAM2 op_illg_1 (uae_u32 opcode) { - cpuop_return( op_illg (cft_map (opcode)) ); + op_illg (cft_map (opcode)); } static void build_cpufunctbl (void) @@ -235,15 +253,6 @@ void init_m68k (void) movem_index2[i] = 7-j; movem_next[i] = i & (~(1 << j)); } - for (i = 0 ; i < 256 ; i++) { - int j; - for (j = 7 ; j >= 0 ; j--) { - if (i & (1 << j)) break; - } - fpp_movem_index1[i] = 7-j; - fpp_movem_index2[i] = j; - fpp_movem_next[i] = i & (~(1 << j)); - } #if COUNT_INSTRS { FILE *f = fopen (icountfilename (), "r"); @@ -268,9 +277,7 @@ void init_m68k (void) #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) spcflags_lock = B2_create_mutex(); #endif - - fpu_init (); - fpu_set_integral_fpu (CPUType == 4); + fpu_init(CPUType == 4); } void exit_m68k (void) @@ -816,7 +823,22 @@ int m68k_move2c (int regno, uae_u32 *reg switch (regno) { case 0: regs.sfc = *regp & 7; break; case 1: regs.dfc = *regp & 7; break; - case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); break; + case 2: + cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); +#if USE_JIT + if (CPUType < 4) { + set_cache_state(cacr&1); + if (*regp & 0x08) + flush_icache(1); + } + else { + set_cache_state((cacr&0x8000) || 0); + // FIXME: The User Manual claims bit 3 of CACR is undefined + if (*regp & 0x08) + flush_icache(2); + } +#endif + break; case 3: tc = *regp & 0xc000; break; case 4: itt0 = *regp & 0xffffe364; break; case 5: itt1 = *regp & 0xffffe364; break; @@ -1153,21 +1175,27 @@ void m68k_reset (void) fpu_reset(); #if FLIGHT_RECORDER + log_ptr = 0; + memset(log, 0, sizeof(log)); +#endif + #if ENABLE_MON - if (log_ptr == -1) { + static bool first_time = true; + if (first_time) { + first_time = false; + mon_add_command("regs", dump_regs, "regs Dump m68k emulator registers\n"); +#if FLIGHT_RECORDER // Install "log" command in mon mon_add_command("log", dump_log, "log Dump m68k emulation log\n"); - } #endif - log_ptr = 0; - memset(log, 0, sizeof(log)); + } #endif } void m68k_emulop_return(void) { SPCFLAGS_SET( SPCFLAG_BRK ); - quit_program = 1; + quit_program = true; } void m68k_emulop(uae_u32 opcode) @@ -1190,24 +1218,27 @@ void m68k_emulop(uae_u32 opcode) MakeFromSR(); } -cpuop_rettype REGPARAM2 op_illg (uae_u32 opcode) +void REGPARAM2 op_illg (uae_u32 opcode) { uaecptr pc = m68k_getpc (); if ((opcode & 0xF000) == 0xA000) { Exception(0xA,0); - cpuop_return(CFLOW_TRAP); + return; } if ((opcode & 0xF000) == 0xF000) { Exception(0xB,0); - cpuop_return(CFLOW_TRAP); + return; } write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); +#if USE_JIT && JIT_DEBUG + compiler_dumpstate(); +#endif Exception (4,0); - cpuop_return(CFLOW_TRAP); + return; } void mmu_op(uae_u32 opcode, uae_u16 extra) @@ -1262,6 +1293,18 @@ static void do_trace (void) int m68k_do_specialties (void) { +#if USE_JIT + // Block was compiled + SPCFLAGS_CLEAR( SPCFLAG_JIT_END_COMPILE ); + + // Retain the request to get out of compiled code until + // we reached the toplevel execution, i.e. the one that + // can compile then run compiled code. This also means + // we processed all (nested) EmulOps + if ((m68k_execute_depth == 0) && SPCFLAGS_TEST( SPCFLAG_JIT_EXEC_RETURN )) + SPCFLAGS_CLEAR( SPCFLAG_JIT_EXEC_RETURN ); +#endif + if (SPCFLAGS_TEST( SPCFLAG_DOTRACE )) { Exception (9,last_trace_ad); } @@ -1293,7 +1336,7 @@ int m68k_do_specialties (void) } if (SPCFLAGS_TEST( SPCFLAG_BRK )) { SPCFLAGS_CLEAR( SPCFLAG_BRK ); - return CFLOW_EXEC_RETURN; + return 1; } return 0; } @@ -1303,38 +1346,41 @@ void m68k_do_execute (void) for (;;) { uae_u32 opcode = GET_OPCODE; #if FLIGHT_RECORDER - record_step(m68k_getpc()); + m68k_record_step(m68k_getpc()); #endif -#ifdef X86_ASSEMBLY - __asm__ __volatile__("\tpushl %%ebp\n\tcall *%%ebx\n\tpopl %%ebp" /* FIXME */ - : : "b" (cpufunctbl[opcode]), "a" (opcode) - : "%edx", "%ecx", "%esi", "%edi", "%ebp", "memory", "cc"); -#else (*cpufunctbl[opcode])(opcode); -#endif - if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) { - if (m68k_do_specialties()) + cpu_check_ticks(); + if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) { + if (m68k_do_specialties()) return; } } } +#if USE_JIT && !(defined(X86_ASSEMBLY) || defined(X86_64_ASSEMBLY)) +void m68k_compile_execute (void) +{ + for (;;) { + if (quit_program) + break; + m68k_do_compile_execute(); + } +} +#endif + void m68k_execute (void) { +#if USE_JIT + ++m68k_execute_depth; +#endif for (;;) { - if (quit_program > 0) { - if (quit_program == 1) + if (quit_program) break; - quit_program = 0; - m68k_reset (); - } - m68k_do_execute(); + m68k_do_execute(); } - if (debugging) { - uaecptr nextpc; - m68k_dumpstate(&nextpc); - exit(1); - } +#if USE_JIT + --m68k_execute_depth; +#endif } static void m68k_verify (uaecptr addr, uaecptr *nextpc) @@ -1443,16 +1489,10 @@ void m68k_dumpstate (uaecptr *nextpc) printf ("T=%d%d S=%d M=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n", regs.t1, regs.t0, regs.s, regs.m, GET_XFLG, GET_NFLG, GET_ZFLG, GET_VFLG, GET_CFLG, regs.intmask); - for (i = 0; i < 8; i++){ - printf ("FP%d: %g ", i, regs.fp[i]); - if ((i & 3) == 3) printf ("\n"); - } - printf ("N=%d Z=%d I=%d NAN=%d\n", - (regs.fpsr & 0x8000000) != 0, - (regs.fpsr & 0x4000000) != 0, - (regs.fpsr & 0x2000000) != 0, - (regs.fpsr & 0x1000000) != 0); - + + fpu_dump_registers(); + fpu_dump_flags(); + m68k_disasm(m68k_getpc (), nextpc, 1); if (nextpc) printf ("next PC: %08lx\n", *nextpc);