--- uae/src/newcpu.c 2018/04/24 16:47:25 1.1.1.7 +++ uae/src/newcpu.c 2018/04/24 16:52:58 1.1.1.10 @@ -97,20 +97,11 @@ void dump_counts (void) int broken_in; -static __inline__ unsigned int cft_map (unsigned int f) -{ -#ifndef HAVE_GET_WORD_UNSWAPPED - return f; -#else - return ((f >> 8) & 255) | ((f & 255) << 8); -#endif -} - static unsigned long op_illg_1 (uae_u32 opcode) REGPARAM; static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode) { - op_illg (cft_map (opcode)); + op_illg (opcode); return 4; } @@ -128,10 +119,10 @@ static void build_cpufunctbl (void) currprefs.cpu_level, currprefs.cpu_compatible, currprefs.address_space_24); for (opcode = 0; opcode < 65536; opcode++) - cpufunctbl[cft_map (opcode)] = op_illg_1; + cpufunctbl[opcode] = op_illg_1; for (i = 0; tbl[i].handler != NULL; i++) { if (! tbl[i].specific) - cpufunctbl[cft_map (tbl[i].opcode)] = tbl[i].handler; + cpufunctbl[tbl[i].opcode] = tbl[i].handler; } for (opcode = 0; opcode < 65536; opcode++) { cpuop_func *f; @@ -140,15 +131,15 @@ static void build_cpufunctbl (void) continue; if (table68k[opcode].handler != -1) { - f = cpufunctbl[cft_map (table68k[opcode].handler)]; + f = cpufunctbl[table68k[opcode].handler]; if (f == op_illg_1) abort(); - cpufunctbl[cft_map (opcode)] = f; + cpufunctbl[opcode] = f; } } for (i = 0; tbl[i].handler != NULL; i++) { if (tbl[i].specific) - cpufunctbl[cft_map (tbl[i].opcode)] = tbl[i].handler; + cpufunctbl[tbl[i].opcode] = tbl[i].handler; } } @@ -199,8 +190,8 @@ void init_m68k (void) for (j = 7 ; j >= 0 ; j--) { if (i & (1 << j)) break; } - fpp_movem_index1[i] = j; - fpp_movem_index2[i] = 7-j; + fpp_movem_index1[i] = 7-j; + fpp_movem_index2[i] = j; fpp_movem_next[i] = i & (~(1 << j)); } #if COUNT_INSTRS @@ -289,7 +280,7 @@ uae_s32 ShowEA (int reg, amodes mode, wo disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; addr = m68k_areg(regs,reg) + (uae_s16)disp16; sprintf (buffer,"(A%d,$%04x) == $%08lx", reg, disp16 & 0xffff, - (long unsigned int)addr); + (unsigned long)addr); break; case Ad8r: dp = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; @@ -322,20 +313,20 @@ uae_s32 ShowEA (int reg, amodes mode, wo dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp,outer, - (long unsigned int)addr); + (unsigned long)addr); } else { addr = m68k_areg(regs,reg) + (uae_s32)((uae_s8)disp8) + dispreg; sprintf (buffer,"(A%d, %c%d.%c*%d, $%02x) == $%08lx", reg, dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp8, - (long unsigned int)addr); + (unsigned long)addr); } break; case PC16: addr = m68k_getpc () + m68kpc_offset; disp16 = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; addr += (uae_s16)disp16; - sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(long unsigned int)addr); + sprintf (buffer,"(PC,$%04x) == $%08lx", disp16 & 0xffff,(unsigned long)addr); break; case PC8r: addr = m68k_getpc () + m68kpc_offset; @@ -369,20 +360,20 @@ uae_s32 ShowEA (int reg, amodes mode, wo dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), disp,outer, - (long unsigned int)addr); + (unsigned long)addr); } else { addr += (uae_s32)((uae_s8)disp8) + dispreg; sprintf (buffer,"(PC, %c%d.%c*%d, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3), - disp8, (long unsigned int)addr); + disp8, (unsigned long)addr); } break; case absw: - sprintf (buffer,"$%08lx", (long unsigned int)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); + sprintf (buffer,"$%08lx", (unsigned long)(uae_s32)(uae_s16)get_iword_1 (m68kpc_offset)); m68kpc_offset += 2; break; case absl: - sprintf (buffer,"$%08lx", (long unsigned int)get_ilong_1 (m68kpc_offset)); + sprintf (buffer,"$%08lx", (unsigned long)get_ilong_1 (m68kpc_offset)); m68kpc_offset += 4; break; case imm: @@ -396,7 +387,7 @@ uae_s32 ShowEA (int reg, amodes mode, wo m68kpc_offset += 2; break; case sz_long: - sprintf (buffer,"#$%08lx", (long unsigned int)(get_ilong_1 (m68kpc_offset))); + sprintf (buffer,"#$%08lx", (unsigned long)(get_ilong_1 (m68kpc_offset))); m68kpc_offset += 4; break; default: @@ -416,11 +407,11 @@ uae_s32 ShowEA (int reg, amodes mode, wo case imm2: offset = (uae_s32)get_ilong_1 (m68kpc_offset); m68kpc_offset += 4; - sprintf (buffer,"#$%08lx", (long unsigned int)offset); + sprintf (buffer,"#$%08lx", (unsigned long)offset); break; case immi: offset = (uae_s32)(uae_s8)(reg & 0xff); - sprintf (buffer,"#$%08lx", (long unsigned int)offset); + sprintf (buffer,"#$%08lx", (unsigned long)offset); break; default: break; @@ -762,11 +753,12 @@ static void Interrupt(int nr) static int caar, cacr; -void m68k_move2c (int regno, uae_u32 *regp) +int m68k_move2c (int regno, uae_u32 *regp) { - if (currprefs.cpu_level == 1 && (regno & 0x7FF) > 1) + if (currprefs.cpu_level == 1 && (regno & 0x7FF) > 1) { op_illg (0x4E7B); - else + return 0; + } else switch (regno) { case 0: regs.sfc = *regp & 7; break; case 1: regs.dfc = *regp & 7; break; @@ -778,15 +770,17 @@ void m68k_move2c (int regno, uae_u32 *re case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break; default: op_illg (0x4E7B); - break; + return 0; } + return 1; } -void m68k_movec2 (int regno, uae_u32 *regp) +int m68k_movec2 (int regno, uae_u32 *regp) { - if (currprefs.cpu_level == 1 && (regno & 0x7FF) > 1) + if (currprefs.cpu_level == 1 && (regno & 0x7FF) > 1) { op_illg (0x4E7A); - else + return 0; + } else switch (regno) { case 0: *regp = regs.sfc; break; case 1: *regp = regs.dfc; break; @@ -798,11 +792,12 @@ void m68k_movec2 (int regno, uae_u32 *re case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break; default: op_illg (0x4E7A); - break; + return 0; } + return 1; } -static __inline__ int +STATIC_INLINE int div_unsigned(uae_u32 src_hi, uae_u32 src_lo, uae_u32 div, uae_u32 *quot, uae_u32 *rem) { uae_u32 q = 0, cbit = 0; @@ -948,7 +943,7 @@ void m68k_divl (uae_u32 opcode, uae_u32 #endif } -static __inline__ void +STATIC_INLINE void mul_unsigned(uae_u32 src1, uae_u32 src2, uae_u32 *dst_hi, uae_u32 *dst_lo) { uae_u32 r0 = (src1 & 0xffff) * (src2 & 0xffff); @@ -1132,7 +1127,9 @@ unsigned long REGPARAM2 op_illg (uae_u32 Exception(0xA,0); return 4; } +#if 0 write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc); +#endif Exception (4,0); return 4; } @@ -1189,20 +1186,24 @@ static void do_trace (void) static int do_specialties (void) { + if (regs.spcflags & SPCFLAG_COPPER) + do_copper (); + /*n_spcinsns++;*/ while (regs.spcflags & SPCFLAG_BLTNASTY) { do_cycles (4); - if (regs.spcflags & SPCFLAG_DISK) - do_disk (); + if (regs.spcflags & SPCFLAG_COPPER) + do_copper (); } + run_compiled_code(); if (regs.spcflags & SPCFLAG_DOTRACE) { Exception (9,last_trace_ad); } while (regs.spcflags & SPCFLAG_STOP) { do_cycles (4); - if (regs.spcflags & SPCFLAG_DISK) - do_disk (); + if (regs.spcflags & SPCFLAG_COPPER) + do_copper (); if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)){ int intr = intlev (); regs.spcflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT); @@ -1216,9 +1217,6 @@ static int do_specialties (void) if (regs.spcflags & SPCFLAG_TRACE) do_trace (); - if (regs.spcflags & SPCFLAG_DISK) - do_disk (); - if (regs.spcflags & SPCFLAG_DOINT) { int intr = intlev (); regs.spcflags &= ~SPCFLAG_DOINT; @@ -1238,11 +1236,52 @@ static int do_specialties (void) return 0; } +/* It's really sad to have two almost identical functions for this, but we + do it all for performance... :( */ static void m68k_run_1 (void) { for (;;) { int cycles; - uae_u32 opcode = GET_OPCODE; + uae_u32 opcode = get_iword_prefetch (0); +#if 0 + if (get_ilong (0) != do_get_mem_long (®s.prefetch)) { + debugging = 1; + return; + } +#endif + /* assert (!regs.stopped && !(regs.spcflags & SPCFLAG_STOP)); */ +/* regs_backup[backup_pointer = (backup_pointer + 1) % 16] = regs;*/ +#if COUNT_INSTRS == 2 + if (table68k[opcode].handler != -1) + instrcount[table68k[opcode].handler]++; +#elif COUNT_INSTRS == 1 + instrcount[opcode]++; +#endif +#if defined X86_ASSEMBLY + __asm__ __volatile__("\tcall *%%ebx" + : "=&a" (cycles) : "b" (cpufunctbl[opcode]), "0" (opcode) + : "%edx", "%ecx", + "%esi", "%edi", "%ebp", "memory", "cc"); +#else + cycles = (*cpufunctbl[opcode])(opcode); +#endif + /*n_insns++;*/ + cycles &= cycles_mask; + cycles |= cycles_val; + do_cycles (cycles); + if (regs.spcflags) { + if (do_specialties ()) + return; + } + } +} + +/* Same thing, but don't use prefetch to get opcode. */ +static void m68k_run_2 (void) +{ + for (;;) { + int cycles; + uae_u32 opcode = get_iword (0); #if 0 if (get_ilong (0) != do_get_mem_long (®s.prefetch)) { debugging = 1; @@ -1252,12 +1291,12 @@ static void m68k_run_1 (void) /* assert (!regs.stopped && !(regs.spcflags & SPCFLAG_STOP)); */ /* regs_backup[backup_pointer = (backup_pointer + 1) % 16] = regs;*/ #if COUNT_INSTRS == 2 - if (table68k[cft_map (opcode)].handler != -1) - instrcount[table68k[cft_map (opcode)].handler]++; + if (table68k[opcode].handler != -1) + instrcount[table68k[opcode].handler]++; #elif COUNT_INSTRS == 1 instrcount[opcode]++; #endif -#if defined(X86_ASSEMBLY) +#if defined X86_ASSEMBLY __asm__ __volatile__("\tcall *%%ebx" : "=&a" (cycles) : "b" (cpufunctbl[opcode]), "0" (opcode) : "%edx", "%ecx", @@ -1277,13 +1316,14 @@ static void m68k_run_1 (void) } #ifdef X86_ASSEMBLY -static __inline__ void m68k_run1 (void) +STATIC_INLINE void m68k_run1 (void (*func)(void)) { /* Work around compiler bug: GCC doesn't push %ebp in m68k_run_1. */ - __asm__ __volatile__ ("pushl %%ebp\n\tcall *%0\n\tpopl %%ebp" : : "r" (m68k_run_1) : "%eax", "%edx", "%ecx", "memory", "cc"); + __asm__ __volatile__ ("pushl %%ebp\n\tcall *%0\n\tpopl %%ebp" + : : "r" (func) : "%eax", "%edx", "%ecx", "memory", "cc"); } #else -#define m68k_run1 m68k_run_1 +#define m68k_run1(F) F #endif int in_m68k_go = 0; @@ -1310,7 +1350,7 @@ void m68k_go (int may_quit) } if (debugging) debug (); - m68k_run1 (); + m68k_run1 (currprefs.cpu_compatible ? m68k_run_1 : m68k_run_2); } in_m68k_go--; } @@ -1324,7 +1364,7 @@ static void m68k_verify (uaecptr addr, u last_op_for_exception_3 = opcode; m68kpc_offset = 2; - if (cpufunctbl[cft_map (opcode)] == op_illg_1) { + if (cpufunctbl[opcode] == op_illg_1) { opcode = 0x4AFC; } dp = table68k + opcode; @@ -1359,7 +1399,7 @@ void m68k_disasm (uaecptr addr, uaecptr } opcode = get_iword_1 (m68kpc_offset); m68kpc_offset += 2; - if (cpufunctbl[cft_map (opcode)] == op_illg_1) { + if (cpufunctbl[opcode] == op_illg_1) { opcode = 0x4AFC; } dp = table68k + opcode;