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