]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/gen-engine.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / sim / igen / gen-engine.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
6aba47ca 3 Copyright 2002, 2007 Free Software Foundation, Inc.
feaee4bd
AC
4
5 Contributed by Andrew Cagney.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
c906108c
SS
23
24#include "misc.h"
25#include "lf.h"
26#include "table.h"
27#include "filter.h"
28
29#include "igen.h"
30
31#include "ld-insn.h"
32#include "ld-decode.h"
33
34#include "gen.h"
35
36#include "gen-idecode.h"
37#include "gen-engine.h"
38#include "gen-icache.h"
39#include "gen-semantics.h"
40
41
42static void
43print_engine_issue_prefix_hook (lf *file)
44{
45 lf_printf (file, "\n");
46 lf_indent_suppress (file);
ac835424
CD
47 lf_printf (file, "#if defined (ENGINE_ISSUE_PREFIX_HOOK)\n");
48 lf_printf (file, "ENGINE_ISSUE_PREFIX_HOOK();\n");
c906108c
SS
49 lf_indent_suppress (file);
50 lf_printf (file, "#endif\n");
51 lf_printf (file, "\n");
52}
53
54static void
55print_engine_issue_postfix_hook (lf *file)
56{
57 lf_printf (file, "\n");
58 lf_indent_suppress (file);
ac835424
CD
59 lf_printf (file, "#if defined (ENGINE_ISSUE_POSTFIX_HOOK)\n");
60 lf_printf (file, "ENGINE_ISSUE_POSTFIX_HOOK();\n");
c906108c
SS
61 lf_indent_suppress (file);
62 lf_printf (file, "#endif\n");
63 lf_printf (file, "\n");
64}
65
66
67static void
4e0bf4c4 68print_run_body (lf *file, gen_entry *table)
c906108c
SS
69{
70 /* Output the function to execute real code:
4e0bf4c4 71
c906108c 72 Unfortunatly, there are multiple cases to consider vis:
4e0bf4c4 73
c906108c 74 <icache> X <smp>
4e0bf4c4 75
c906108c 76 Consequently this function is written in multiple different ways */
4e0bf4c4 77
c906108c
SS
78 lf_printf (file, "{\n");
79 lf_indent (file, +2);
80 if (!options.gen.smp)
81 {
4e0bf4c4
AC
82 lf_printf (file, "%sinstruction_address cia;\n",
83 options.module.global.prefix.l);
c906108c
SS
84 }
85 lf_printf (file, "int current_cpu = next_cpu_nr;\n");
4e0bf4c4 86
c906108c
SS
87 if (options.gen.icache)
88 {
89 lf_printf (file, "/* flush the icache of a possible break insn */\n");
90 lf_printf (file, "{\n");
91 lf_printf (file, " int cpu_nr;\n");
92 lf_printf (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
93 lf_printf (file, " cpu_flush_icache (STATE_CPU (sd, cpu_nr));\n");
94 lf_printf (file, "}\n");
95 }
4e0bf4c4 96
c906108c
SS
97 if (!options.gen.smp)
98 {
4e0bf4c4 99
4e62efb8
RH
100 lf_putstr (file, "\
101/* CASE 1: NO SMP (with or with out instruction cache).\n\
102\n\
103In this case, we can take advantage of the fact that the current\n\
104instruction address (CIA) does not need to be read from / written to\n\
105the CPU object after the execution of an instruction.\n\
106\n\
107Instead, CIA is only saved when the main loop exits. This occures\n\
108when either sim_engine_halt or sim_engine_restart is called. Both of\n\
109these functions save the current instruction address before halting /\n\
110restarting the simulator.\n\
111\n\
112As a variation, there may also be support for an instruction cracking\n\
113cache. */\n\
114\n\
c906108c
SS
115");
116
117 lf_putstr (file, "\n");
118 lf_putstr (file, "/* prime the main loop */\n");
119 lf_putstr (file, "SIM_ASSERT (current_cpu == 0);\n");
120 lf_putstr (file, "SIM_ASSERT (nr_cpus == 1);\n");
121 lf_putstr (file, "cia = CIA_GET (CPU);\n");
122
123 lf_putstr (file, "\n");
124 lf_putstr (file, "while (1)\n");
125 lf_putstr (file, " {\n");
126 lf_indent (file, +4);
4e0bf4c4 127
c906108c
SS
128 lf_printf (file, "%sinstruction_address nia;\n",
129 options.module.global.prefix.l);
130
131 lf_printf (file, "\n");
132 if (!options.gen.icache)
133 {
4e0bf4c4
AC
134 lf_printf (file,
135 "%sinstruction_word instruction_0 = IMEM%d (cia);\n",
136 options.module.global.prefix.l, options.insn_bit_size);
c906108c
SS
137 print_engine_issue_prefix_hook (file);
138 print_idecode_body (file, table, "nia = ");
139 print_engine_issue_postfix_hook (file);
140 }
141 else
142 {
143 lf_putstr (file, "idecode_cache *cache_entry =\n");
144 lf_putstr (file, " cpu_icache_entry (cpu, cia);\n");
145 lf_putstr (file, "if (cache_entry->address == cia)\n");
146 lf_putstr (file, " {\n");
147 lf_indent (file, -4);
148 lf_putstr (file, "/* cache hit */\n");
4e0bf4c4
AC
149 lf_putstr (file,
150 "idecode_semantic *const semantic = cache_entry->semantic;\n");
c906108c
SS
151 lf_putstr (file, "cia = semantic (cpu, cache_entry, cia);\n");
152 /* tail */
153 lf_indent (file, -4);
154 lf_putstr (file, " }\n");
155 lf_putstr (file, "else\n");
156 lf_putstr (file, " {\n");
157 lf_indent (file, +4);
158 lf_putstr (file, "/* cache miss */\n");
159 if (!options.gen.semantic_icache)
160 {
161 lf_putstr (file, "idecode_semantic *semantic;\n");
162 }
163 lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n",
164 options.insn_bit_size);
165 lf_putstr (file, "if (WITH_MON != 0)\n");
4e0bf4c4
AC
166 lf_putstr (file,
167 " mon_event (mon_event_icache_miss, cpu, cia);\n");
c906108c
SS
168 if (options.gen.semantic_icache)
169 {
170 lf_putstr (file, "{\n");
171 lf_indent (file, +2);
172 print_engine_issue_prefix_hook (file);
173 print_idecode_body (file, table, "nia =");
174 print_engine_issue_postfix_hook (file);
175 lf_indent (file, -2);
176 lf_putstr (file, "}\n");
177 }
178 else
179 {
180 print_engine_issue_prefix_hook (file);
181 print_idecode_body (file, table, "semantic =");
182 lf_putstr (file, "nia = semantic (cpu, cache_entry, cia);\n");
183 print_engine_issue_postfix_hook (file);
184 }
185 lf_indent (file, -4);
186 lf_putstr (file, " }\n");
187 }
4e0bf4c4 188
c906108c
SS
189 /* update the cpu if necessary */
190 switch (options.gen.nia)
191 {
192 case nia_is_cia_plus_one:
193 lf_printf (file, "\n");
194 lf_printf (file, "/* Update the instruction address */\n");
195 lf_printf (file, "cia = nia;\n");
196 break;
197 case nia_is_void:
198 case nia_is_invalid:
199 ERROR ("engine gen when NIA complex");
200 }
201
202 /* events */
203 lf_putstr (file, "\n");
204 lf_putstr (file, "/* process any events */\n");
205 lf_putstr (file, "if (sim_events_tick (sd))\n");
206 lf_putstr (file, " {\n");
207 lf_putstr (file, " CIA_SET (CPU, cia);\n");
208 lf_putstr (file, " sim_events_process (sd);\n");
209 lf_putstr (file, " cia = CIA_GET (CPU);\n");
210 lf_putstr (file, " }\n");
211
212 lf_indent (file, -4);
213 lf_printf (file, " }\n");
214 }
4e0bf4c4 215
c906108c
SS
216 if (options.gen.smp)
217 {
4e0bf4c4 218
4e62efb8
RH
219 lf_putstr (file, "\
220/* CASE 2: SMP (With or without ICACHE)\n\
221\n\
222The complexity here comes from needing to correctly halt the simulator\n\
223when it is aborted. For instance, if cpu0 requests a restart then\n\
224cpu1 will normally be the next cpu that is run. Cpu0 being restarted\n\
225after all the other CPU's and the event queue have been processed */\n\
226\n\
c906108c 227");
4e0bf4c4 228
c906108c 229 lf_putstr (file, "\n");
4e0bf4c4
AC
230 lf_printf (file,
231 "/* have ensured that the event queue is NOT next */\n");
c906108c
SS
232 lf_printf (file, "SIM_ASSERT (current_cpu >= 0);\n");
233 lf_printf (file, "SIM_ASSERT (current_cpu <= nr_cpus - 1);\n");
234 lf_printf (file, "SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);\n");
235
236 lf_putstr (file, "\n");
237 lf_putstr (file, "while (1)\n");
238 lf_putstr (file, " {\n");
239 lf_indent (file, +4);
240 lf_putstr (file, "sim_cpu *cpu = STATE_CPU (sd, current_cpu);\n");
241 lf_putstr (file, "instruction_address cia = CIA_GET (cpu);\n");
242 lf_putstr (file, "\n");
243
244 if (!options.gen.icache)
245 {
246 lf_printf (file, "instruction_word instruction_0 = IMEM%d (cia);\n",
247 options.insn_bit_size);
248 print_engine_issue_prefix_hook (file);
249 print_idecode_body (file, table, "cia =");
250 lf_putstr (file, "CIA_SET (cpu, cia);\n");
251 print_engine_issue_postfix_hook (file);
252 }
4e0bf4c4 253
c906108c
SS
254 if (options.gen.icache)
255 {
256 lf_putstr (file, "engine_cache *cache_entry =\n");
257 lf_putstr (file, " cpu_icache_entry(processor, cia);\n");
258 lf_putstr (file, "\n");
259 lf_putstr (file, "if (cache_entry->address == cia) {\n");
260 {
261 lf_indent (file, +2);
262 lf_putstr (file, "\n");
263 lf_putstr (file, "/* cache hit */\n");
4e0bf4c4
AC
264 lf_putstr (file,
265 "engine_semantic *semantic = cache_entry->semantic;\n");
266 lf_putstr (file,
267 "cia = semantic(processor, cache_entry, cia);\n");
c906108c
SS
268 /* tail */
269 lf_putstr (file, "cpu_set_program_counter(processor, cia);\n");
270 lf_putstr (file, "\n");
271 lf_indent (file, -2);
272 }
273 lf_putstr (file, "}\n");
274 lf_putstr (file, "else {\n");
275 {
276 lf_indent (file, +2);
277 lf_putstr (file, "\n");
278 lf_putstr (file, "/* cache miss */\n");
279 if (!options.gen.semantic_icache)
280 {
281 lf_putstr (file, "engine_semantic *semantic;\n");
282 }
283 lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n",
284 options.insn_bit_size);
285 lf_putstr (file, "if (WITH_MON != 0)\n");
4e0bf4c4
AC
286 lf_putstr (file,
287 " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
c906108c
SS
288 if (options.gen.semantic_icache)
289 {
290 lf_putstr (file, "{\n");
291 lf_indent (file, +2);
292 print_engine_issue_prefix_hook (file);
4e0bf4c4 293 print_idecode_body (file, table, "cia =");
c906108c
SS
294 print_engine_issue_postfix_hook (file);
295 lf_indent (file, -2);
296 lf_putstr (file, "}\n");
297 }
298 else
299 {
300 print_engine_issue_prefix_hook (file);
4e0bf4c4
AC
301 print_idecode_body (file, table, "semantic = ");
302 lf_putstr (file,
303 "cia = semantic(processor, cache_entry, cia);\n");
c906108c
SS
304 print_engine_issue_postfix_hook (file);
305 }
306 /* tail */
307 lf_putstr (file, "cpu_set_program_counter(processor, cia);\n");
308 lf_putstr (file, "\n");
309 lf_indent (file, -2);
310 }
311 lf_putstr (file, "}\n");
312 }
4e0bf4c4 313
c906108c
SS
314 lf_putstr (file, "\n");
315 lf_putstr (file, "current_cpu += 1;\n");
316 lf_putstr (file, "if (current_cpu == nr_cpus)\n");
317 lf_putstr (file, " {\n");
318 lf_putstr (file, " if (sim_events_tick (sd))\n");
319 lf_putstr (file, " {\n");
320 lf_putstr (file, " sim_events_process (sd);\n");
321 lf_putstr (file, " }\n");
322 lf_putstr (file, " current_cpu = 0;\n");
323 lf_putstr (file, " }\n");
4e0bf4c4 324
c906108c
SS
325 /* tail */
326 lf_indent (file, -4);
327 lf_putstr (file, " }\n");
328 }
4e0bf4c4
AC
329
330
c906108c
SS
331 lf_indent (file, -2);
332 lf_putstr (file, "}\n");
333}
334
335
336/****************************************************************/
337
338#if 0
339static void
4e0bf4c4 340print_jump (lf *file, int is_tail)
c906108c
SS
341{
342 if (!options.gen.smp)
343 {
344 lf_putstr (file, "if (event_queue_tick (sd))\n");
345 lf_putstr (file, " {\n");
346 lf_putstr (file, " CPU_CIA (processor) = nia;\n");
347 lf_putstr (file, " sim_events_process (sd);\n");
348 lf_putstr (file, " }\n");
349 lf_putstr (file, "}\n");
350 }
4e0bf4c4 351
c906108c
SS
352 if (options.gen.smp)
353 {
354 if (is_tail)
355 lf_putstr (file, "cpu_set_program_counter(processor, nia);\n");
356 lf_putstr (file, "current_cpu += 1;\n");
357 lf_putstr (file, "if (current_cpu >= nr_cpus)\n");
358 lf_putstr (file, " {\n");
359 lf_putstr (file, " if (sim_events_tick (sd))\n");
360 lf_putstr (file, " {\n");
361 lf_putstr (file, " sim_events_process (sd);\n");
362 lf_putstr (file, " }\n");
363 lf_putstr (file, " current_cpu = 0;\n");
364 lf_putstr (file, " }\n");
365 lf_putstr (file, "processor = processors[current_cpu];\n");
366 lf_putstr (file, "nia = cpu_get_program_counter(processor);\n");
367 }
4e0bf4c4 368
c906108c
SS
369 if (options.gen.icache)
370 {
371 lf_putstr (file, "cache_entry = cpu_icache_entry(processor, nia);\n");
372 lf_putstr (file, "if (cache_entry->address == nia) {\n");
373 lf_putstr (file, " /* cache hit */\n");
374 lf_putstr (file, " goto *cache_entry->semantic;\n");
375 lf_putstr (file, "}\n");
4e0bf4c4
AC
376 if (is_tail)
377 {
378 lf_putstr (file, "goto cache_miss;\n");
379 }
c906108c 380 }
4e0bf4c4 381
c906108c
SS
382 if (!options.gen.icache && is_tail)
383 {
384 lf_printf (file, "goto engine;\n");
385 }
4e0bf4c4 386
c906108c
SS
387}
388#endif
389
390
391#if 0
392static void
393print_jump_insn (lf *file,
4e0bf4c4 394 insn_entry * instruction,
c906108c 395 opcode_bits *expanded_bits,
4e0bf4c4 396 opcode_field *opcodes, cache_entry *cache_rules)
c906108c
SS
397{
398 insn_opcodes opcode_path;
399
400 memset (&opcode_path, 0, sizeof (opcode_path));
401 opcode_path.opcode = opcodes;
402
403 /* what we are for the moment */
404 lf_printf (file, "\n");
405 print_my_defines (file,
406 instruction->name,
4e0bf4c4
AC
407 instruction->format_name, expanded_bits);
408
c906108c
SS
409 /* output the icache entry */
410 if (options.gen.icache)
411 {
412 lf_printf (file, "\n");
413 lf_indent (file, -1);
414 print_function_name (file,
415 instruction->name,
416 instruction->format_name,
4e0bf4c4 417 NULL, expanded_bits, function_name_prefix_icache);
c906108c
SS
418 lf_printf (file, ":\n");
419 lf_indent (file, +1);
420 lf_printf (file, "{\n");
421 lf_indent (file, +2);
422 lf_putstr (file, "const unsigned_word cia = nia;\n");
4e0bf4c4 423 print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
c906108c
SS
424 print_idecode_validate (file, instruction, &opcode_path);
425 lf_printf (file, "\n");
426 lf_printf (file, "{\n");
427 lf_indent (file, +2);
4e0bf4c4 428 print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */
c906108c
SS
429 put_values_in_icache);
430 lf_printf (file, "cache_entry->address = nia;\n");
431 lf_printf (file, "cache_entry->semantic = &&");
432 print_function_name (file,
433 instruction->name,
434 instruction->format_name,
435 NULL,
4e0bf4c4 436 expanded_bits, function_name_prefix_semantics);
c906108c
SS
437 lf_printf (file, ";\n");
438 if (options.gen.semantic_icache)
439 {
440 print_semantic_body (file,
4e0bf4c4
AC
441 instruction, expanded_bits, &opcode_path);
442 print_jump (file, 1 /*is-tail */ );
c906108c
SS
443 }
444 else
445 {
446 lf_printf (file, "/* goto ");
447 print_function_name (file,
448 instruction->name,
449 instruction->format_name,
450 NULL,
4e0bf4c4 451 expanded_bits, function_name_prefix_semantics);
c906108c
SS
452 lf_printf (file, "; */\n");
453 }
454 lf_indent (file, -2);
455 lf_putstr (file, "}\n");
456 lf_indent (file, -2);
457 lf_printf (file, "}\n");
458 }
4e0bf4c4 459
c906108c
SS
460 /* print the semantics */
461 lf_printf (file, "\n");
462 lf_indent (file, -1);
463 print_function_name (file,
464 instruction->name,
465 instruction->format_name,
4e0bf4c4 466 NULL, expanded_bits, function_name_prefix_semantics);
c906108c
SS
467 lf_printf (file, ":\n");
468 lf_indent (file, +1);
469 lf_printf (file, "{\n");
470 lf_indent (file, +2);
471 lf_putstr (file, "const unsigned_word cia = nia;\n");
472 print_icache_body (file,
473 instruction,
474 expanded_bits,
475 cache_rules,
476 (options.gen.direct_access
477 ? define_variables
478 : declare_variables),
479 (options.gen.icache
4e0bf4c4
AC
480 ? get_values_from_icache : do_not_use_icache));
481 print_semantic_body (file, instruction, expanded_bits, &opcode_path);
c906108c
SS
482 if (options.gen.direct_access)
483 print_icache_body (file,
484 instruction,
485 expanded_bits,
486 cache_rules,
487 undef_variables,
488 (options.gen.icache
4e0bf4c4
AC
489 ? get_values_from_icache : do_not_use_icache));
490 print_jump (file, 1 /*is tail */ );
c906108c
SS
491 lf_indent (file, -2);
492 lf_printf (file, "}\n");
493}
494#endif
495
496
497#if 0
498static void
4e0bf4c4 499print_jump_definition (lf *file, gen_entry *entry, int depth, void *data)
c906108c 500{
4e0bf4c4 501 cache_entry *cache_rules = (cache_entry *) data;
c906108c
SS
502 if (entry->opcode_rule->with_duplicates)
503 {
504 ASSERT (entry->nr_insns == 1
505 && entry->opcode == NULL
4e0bf4c4 506 && entry->parent != NULL && entry->parent->opcode != NULL);
c906108c
SS
507 ASSERT (entry->nr_insns == 1
508 && entry->opcode == NULL
509 && entry->parent != NULL
510 && entry->parent->opcode != NULL
511 && entry->parent->opcode_rule != NULL);
512 print_jump_insn (file,
513 entry->insns->insn,
4e0bf4c4 514 entry->expanded_bits, entry->opcode, cache_rules);
c906108c 515 }
4e0bf4c4 516 else
c906108c 517 {
4e0bf4c4 518 print_jump_insn (file, entry->insns->insn, NULL, NULL, cache_rules);
c906108c
SS
519 }
520}
521#endif
522
523
524#if 0
525static void
4e0bf4c4 526print_jump_internal_function (lf *file, function_entry * function, void *data)
c906108c
SS
527{
528 if (function->is_internal)
529 {
530 lf_printf (file, "\n");
531 lf_print__line_ref (file, function->line);
532 lf_indent (file, -1);
533 print_function_name (file,
534 function->name,
535 NULL,
536 NULL,
537 NULL,
538 (options.gen.icache
539 ? function_name_prefix_icache
540 : function_name_prefix_semantics));
541 lf_printf (file, ":\n");
542 lf_indent (file, +1);
543 lf_printf (file, "{\n");
544 lf_indent (file, +2);
545 lf_printf (file, "const unsigned_word cia = nia;\n");
546 table_print_code (file, function->code);
547 lf_print__internal_ref (file);
548 lf_printf (file, "error(\"Internal function must longjump\\n\");\n");
549 lf_indent (file, -2);
550 lf_printf (file, "}\n");
551 }
552}
553#endif
554
555
556#if 0
557static void
558print_jump_body (lf *file,
4e0bf4c4 559 gen_entry *entry, insn_table *isa, cache_entry *cache_rules)
c906108c
SS
560{
561 lf_printf (file, "{\n");
562 lf_indent (file, +2);
563 lf_putstr (file, "jmp_buf halt;\n");
564 lf_putstr (file, "jmp_buf restart;\n");
565 lf_putstr (file, "cpu *processor = NULL;\n");
566 lf_putstr (file, "unsigned_word nia = -1;\n");
567 lf_putstr (file, "instruction_word instruction = 0;\n");
568 if (options.gen.icache)
569 {
570 lf_putstr (file, "engine_cache *cache_entry = NULL;\n");
571 }
572 if (options.gen.smp)
573 {
574 lf_putstr (file, "int current_cpu = -1;\n");
575 }
4e0bf4c4 576
c906108c
SS
577 /* all the switches and tables - they know about jumping */
578 print_idecode_lookups (file, entry, cache_rules);
4e0bf4c4 579
c906108c
SS
580 /* start the simulation up */
581 if (options.gen.icache)
582 {
583 lf_putstr (file, "\n");
584 lf_putstr (file, "{\n");
585 lf_putstr (file, " int cpu_nr;\n");
586 lf_putstr (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
587 lf_putstr (file, " cpu_flush_icache(processors[cpu_nr]);\n");
588 lf_putstr (file, "}\n");
589 }
4e0bf4c4 590
c906108c
SS
591 lf_putstr (file, "\n");
592 lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
4e0bf4c4 593
c906108c
SS
594 lf_putstr (file, "\n");
595 lf_putstr (file, "if (setjmp(halt))\n");
596 lf_putstr (file, " return;\n");
4e0bf4c4 597
c906108c
SS
598 lf_putstr (file, "\n");
599 lf_putstr (file, "setjmp(restart);\n");
4e0bf4c4 600
c906108c
SS
601 lf_putstr (file, "\n");
602 if (!options.gen.smp)
603 {
604 lf_putstr (file, "processor = processors[0];\n");
605 lf_putstr (file, "nia = cpu_get_program_counter(processor);\n");
606 }
607 else
608 {
609 lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
610 }
4e0bf4c4 611
c906108c
SS
612 if (!options.gen.icache)
613 {
614 lf_printf (file, "\n");
615 lf_indent (file, -1);
616 lf_printf (file, "engine:\n");
617 lf_indent (file, +1);
618 }
4e0bf4c4
AC
619
620 print_jump (file, 0 /*is_tail */ );
621
c906108c
SS
622 if (options.gen.icache)
623 {
624 lf_indent (file, -1);
625 lf_printf (file, "cache_miss:\n");
626 lf_indent (file, +1);
627 }
4e0bf4c4
AC
628
629 print_engine_issue_prefix_hook (file);
c906108c 630 lf_putstr (file, "instruction\n");
4e0bf4c4
AC
631 lf_putstr (file,
632 " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
c906108c
SS
633 lf_putstr (file, " processor, nia);\n");
634 print_engine_issue_prefix_hook (file);
635 print_idecode_body (file, entry, "/*IGORE*/");
636 print_engine_issue_postfix_hook (file);
4e0bf4c4 637
c906108c
SS
638 /* print out a table of all the internals functions */
639 function_entry_traverse (file, isa->functions,
4e0bf4c4
AC
640 print_jump_internal_function, NULL);
641
c906108c
SS
642 /* print out a table of all the instructions */
643 ERROR ("Use the list of semantic functions, not travere_tree");
4e0bf4c4
AC
644 gen_entry_traverse_tree (file, entry, 1, NULL, /* start */
645 print_jump_definition, /* leaf */
646 NULL, /* end */
c906108c
SS
647 cache_rules);
648 lf_indent (file, -2);
649 lf_printf (file, "}\n");
650}
651#endif
652
653
654/****************************************************************/
655
656
657void
658print_engine_run_function_header (lf *file,
659 char *processor,
660 function_decl_type decl_type)
661{
662 int indent;
663 lf_printf (file, "\n");
664 switch (decl_type)
665 {
666 case is_function_declaration:
667 lf_print__function_type (file, "void", "INLINE_ENGINE", "\n");
668 break;
669 case is_function_definition:
670 lf_print__function_type (file, "void", "INLINE_ENGINE", " ");
671 break;
672 case is_function_variable:
673 lf_printf (file, "void (*");
674 break;
675 }
4e0bf4c4
AC
676 indent = print_function_name (file, "run", NULL, /* format name */
677 processor, NULL, /* expanded bits */
c906108c
SS
678 function_name_prefix_engine);
679 switch (decl_type)
680 {
681 case is_function_definition:
682 lf_putstr (file, "\n(");
683 indent = 1;
684 break;
685 case is_function_declaration:
686 indent += lf_printf (file, " (");
687 break;
688 case is_function_variable:
689 lf_putstr (file, ")\n(");
690 indent = 1;
691 break;
692 }
693 lf_indent (file, +indent);
694 lf_printf (file, "SIM_DESC sd,\n");
695 lf_printf (file, "int next_cpu_nr,\n");
696 lf_printf (file, "int nr_cpus,\n");
697 lf_printf (file, "int siggnal)");
698 lf_indent (file, -indent);
699 switch (decl_type)
700 {
701 case is_function_definition:
702 lf_putstr (file, "\n");
703 break;
704 case is_function_variable:
705 case is_function_declaration:
706 lf_putstr (file, ";\n");
707 break;
708 }
709}
710
711
712void
713gen_engine_h (lf *file,
4e0bf4c4 714 gen_table *gen, insn_table *isa, cache_entry *cache_rules)
c906108c
SS
715{
716 gen_list *entry;
717 for (entry = gen->tables; entry != NULL; entry = entry->next)
718 {
719 print_engine_run_function_header (file,
720 (options.gen.multi_sim
721 ? entry->model->name
4e0bf4c4 722 : NULL), is_function_declaration);
c906108c
SS
723 }
724}
725
726
727void
4e0bf4c4
AC
728gen_engine_c (lf *file,
729 gen_table *gen, insn_table *isa, cache_entry *cache_rules)
c906108c
SS
730{
731 gen_list *entry;
732 /* the intro */
733 print_includes (file);
734 print_include_inline (file, options.module.semantics);
735 print_include (file, options.module.engine);
736 lf_printf (file, "\n");
737 lf_printf (file, "#include \"sim-assert.h\"\n");
738 lf_printf (file, "\n");
739 print_idecode_globals (file);
740 lf_printf (file, "\n");
741
742 for (entry = gen->tables; entry != NULL; entry = entry->next)
743 {
744 switch (options.gen.code)
745 {
746 case generate_calls:
747 print_idecode_lookups (file, entry->table, cache_rules);
4e0bf4c4 748
c906108c
SS
749 /* output the main engine routine */
750 print_engine_run_function_header (file,
751 (options.gen.multi_sim
752 ? entry->model->name
4e0bf4c4 753 : NULL), is_function_definition);
c906108c
SS
754 print_run_body (file, entry->table);
755 break;
4e0bf4c4 756
c906108c
SS
757 case generate_jumps:
758 ERROR ("Jumps currently unimplemented");
759#if 0
760 print_engine_run_function_header (file,
761 entry->processor,
762 is_function_definition);
4e0bf4c4 763 print_jump_body (file, entry->table, isa, cache_rules);
c906108c
SS
764#endif
765 break;
766 }
767 }
768}