* gx sim prototype tweaks
[binutils-gdb.git] / sim / common / sim-gx-run.c
blobdeda27ba7e34ecef99f801de5fe5ec5f044994a5
1 /* GX generic simulator run.
2 Copyright (C) 1998 Cygnus Solutions.
3 */
5 #include "sim-main.h"
6 #include "sim-assert.h"
7 #include "sim-gx.h"
9 #ifdef HAVE_TIME_H
10 #include <time.h>
11 #endif
14 /* GX implementation of sim_engine_run that works within the
15 sim_engine setjmp/longjmp framework. */
18 void
19 sim_engine_run (SIM_DESC sd,
20 int next_cpu_nr,
21 int nr_cpus, /* ignore */
22 int siggnal) /* ignore */
24 sim_cpu* cpu;
25 int cont = 1;
26 int rc;
28 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
29 cpu = STATE_CPU (sd, next_cpu_nr);
31 while(cont)
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 = 0;
38 int pre_checksum = 0;
39 int post_checksum = 0;
41 /* find optimized gx block that includes this PC */
42 block = sim_gx_block_find(cia);
43 if(block == NULL)
45 /* start new learning block */
46 block = sim_gx_block_create(cia);
47 sim_gx_write_block_list();
49 ASSERT(block != NULL);
51 /* pick preferred compiled block */
52 if(block->optimized_block != NULL)
54 compiled_block = block->optimized_block;
55 /* no stats */
57 else
59 /* test for optimization policy */
60 if(tgx_optimize_test(block))
62 block->opt_compile_count ++;
63 sim_gx_block_translate(block, 1 /* optimized */);
64 sim_gx_write_block_list();
65 compiled_block = block->optimized_block;
66 optimized = 1;
68 else
70 compiled_block = block->learning_block;
71 optimized = 0;
74 ASSERT(compiled_block != NULL);
76 /* load & resolve gx function */
77 f = sim_gx_compiled_block_f(compiled_block);
79 /* XXX: debug
80 printf("calling into gx function %p, pc=%08lx, opt %d\n",
81 (void*) f, (unsigned long) cpu->regs.h_pc, optimized);
84 /* compute pc_flags checksum */
85 if(! optimized)
87 int i;
88 pre_checksum = 0;
89 for(i=0; i < block->length / block->divisor; i++)
90 pre_checksum += block->pc_flags[i];
93 /* call into gx function */
95 struct tgx_info info = {& cpu->regs,
96 block->pc_flags,
97 block->callbacks };
98 rc = (*f)(& info);
101 /* compute pc_flags checksum */
102 if(! optimized)
104 int i;
105 post_checksum = 0;
106 for(i=0; i < block->length / block->divisor; i++)
107 post_checksum += block->pc_flags[i];
109 if(post_checksum != pre_checksum) /* system changing */
111 block->learn_last_change = time(NULL);
115 /* XXX: debug
116 printf("returned from gx function %p, rc=%d, pc=%08lx\n",
117 (void*) f, rc, (unsigned long) cpu->regs.h_pc);
120 switch(rc)
122 case GX_F_YIELD: /* gx block voluntarily gave up control */
123 case GX_F_RANGE: /* PC travelled outside this block */
124 ; /* continue block dispatch loop */
125 break;
127 case GX_F_NONPC: /* non-instruction PC in this block */
128 if(compiled_block == block->optimized_block)
130 /* sim_io_printf(sd, "NOTE: cancelling premature optimization, GX block %p, PC %08lx\n",
131 block, (long) cpu->regs.h_pc); */
132 sim_gx_compiled_block_dispose(compiled_block);
133 block->learn_last_change = time(NULL);
134 block->optimized_block = NULL;
136 else
138 /* learning-mode gx block should not fail this way */
139 sim_io_error(sd, "Internal error - GX block cia %08lx NONPC\n", (long) cia);
141 break;
143 case GX_F_HALT: /* gx function returning control */
144 cont = 0; /* merely exit loop */
145 break;
147 /* should not happen */
148 default:
149 sim_io_error(sd, "Translation error (bad rc 0x%d in gx block)", rc);
150 /* NOTREACHED */
153 if(sim_events_tick(sd))
154 sim_events_process(sd);