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