ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/newcpu.cpp
(Generate patch)

Comparing BasiliskII/src/uae_cpu/newcpu.cpp (file contents):
Revision 1.12 by gbeauche, 2002-03-23T13:57:38Z vs.
Revision 1.22 by gbeauche, 2006-01-15T22:42:51Z

# Line 22 | Line 22 | extern int intlev(void);       // From baisili
22   #include "memory.h"
23   #include "readcpu.h"
24   #include "newcpu.h"
25 + #include "compiler/compemu.h"
26 + #include "fpu/fpu.h"
27 +
28 + #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS)
29 + B2_mutex *spcflags_lock = NULL;
30 + #endif
31  
32   #if ENABLE_MON
33   #include "mon.h"
34   #include "mon_disass.h"
35   #endif
36  
37 < int quit_program = 0;
32 < int debugging = 0;
37 > bool quit_program = false;
38   struct flag_struct regflags;
39  
40   /* Opcode of faulting instruction */
# Line 46 | Line 51 | int movem_index1[256];
51   int movem_index2[256];
52   int movem_next[256];
53  
49 int fpp_movem_index1[256];
50 int fpp_movem_index2[256];
51 int fpp_movem_next[256];
52
54   cpuop_func *cpufunctbl[65536];
55  
55 #define FLIGHT_RECORDER 0
56
56   #if FLIGHT_RECORDER
57   struct rec_step {
58 +        uae_u32 pc;
59 + #if FLIGHT_RECORDER >= 2
60          uae_u32 d[8];
61          uae_u32 a[8];
62 <        uae_u32 pc;
62 > #endif
63   };
64  
65 < const int LOG_SIZE = 8192;
65 > const int LOG_SIZE = 32768;
66   static rec_step log[LOG_SIZE];
67   static int log_ptr = -1; // First time initialization
68  
# Line 71 | Line 72 | static const char *log_filename(void)
72          return name ? name : "log.68k";
73   }
74  
75 < static void record_step(uaecptr pc)
75 > void m68k_record_step(uaecptr pc)
76   {
77 <        for (int i = 0; i < 8; i++) {
78 <                log[log_ptr].d[i] = m68k_dreg(regs, i);
79 <                log[log_ptr].a[i] = m68k_areg(regs, i);
77 > #if FLIGHT_RECORDER >= 2
78 >        /* XXX: if LSB is set, we are recording from generated code and we
79 >           don't support registers recording yet.  */
80 >        if ((pc & 1) == 0) {
81 >                for (int i = 0; i < 8; i++) {
82 >                        log[log_ptr].d[i] = m68k_dreg(regs, i);
83 >                        log[log_ptr].a[i] = m68k_areg(regs, i);
84 >                }
85          }
86 + #endif
87          log[log_ptr].pc = pc;
88          log_ptr = (log_ptr + 1) % LOG_SIZE;
89   }
# Line 88 | Line 95 | static void dump_log(void)
95                  return;
96          for (int i = 0; i < LOG_SIZE; i++) {
97                  int j = (i + log_ptr) % LOG_SIZE;
98 <                fprintf(f, "pc %08x\n", log[j].pc);
99 <                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]);
100 <                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]);
101 <                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]);
102 <                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]);
98 >                uae_u32 pc = log[j].pc & ~1;
99 >                fprintf(f, "pc %08x", pc);
100 > #if FLIGHT_RECORDER >= 2
101 >                fprintf(f, "\n");
102 >                if ((log[j].pc & 1) == 0) {
103 >                        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]);
104 >                        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]);
105 >                        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]);
106 >                        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]);
107 >                }
108 > #else
109 >                fprintf(f, " | ");
110 > #endif
111   #if ENABLE_MON
112 <                disass_68k(f, log[j].pc);
112 >                disass_68k(f, pc);
113   #endif
114          }
115          fclose(f);
116   }
117   #endif
118  
119 + #if ENABLE_MON
120 + static void dump_regs(void)
121 + {
122 +        m68k_dumpstate(NULL);
123 + }
124 + #endif
125 +
126   #define COUNT_INSTRS 0
127  
128   #if COUNT_INSTRS
# Line 164 | Line 186 | static __inline__ unsigned int cft_map (
186   #endif
187   }
188  
189 < static void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM;
189 > void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM;
190  
191 < static void REGPARAM2 op_illg_1 (uae_u32 opcode)
191 > void REGPARAM2 op_illg_1 (uae_u32 opcode)
192   {
193      op_illg (cft_map (opcode));
194   }
# Line 187 | Line 209 | static void build_cpufunctbl (void)
209                          cpu_level = 1;
210          }
211      struct cputbl *tbl = (
212 <                  cpu_level == 4 ? op_smalltbl_0
213 <                : cpu_level == 3 ? op_smalltbl_1
214 <                : cpu_level == 2 ? op_smalltbl_2
215 <                : cpu_level == 1 ? op_smalltbl_3
216 <                : op_smalltbl_4);
212 >                  cpu_level == 4 ? op_smalltbl_0_ff
213 >                : cpu_level == 3 ? op_smalltbl_1_ff
214 >                : cpu_level == 2 ? op_smalltbl_2_ff
215 >                : cpu_level == 1 ? op_smalltbl_3_ff
216 >                : op_smalltbl_4_ff);
217  
218      for (opcode = 0; opcode < 65536; opcode++)
219          cpufunctbl[cft_map (opcode)] = op_illg_1;
# Line 231 | Line 253 | void init_m68k (void)
253          movem_index2[i] = 7-j;
254          movem_next[i] = i & (~(1 << j));
255      }
234    for (i = 0 ; i < 256 ; i++) {
235        int j;
236        for (j = 7 ; j >= 0 ; j--) {
237                if (i & (1 << j)) break;
238        }
239        fpp_movem_index1[i] = 7-j;
240        fpp_movem_index2[i] = j;
241        fpp_movem_next[i] = i & (~(1 << j));
242    }
256   #if COUNT_INSTRS
257      {
258          FILE *f = fopen (icountfilename (), "r");
# Line 260 | Line 273 | void init_m68k (void)
273      do_merges ();
274  
275      build_cpufunctbl ();
276 <    
277 <    fpu_init ();
278 <    fpu_set_integral_fpu (CPUType == 4);
276 >        
277 > #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS)
278 >        spcflags_lock = B2_create_mutex();
279 > #endif
280 >    fpu_init(CPUType == 4);
281   }
282  
283   void exit_m68k (void)
284   {
285          fpu_exit ();
286 + #if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS)
287 +        B2_delete_mutex(spcflags_lock);
288 + #endif
289   }
290  
291   struct regstruct regs, lastint_regs;
# Line 703 | Line 721 | void MakeFromSR (void)
721          }
722      }
723  
724 <    regs.spcflags |= SPCFLAG_INT;
724 >    SPCFLAGS_SET( SPCFLAG_INT );
725      if (regs.t1 || regs.t0)
726 <        regs.spcflags |= SPCFLAG_TRACE;
726 >                SPCFLAGS_SET( SPCFLAG_TRACE );
727      else
728          /* Keep SPCFLAG_DOTRACE, we still want a trace exception for
729             SR-modifying instructions (including STOP).  */
730 <        regs.spcflags &= ~SPCFLAG_TRACE;
730 >                SPCFLAGS_CLEAR( SPCFLAG_TRACE );
731   }
732  
733   void Exception(int nr, uaecptr oldpc)
# Line 774 | Line 792 | kludge_me_do:
792      m68k_areg(regs, 7) -= 2;
793      put_word (m68k_areg(regs, 7), regs.sr);
794      m68k_setpc (get_long (regs.vbr + 4*nr));
795 +        SPCFLAGS_SET( SPCFLAG_JIT_END_COMPILE );
796      fill_prefetch_0 ();
797      regs.t1 = regs.t0 = regs.m = 0;
798 <    regs.spcflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
798 >        SPCFLAGS_CLEAR( SPCFLAG_TRACE | SPCFLAG_DOTRACE );
799   }
800  
801   static void Interrupt(int nr)
# Line 787 | Line 806 | static void Interrupt(int nr)
806      Exception(nr+24, 0);
807  
808      regs.intmask = nr;
809 <    regs.spcflags |= SPCFLAG_INT;
809 >        SPCFLAGS_SET( SPCFLAG_INT );
810   }
811  
812   static int caar, cacr, tc, itt0, itt1, dtt0, dtt1, mmusr, urp, srp;
# Line 804 | Line 823 | int m68k_move2c (int regno, uae_u32 *reg
823          switch (regno) {
824           case 0: regs.sfc = *regp & 7; break;
825           case 1: regs.dfc = *regp & 7; break;
826 <         case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); break;
826 >         case 2:
827 >                cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000);
828 > #if USE_JIT
829 >                if (CPUType < 4) {
830 >                        set_cache_state(cacr&1);
831 >                        if (*regp & 0x08)
832 >                                flush_icache(1);
833 >                }
834 >                else {
835 >                        set_cache_state((cacr&0x8000) || 0);
836 >                        // FIXME: The User Manual claims bit 3 of CACR is undefined
837 >                        if (*regp & 0x08)
838 >                                flush_icache(2);
839 >                }
840 > #endif
841 >         break;
842           case 3: tc = *regp & 0xc000; break;
843           case 4: itt0 = *regp & 0xffffe364; break;
844           case 5: itt1 = *regp & 0xffffe364; break;
# Line 1115 | Line 1149 | static char* ccnames[] =
1149   { "T ","F ","HI","LS","CC","CS","NE","EQ",
1150    "VC","VS","PL","MI","GE","LT","GT","LE" };
1151  
1152 + // If value is greater than zero, this means we are still processing an EmulOp
1153 + // because the counter is incremented only in m68k_execute(), i.e. interpretive
1154 + // execution only
1155 + static int m68k_execute_depth = 0;
1156 +
1157   void m68k_reset (void)
1158   {
1159      m68k_areg (regs, 7) = 0x2000;
1160      m68k_setpc (ROMBaseMac + 0x2a);
1161      fill_prefetch_0 ();
1123    regs.kick_mask = 0xF80000;
1162      regs.s = 1;
1163      regs.m = 0;
1164      regs.stopped = 0;
# Line 1131 | Line 1169 | void m68k_reset (void)
1169      SET_CFLG (0);
1170      SET_VFLG (0);
1171      SET_NFLG (0);
1172 <    regs.spcflags = 0;
1172 >        SPCFLAGS_INIT( 0 );
1173      regs.intmask = 7;
1174      regs.vbr = regs.sfc = regs.dfc = 0;
1137    /* gb-- moved into {fpp,fpu_x86}.cpp::fpu_init()
1138    regs.fpcr = regs.fpsr = regs.fpiar = 0; */
1175      fpu_reset();
1176          
1177   #if FLIGHT_RECORDER
1178 +        log_ptr = 0;
1179 +        memset(log, 0, sizeof(log));
1180 + #endif
1181 +
1182   #if ENABLE_MON
1183 <        if (log_ptr == -1) {
1183 >        static bool first_time = true;
1184 >        if (first_time) {
1185 >                first_time = false;
1186 >                mon_add_command("regs", dump_regs, "regs                    Dump m68k emulator registers\n");
1187 > #if FLIGHT_RECORDER
1188                  // Install "log" command in mon
1189                  mon_add_command("log", dump_log, "log                      Dump m68k emulation log\n");
1146        }
1190   #endif
1191 <        log_ptr = 0;
1149 <        memset(log, 0, sizeof(log));
1191 >        }
1192   #endif
1193   }
1194  
1195 < void REGPARAM2 op_illg (uae_u32 opcode)
1195 > void m68k_emulop_return(void)
1196   {
1197 <    uaecptr pc = m68k_getpc ();
1197 >        SPCFLAGS_SET( SPCFLAG_BRK );
1198 >        quit_program = true;
1199 > }
1200  
1201 <        if ((opcode & 0xFF00) == 0x7100) {
1201 > void m68k_emulop(uae_u32 opcode)
1202 > {
1203                  struct M68kRegisters r;
1204                  int i;
1205  
1161                // Return from Exectue68k()?
1162                if (opcode == M68K_EXEC_RETURN) {
1163                        regs.spcflags |= SPCFLAG_BRK;
1164                        quit_program = 1;
1165                        return;
1166                }
1167
1168                // Call EMUL_OP opcode
1206                  for (i=0; i<8; i++) {
1207                          r.d[i] = m68k_dreg(regs, i);
1208                          r.a[i] = m68k_areg(regs, i);
# Line 1179 | Line 1216 | void REGPARAM2 op_illg (uae_u32 opcode)
1216                  }
1217                  regs.sr = r.sr;
1218                  MakeFromSR();
1219 <                m68k_incpc(2);
1220 <                fill_prefetch_0 ();
1221 <                return;
1222 <        }
1219 > }
1220 >
1221 > void REGPARAM2 op_illg (uae_u32 opcode)
1222 > {
1223 >        uaecptr pc = m68k_getpc ();
1224  
1225      if ((opcode & 0xF000) == 0xA000) {
1226          Exception(0xA,0);
1227          return;
1228      }
1229  
1192 //    write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc);
1193
1230      if ((opcode & 0xF000) == 0xF000) {
1231          Exception(0xB,0);
1232          return;
1233      }
1234  
1235      write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc);
1236 + #if USE_JIT && JIT_DEBUG
1237 +    compiler_dumpstate();
1238 + #endif
1239  
1240      Exception (4,0);
1241 +        return;
1242   }
1243  
1244   void mmu_op(uae_u32 opcode, uae_u16 extra)
# Line 1225 | Line 1265 | static void do_trace (void)
1265         /* We can afford this to be inefficient... */
1266         m68k_setpc (m68k_getpc ());
1267         fill_prefetch_0 ();
1268 <       opcode = get_word (regs.pc);
1268 >       opcode = get_word(m68k_getpc());
1269         if (opcode == 0x4e72            /* RTE */
1270             || opcode == 0x4e74                 /* RTD */
1271             || opcode == 0x4e75                 /* RTS */
# Line 1241 | Line 1281 | static void do_trace (void)
1281                 && (uae_s16)m68k_dreg(regs, opcode & 7) != 0))
1282        {
1283              last_trace_ad = m68k_getpc ();
1284 <            regs.spcflags &= ~SPCFLAG_TRACE;
1285 <            regs.spcflags |= SPCFLAG_DOTRACE;
1284 >                SPCFLAGS_CLEAR( SPCFLAG_TRACE );
1285 >                SPCFLAGS_SET( SPCFLAG_DOTRACE );
1286          }
1287      } else if (regs.t1) {
1288         last_trace_ad = m68k_getpc ();
1289 <       regs.spcflags &= ~SPCFLAG_TRACE;
1290 <       regs.spcflags |= SPCFLAG_DOTRACE;
1289 >       SPCFLAGS_CLEAR( SPCFLAG_TRACE );
1290 >       SPCFLAGS_SET( SPCFLAG_DOTRACE );
1291      }
1292   }
1293  
1294 <
1255 < static int do_specialties (void)
1294 > int m68k_do_specialties (void)
1295   {
1296 <    /*n_spcinsns++;*/
1297 <    if (regs.spcflags & SPCFLAG_DOTRACE) {
1296 > #if USE_JIT
1297 >    // Block was compiled
1298 >    SPCFLAGS_CLEAR( SPCFLAG_JIT_END_COMPILE );
1299 >
1300 >    // Retain the request to get out of compiled code until
1301 >    // we reached the toplevel execution, i.e. the one that
1302 >    // can compile then run compiled code. This also means
1303 >    // we processed all (nested) EmulOps
1304 >    if ((m68k_execute_depth == 0) && SPCFLAGS_TEST( SPCFLAG_JIT_EXEC_RETURN ))
1305 >        SPCFLAGS_CLEAR( SPCFLAG_JIT_EXEC_RETURN );
1306 > #endif
1307 >        
1308 >    if (SPCFLAGS_TEST( SPCFLAG_DOTRACE )) {
1309          Exception (9,last_trace_ad);
1310      }
1311 <    while (regs.spcflags & SPCFLAG_STOP) {
1312 <        if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)){
1311 >    while (SPCFLAGS_TEST( SPCFLAG_STOP )) {
1312 >        if (SPCFLAGS_TEST( SPCFLAG_INT | SPCFLAG_DOINT )){
1313 >                SPCFLAGS_CLEAR( SPCFLAG_INT | SPCFLAG_DOINT );
1314              int intr = intlev ();
1264            regs.spcflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
1315              if (intr != -1 && intr > regs.intmask) {
1316                  Interrupt (intr);
1317                  regs.stopped = 0;
1318 <                regs.spcflags &= ~SPCFLAG_STOP;
1318 >                SPCFLAGS_CLEAR( SPCFLAG_STOP );
1319              }
1320          }
1321      }
1322 <    if (regs.spcflags & SPCFLAG_TRACE)
1322 >    if (SPCFLAGS_TEST( SPCFLAG_TRACE ))
1323         do_trace ();
1324  
1325 <    if (regs.spcflags & SPCFLAG_DOINT) {
1325 >    if (SPCFLAGS_TEST( SPCFLAG_DOINT )) {
1326 >        SPCFLAGS_CLEAR( SPCFLAG_DOINT );
1327          int intr = intlev ();
1277        regs.spcflags &= ~SPCFLAG_DOINT;
1328          if (intr != -1 && intr > regs.intmask) {
1329              Interrupt (intr);
1330              regs.stopped = 0;
1331          }
1332      }
1333 <    if (regs.spcflags & SPCFLAG_INT) {
1334 <        regs.spcflags &= ~SPCFLAG_INT;
1335 <        regs.spcflags |= SPCFLAG_DOINT;
1333 >    if (SPCFLAGS_TEST( SPCFLAG_INT )) {
1334 >        SPCFLAGS_CLEAR( SPCFLAG_INT );
1335 >        SPCFLAGS_SET( SPCFLAG_DOINT );
1336      }
1337 <    if (regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)) {
1338 <        regs.spcflags &= ~(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
1337 >    if (SPCFLAGS_TEST( SPCFLAG_BRK )) {
1338 >        SPCFLAGS_CLEAR( SPCFLAG_BRK );
1339          return 1;
1340      }
1341      return 0;
1342   }
1343  
1344 < static void m68k_run_1 (void)
1344 > void m68k_do_execute (void)
1345   {
1346          for (;;) {
1347                  uae_u32 opcode = GET_OPCODE;
1348   #if FLIGHT_RECORDER
1349 <                record_step(m68k_getpc());
1349 >                m68k_record_step(m68k_getpc());
1350   #endif
1301 #ifdef X86_ASSEMBLY
1302                __asm__ __volatile__("\tpushl %%ebp\n\tcall *%%ebx\n\tpopl %%ebp" /* FIXME */
1303                                                         : : "b" (cpufunctbl[opcode]), "a" (opcode)
1304                                                         : "%edx", "%ecx", "%esi", "%edi",  "%ebp", "memory", "cc");
1305 #else
1351                  (*cpufunctbl[opcode])(opcode);
1352 < #endif
1353 <                if (regs.spcflags) {
1354 <                        if (do_specialties())
1352 >                cpu_check_ticks();
1353 >                if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) {
1354 >                        if (m68k_do_specialties())
1355                                  return;
1356                  }
1357          }
1358   }
1359  
1360 < #define m68k_run1 m68k_run_1
1316 <
1317 < int in_m68k_go = 0;
1318 <
1319 < void m68k_go (int may_quit)
1360 > void m68k_execute (void)
1361   {
1362 < // m68k_go() must be reentrant for Execute68k() and Execute68kTrap() to work
1363 < /*
1364 <    if (in_m68k_go || !may_quit) {
1324 <        write_log("Bug! m68k_go is not reentrant.\n");
1325 <        abort();
1326 <    }
1327 < */
1328 <    in_m68k_go++;
1362 > #if USE_JIT
1363 >    ++m68k_execute_depth;
1364 > #endif
1365      for (;;) {
1366 <        if (quit_program > 0) {
1331 <            if (quit_program == 1)
1366 >          if (quit_program)
1367                  break;
1368 <            quit_program = 0;
1334 <            m68k_reset ();
1335 <        }
1336 <        m68k_run1();
1368 >          m68k_do_execute();
1369      }
1370 <        if (debugging) {
1371 <                uaecptr nextpc;
1372 <                m68k_dumpstate(&nextpc);
1341 <                exit(1);
1342 <        }
1343 <    in_m68k_go--;
1370 > #if USE_JIT
1371 >    --m68k_execute_depth;
1372 > #endif
1373   }
1374  
1375   static void m68k_verify (uaecptr addr, uaecptr *nextpc)
# Line 1449 | Line 1478 | void m68k_dumpstate (uaecptr *nextpc)
1478      printf ("T=%d%d S=%d M=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n",
1479              regs.t1, regs.t0, regs.s, regs.m,
1480              GET_XFLG, GET_NFLG, GET_ZFLG, GET_VFLG, GET_CFLG, regs.intmask);
1481 <    for (i = 0; i < 8; i++){
1482 <        printf ("FP%d: %g ", i, regs.fp[i]);
1483 <        if ((i & 3) == 3) printf ("\n");
1484 <    }
1456 <    printf ("N=%d Z=%d I=%d NAN=%d\n",
1457 <                (regs.fpsr & 0x8000000) != 0,
1458 <                (regs.fpsr & 0x4000000) != 0,
1459 <                (regs.fpsr & 0x2000000) != 0,
1460 <                (regs.fpsr & 0x1000000) != 0);
1461 <
1481 >        
1482 >        fpu_dump_registers();
1483 >        fpu_dump_flags();
1484 >        
1485      m68k_disasm(m68k_getpc (), nextpc, 1);
1486      if (nextpc)
1487          printf ("next PC: %08lx\n", *nextpc);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines