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