ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp
(Generate patch)

Comparing SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp (file contents):
Revision 1.11 by gbeauche, 2003-10-26T14:16:39Z vs.
Revision 1.15 by gbeauche, 2003-11-04T20:48:29Z

# Line 28 | Line 28
28   #include "macos_util.h"
29   #include "block-alloc.hpp"
30   #include "sigsegv.h"
31 #include "spcflags.h"
31   #include "cpu/ppc/ppc-cpu.hpp"
32   #include "cpu/ppc/ppc-operations.hpp"
33  
# Line 47 | Line 46
46   #define DEBUG 0
47   #include "debug.h"
48  
49 + // Emulation time statistics
50 + #define EMUL_TIME_STATS 1
51 +
52 + #if EMUL_TIME_STATS
53 + static clock_t emul_start_time;
54 + static uint32 interrupt_count = 0;
55 + static clock_t interrupt_time = 0;
56 + static uint32 exec68k_count = 0;
57 + static clock_t exec68k_time = 0;
58 + static uint32 native_exec_count = 0;
59 + static clock_t native_exec_time = 0;
60 + static uint32 macos_exec_count = 0;
61 + static clock_t macos_exec_time = 0;
62 + #endif
63 +
64   static void enter_mon(void)
65   {
66          // Start up mon in real-mode
# Line 79 | Line 93 | static KernelData * const kernel_data =
93   *              PowerPC emulator glue with special 'sheep' opcodes
94   **/
95  
82 struct sheepshaver_exec_return { };
83
96   class sheepshaver_cpu
97          : public powerpc_cpu
98   {
# Line 115 | Line 127 | public:
127          void interrupt(uint32 entry);
128          void handle_interrupt();
129  
118        // spcflags for interrupts handling
119        static uint32 spcflags;
120
130          // Lazy memory allocator (one item at a time)
131          void *operator new(size_t size)
132                  { return allocator_helper< sheepshaver_cpu, lazy_allocator >::allocate(); }
# Line 128 | Line 137 | public:
137          void operator delete[](void *p);
138   };
139  
131 uint32 sheepshaver_cpu::spcflags = 0;
140   lazy_allocator< sheepshaver_cpu > allocator_helper< sheepshaver_cpu, lazy_allocator >::allocator;
141  
142   sheepshaver_cpu::sheepshaver_cpu()
# Line 148 | Line 156 | void sheepshaver_cpu::init_decoder()
156  
157          static const instr_info_t sheep_ii_table[] = {
158                  { "sheep",
159 <                  (execute_fn)&sheepshaver_cpu::execute_sheep,
159 >                  (execute_pmf)&sheepshaver_cpu::execute_sheep,
160                    NULL,
161                    D_form, 6, 0, CFLOW_JUMP | CFLOW_TRAP
162                  }
# Line 189 | Line 197 | void sheepshaver_cpu::execute_sheep(uint
197                  break;
198  
199          case 1:         // EXEC_RETURN
200 <                throw sheepshaver_exec_return();
200 >                spcflags().set(SPCFLAG_CPU_EXEC_RETURN);
201                  break;
202  
203          case 2:         // EXEC_NATIVE
# Line 225 | Line 233 | void sheepshaver_cpu::execute_sheep(uint
233   // Execution loop
234   void sheepshaver_cpu::execute(uint32 entry, bool enable_cache)
235   {
236 <        try {
229 <                powerpc_cpu::execute(entry, enable_cache);
230 <        }
231 <        catch (sheepshaver_exec_return const &) {
232 <                // Nothing, simply return
233 <        }
234 <        catch (...) {
235 <                printf("ERROR: execute() received an unknown exception!\n");
236 <                QuitEmulator();
237 <        }
236 >        powerpc_cpu::execute(entry, enable_cache);
237   }
238  
239   // Handle MacOS interrupt
240   void sheepshaver_cpu::interrupt(uint32 entry)
241   {
242 + #if EMUL_TIME_STATS
243 +        interrupt_count++;
244 +        const clock_t interrupt_start = clock();
245 + #endif
246 +
247   #if !MULTICORE_CPU
248          // Save program counters and branch registers
249          uint32 saved_pc = pc();
# Line 293 | Line 297 | void sheepshaver_cpu::interrupt(uint32 e
297          ctr()= saved_ctr;
298          gpr(1) = saved_sp;
299   #endif
300 +
301 + #if EMUL_TIME_STATS
302 +        interrupt_time += (clock() - interrupt_start);
303 + #endif
304   }
305  
306   // Execute 68k routine
307   void sheepshaver_cpu::execute_68k(uint32 entry, M68kRegisters *r)
308   {
309 + #if EMUL_TIME_STATS
310 +        exec68k_count++;
311 +        const clock_t exec68k_start = clock();
312 + #endif
313 +
314   #if SAFE_EXEC_68K
315          if (ReadMacInt32(XLM_RUN_MODE) != MODE_EMUL_OP)
316                  printf("FATAL: Execute68k() not called from EMUL_OP mode\n");
# Line 380 | Line 393 | void sheepshaver_cpu::execute_68k(uint32
393          lr() = saved_lr;
394          ctr()= saved_ctr;
395          set_cr(saved_cr);
396 +
397 + #if EMUL_TIME_STATS
398 +        exec68k_time += (clock() - exec68k_start);
399 + #endif
400   }
401  
402   // Call MacOS PPC code
403   uint32 sheepshaver_cpu::execute_macos_code(uint32 tvect, int nargs, uint32 const *args)
404   {
405 + #if EMUL_TIME_STATS
406 +        macos_exec_count++;
407 +        const clock_t macos_exec_start = clock();
408 + #endif
409 +
410          // Save program counters and branch registers
411          uint32 saved_pc = pc();
412          uint32 saved_lr = lr();
# Line 423 | Line 445 | uint32 sheepshaver_cpu::execute_macos_co
445          lr() = saved_lr;
446          ctr()= saved_ctr;
447  
448 + #if EMUL_TIME_STATS
449 +        macos_exec_time += (clock() - macos_exec_start);
450 + #endif
451 +
452          return retval;
453   }
454  
# Line 566 | Line 592 | void init_emul_ppc(void)
592          mon_add_command("regs", dump_registers, "regs                     Dump PowerPC registers\n");
593          mon_add_command("log", dump_log, "log                      Dump PowerPC emulation log\n");
594   #endif
595 +
596 + #if EMUL_TIME_STATS
597 +        emul_start_time = clock();
598 + #endif
599 + }
600 +
601 + /*
602 + *  Deinitialize emulation
603 + */
604 +
605 + void exit_emul_ppc(void)
606 + {
607 + #if EMUL_TIME_STATS
608 +        clock_t emul_end_time = clock();
609 +
610 +        printf("### Statistics for SheepShaver emulation parts\n");
611 +        const clock_t emul_time = emul_end_time - emul_start_time;
612 +        printf("Total emulation time : %.1f sec\n", double(emul_time) / double(CLOCKS_PER_SEC));
613 +        printf("Total interrupt count: %d (%2.1f Hz)\n", interrupt_count,
614 +                   (double(interrupt_count) * CLOCKS_PER_SEC) / double(emul_time));
615 +
616 + #define PRINT_STATS(LABEL, VAR_PREFIX) do {                                                             \
617 +                printf("Total " LABEL " count : %d\n", VAR_PREFIX##_count);             \
618 +                printf("Total " LABEL " time  : %.1f sec (%.1f%%)\n",                   \
619 +                           double(VAR_PREFIX##_time) / double(CLOCKS_PER_SEC),          \
620 +                           100.0 * double(VAR_PREFIX##_time) / double(emul_time));      \
621 +        } while (0)
622 +
623 +        PRINT_STATS("Execute68k[Trap] execution", exec68k);
624 +        PRINT_STATS("NativeOp execution", native_exec);
625 +        PRINT_STATS("MacOS routine execution", macos_exec);
626 +
627 + #undef PRINT_STATS
628 +        printf("\n");
629 + #endif
630 +
631 +        delete main_cpu;
632 + #if MULTICORE_CPU
633 +        delete interrupt_cpu;
634 + #endif
635   }
636  
637   /*
# Line 731 | Line 797 | static void r_get_resource(void);
797  
798   static void NativeOp(int selector)
799   {
800 + #if EMUL_TIME_STATS
801 +        native_exec_count++;
802 +        const clock_t native_exec_start = clock();
803 + #endif
804 +
805          switch (selector) {
806          case NATIVE_PATCH_NAME_REGISTRY:
807                  DoPatchNameRegistry();
# Line 794 | Line 865 | static void NativeOp(int selector)
865                  QuitEmulator();
866                  break;
867          }
868 +
869 + #if EMUL_TIME_STATS
870 +        native_exec_time += (clock() - native_exec_start);
871 + #endif
872   }
873  
874   /*

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines