* Personal prototype "gx" translation-based JIT engine for M32R.
[deliverable/binutils-gdb.git] / sim / common / sim-gx-run.c
1 /* GX generic simulator run.
2 Copyright (C) 1998 Cygnus Solutions.
3 */
4
5 #include "sim-main.h"
6 #include "sim-assert.h"
7 #include "sim-gx.h"
8
9 #ifdef HAVE_TIME_H
10 #include <time.h>
11 #endif
12
13
14 /* GX implementation of sim_engine_run that works within the
15 sim_engine setjmp/longjmp framework. */
16
17
18 void
19 sim_engine_run (SIM_DESC sd,
20 int next_cpu_nr,
21 int nr_cpus, /* ignore */
22 int siggnal) /* ignore */
23 {
24 sim_cpu* cpu;
25 int cont = 1;
26 int rc;
27
28 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
29 cpu = STATE_CPU (sd, next_cpu_nr);
30
31 while(cont)
32 {
33 sim_gx_block* block;
34 sim_gx_compiled_block* compiled_block;
35 sim_gx_function f;
36 sim_cia cia = CIA_GET(cpu);
37 int optimized;
38 int pre_checksum, post_checksum;
39
40 /* find optimized gx block that includes this PC */
41 block = sim_gx_block_find(cia);
42 if(block == NULL)
43 {
44 /* start new learning block */
45 block = sim_gx_block_create(cia);
46 }
47 ASSERT(block != NULL);
48
49 /* pick preferred compiled block */
50 if(block->optimized_block != NULL)
51 {
52 compiled_block = block->optimized_block;
53 /* no stats */
54 }
55 else
56 {
57 /* test for optimization policy */
58 if(tgx_optimize_test(block))
59 {
60 block->opt_compile_count ++;
61 sim_gx_block_translate(block, 1 /* optimized */);
62 compiled_block = block->optimized_block;
63 optimized = 1;
64 }
65 else
66 {
67 compiled_block = block->learning_block;
68 optimized = 0;
69 }
70 }
71 ASSERT(compiled_block != NULL);
72
73 /* load & resolve gx function */
74 f = sim_gx_compiled_block_f(compiled_block);
75
76 /* XXX: debug
77 printf("calling into gx function %p, pc=%08lx, opt %d\n",
78 (void*) f, (unsigned long) cpu->regs.h_pc, optimized);
79 */
80
81 /* compute pc_flags checksum */
82 if(! optimized)
83 {
84 int i;
85 pre_checksum = 0;
86 for(i=0; i < block->length / block->divisor; i++)
87 pre_checksum += block->pc_flags[i];
88 }
89
90 /* call into gx function */
91 rc = (*f)(& cpu->regs, block->pc_flags, block->callbacks);
92
93 /* compute pc_flags checksum */
94 if(! optimized)
95 {
96 int i;
97 post_checksum = 0;
98 for(i=0; i < block->length / block->divisor; i++)
99 post_checksum += block->pc_flags[i];
100
101 if(post_checksum != pre_checksum) /* system changing */
102 {
103 block->learn_last_change = time(NULL);
104 }
105 }
106
107 /* XXX: debug
108 printf("returned from gx function %p, rc=%d, pc=%08lx\n",
109 (void*) f, rc, (unsigned long) cpu->regs.h_pc);
110 */
111
112 switch(rc)
113 {
114 case GX_F_YIELD: /* gx block voluntarily gave up control */
115 case GX_F_RANGE: /* PC travelled outside this block */
116 ; /* continue block dispatch loop */
117 break;
118
119 case GX_F_NONPC: /* non-instruction PC in this block */
120 if(compiled_block == block->optimized_block)
121 {
122 /* sim_io_printf(sd, "NOTE: cancelling premature optimization, GX block %p, PC %08lx\n",
123 block, (long) cpu->regs.h_pc); */
124 sim_gx_compiled_block_dispose(compiled_block);
125 block->learn_last_change = time(NULL);
126 block->optimized_block = NULL;
127 }
128 else
129 {
130 /* learning-mode gx block should not fail this way */
131 sim_io_error(sd, "Internal error - GX block cia %08lx NONPC\n", (long) cia);
132 }
133 break;
134
135 case GX_F_HALT: /* gx function returning control */
136 cont = 0; /* merely exit loop */
137 break;
138
139 /* should not happen */
140 default:
141 sim_io_error(sd, "Translation error (bad rc 0x%d in gx block)", rc);
142 /* NOTREACHED */
143 }
144
145 if(sim_events_tick(sd))
146 sim_events_process(sd);
147 }
148 }
This page took 0.032169 seconds and 4 git commands to generate.