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.36 by gbeauche, 2004-05-12T15:54:23Z vs.
Revision 1.37 by gbeauche, 2004-05-15T17:26:28Z

# Line 38 | Line 38
38   #include "name_registry.h"
39   #include "serial.h"
40   #include "ether.h"
41 + #include "timer.h"
42  
43   #include <stdio.h>
44   #include <stdlib.h>
# Line 101 | Line 102 | const uint32 POWERPC_EXEC_RETURN = POWER
102   // Interrupts in native mode?
103   #define INTERRUPTS_IN_NATIVE_MODE 1
104  
105 + // Enable native EMUL_OPs to be run without a mode switch
106 + #define ENABLE_NATIVE_EMUL_OP 1
107 +
108   // Pointer to Kernel Data
109   static KernelData * const kernel_data = (KernelData *)KERNEL_DATA_BASE;
110  
# Line 129 | Line 133 | class sheepshaver_cpu
133          void init_decoder();
134          void execute_sheep(uint32 opcode);
135  
136 +        // Filter out EMUL_OP routines that only call native code
137 +        bool filter_execute_emul_op(uint32 emul_op);
138 +
139 +        // "Native" EMUL_OP routines
140 +        void execute_emul_op_microseconds();
141 +        void execute_emul_op_idle_time_1();
142 +        void execute_emul_op_idle_time_2();
143 +
144   public:
145  
146          // Constructor
# Line 238 | Line 250 | typedef bit_field< 19, 19 > FN_field;
250   typedef bit_field< 20, 25 > NATIVE_OP_field;
251   typedef bit_field< 26, 31 > EMUL_OP_field;
252  
253 + // "Native" EMUL_OP routines
254 + #define GPR_A(REG) gpr(16 + (REG))
255 + #define GPR_D(REG) gpr( 8 + (REG))
256 +
257 + void sheepshaver_cpu::execute_emul_op_microseconds()
258 + {
259 +        Microseconds(GPR_A(0), GPR_D(0));
260 + }
261 +
262 + void sheepshaver_cpu::execute_emul_op_idle_time_1()
263 + {
264 +        // Sleep if no events pending
265 +        if (ReadMacInt32(0x14c) == 0)
266 +                Delay_usec(16667);
267 +        GPR_A(0) = ReadMacInt32(0x2b6);
268 + }
269 +
270 + void sheepshaver_cpu::execute_emul_op_idle_time_2()
271 + {
272 +        // Sleep if no events pending
273 +        if (ReadMacInt32(0x14c) == 0)
274 +                Delay_usec(16667);
275 +        GPR_D(0) = (uint32)-2;
276 + }
277 +
278 + // Filter out EMUL_OP routines that only call native code
279 + bool sheepshaver_cpu::filter_execute_emul_op(uint32 emul_op)
280 + {
281 +        switch (emul_op) {
282 +        case OP_MICROSECONDS:
283 +                execute_emul_op_microseconds();
284 +                return true;
285 +        case OP_IDLE_TIME:
286 +                execute_emul_op_idle_time_1();
287 +                return true;
288 +        case OP_IDLE_TIME_2:
289 +                execute_emul_op_idle_time_2();
290 +                return true;
291 +        }
292 +        return false;
293 + }
294 +
295   // Execute EMUL_OP routine
296   void sheepshaver_cpu::execute_emul_op(uint32 emul_op)
297   {
298 + #if ENABLE_NATIVE_EMUL_OP
299 +        // First, filter out EMUL_OPs that can be executed without a mode switch
300 +        if (filter_execute_emul_op(emul_op))
301 +                return;
302 + #endif
303 +
304          M68kRegisters r68;
305          WriteMacInt32(XLM_68K_R25, gpr(25));
306          WriteMacInt32(XLM_RUN_MODE, MODE_EMUL_OP);
# Line 394 | Line 454 | bool sheepshaver_cpu::compile1(codegen_c
454          }
455  
456          default: {      // EMUL_OP
457 +                uint32 emul_op = EMUL_OP_field::extract(opcode) - 3;
458 + #if ENABLE_NATIVE_EMUL_OP
459 +                typedef void (*emul_op_func_t)(dyngen_cpu_base);
460 +                emul_op_func_t emul_op_func = 0;
461 +                switch (emul_op) {
462 +                case OP_MICROSECONDS:
463 +                        emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_microseconds).ptr();
464 +                        break;
465 +                case OP_IDLE_TIME:
466 +                        emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_idle_time_1).ptr();
467 +                        break;
468 +                case OP_IDLE_TIME_2:
469 +                        emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_idle_time_2).ptr();
470 +                        break;
471 +                }
472 +                if (emul_op_func) {
473 +                        dg.gen_invoke_CPU(emul_op_func);
474 +                        cg_context.done_compile = false;
475 +                        compiled = true;
476 +                        break;
477 +                }
478 + #endif
479                  typedef void (*func_t)(dyngen_cpu_base, uint32);
480                  func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op).ptr();
481 <                dg.gen_invoke_CPU_im(func, EMUL_OP_field::extract(opcode) - 3);
481 >                dg.gen_invoke_CPU_im(func, emul_op);
482                  cg_context.done_compile = false;
483                  compiled = true;
484                  break;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines