* cgen-trace.c (trace_insn): Pass pc to trace_prefix for virtual insns.
[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 = 0;
38 int pre_checksum = 0;
39 int post_checksum = 0;
40
41 /* find optimized gx block that includes this PC */
42 block = sim_gx_block_find(cia);
43 if(block == NULL)
44 {
45 /* start new learning block */
46 block = sim_gx_block_create(cia);
47 sim_gx_write_block_list();
48 }
49 ASSERT(block != NULL);
50
51 /* pick preferred compiled block */
52 if(block->optimized_block != NULL)
53 {
54 compiled_block = block->optimized_block;
55 /* no stats */
56 }
57 else
58 {
59 /* test for optimization policy */
60 if(tgx_optimize_test(block))
61 {
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;
67 }
68 else
69 {
70 compiled_block = block->learning_block;
71 optimized = 0;
72 }
73 }
74 ASSERT(compiled_block != NULL);
75
76 /* load & resolve gx function */
77 f = sim_gx_compiled_block_f(compiled_block);
78
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);
82 */
83
84 /* compute pc_flags checksum */
85 if(! optimized)
86 {
87 int i;
88 pre_checksum = 0;
89 for(i=0; i < block->length / block->divisor; i++)
90 pre_checksum += block->pc_flags[i];
91 }
92
93 /* call into gx function */
94 {
95 struct tgx_info info = {& cpu->regs,
96 block->pc_flags,
97 block->callbacks };
98 rc = (*f)(& info);
99 }
100
101 /* compute pc_flags checksum */
102 if(! optimized)
103 {
104 int i;
105 post_checksum = 0;
106 for(i=0; i < block->length / block->divisor; i++)
107 post_checksum += block->pc_flags[i];
108
109 if(post_checksum != pre_checksum) /* system changing */
110 {
111 block->learn_last_change = time(NULL);
112 }
113 }
114
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);
118 */
119
120 switch(rc)
121 {
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;
126
127 case GX_F_NONPC: /* non-instruction PC in this block */
128 if(compiled_block == block->optimized_block)
129 {
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;
135 }
136 else
137 {
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);
140 }
141 break;
142
143 case GX_F_HALT: /* gx function returning control */
144 cont = 0; /* merely exit loop */
145 break;
146
147 /* should not happen */
148 default:
149 sim_io_error(sd, "Translation error (bad rc 0x%d in gx block)", rc);
150 /* NOTREACHED */
151 }
152
153 if(sim_events_tick(sd))
154 sim_events_process(sd);
155 }
156 }
This page took 0.032422 seconds and 4 git commands to generate.