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