1 /* This file is part of the program psim.
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
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.
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.
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.
29 #include "ld-decode.h"
33 #include "gen-idecode.h"
34 #include "gen-engine.h"
35 #include "gen-icache.h"
36 #include "gen-semantics.h"
40 print_engine_issue_prefix_hook (lf *file)
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");
54 print_engine_issue_postfix_hook (lf *file)
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");
69 print_run_body (lf *file,
72 /* Output the function to execute real code:
74 Unfortunatly, there are multiple cases to consider vis:
78 Consequently this function is written in multiple different ways */
80 lf_printf (file, "{\n");
84 lf_printf (file, "%sinstruction_address cia;\n", options.module.global.prefix.l);
86 lf_printf (file, "int current_cpu = next_cpu_nr;\n");
88 if (options.gen.icache)
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");
102 /* CASE 1: NO SMP (with or with out instruction cache).
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.
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.
113 As a variation, there may also be support for an instruction cracking
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");
124 lf_putstr (file, "\n");
125 lf_putstr (file, "while (1)\n");
126 lf_putstr (file, " {\n");
127 lf_indent (file, +4);
129 lf_printf (file, "%sinstruction_address nia;\n",
130 options.module.global.prefix.l);
132 lf_printf (file, "\n");
133 if (!options.gen.icache)
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);
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");
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)
161 lf_putstr (file, "idecode_semantic *semantic;\n");
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)
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");
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);
184 lf_indent (file, -4);
185 lf_putstr (file, " }\n");
188 /* update the cpu if necessary */
189 switch (options.gen.nia)
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");
198 ERROR ("engine gen when NIA complex");
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");
211 lf_indent (file, -4);
212 lf_printf (file, " }\n");
219 /* CASE 2: SMP (With or without ICACHE)
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 */
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");
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");
242 if (!options.gen.icache)
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);
252 if (options.gen.icache)
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");
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");
265 lf_putstr (file, "cpu_set_program_counter(processor, cia);\n");
266 lf_putstr (file, "\n");
267 lf_indent (file, -2);
269 lf_putstr (file, "}\n");
270 lf_putstr (file, "else {\n");
272 lf_indent (file, +2);
273 lf_putstr (file, "\n");
274 lf_putstr (file, "/* cache miss */\n");
275 if (!options.gen.semantic_icache)
277 lf_putstr (file, "engine_semantic *semantic;\n");
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)
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");
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);
301 lf_putstr (file, "cpu_set_program_counter(processor, cia);\n");
302 lf_putstr (file, "\n");
303 lf_indent (file, -2);
305 lf_putstr (file, "}\n");
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");
320 lf_indent (file, -4);
321 lf_putstr (file, " }\n");
325 lf_indent (file, -2);
326 lf_putstr (file, "}\n");
330 /****************************************************************/
334 print_jump (lf *file,
337 if (!options.gen.smp)
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");
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");
364 if (options.gen.icache)
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");
372 lf_putstr (file, "goto cache_miss;\n");
376 if (!options.gen.icache && is_tail)
378 lf_printf (file, "goto engine;\n");
387 print_jump_insn (lf *file,
388 insn_entry *instruction,
389 opcode_bits *expanded_bits,
390 opcode_field *opcodes,
391 cache_entry *cache_rules)
393 insn_opcodes opcode_path;
395 memset (&opcode_path, 0, sizeof (opcode_path));
396 opcode_path.opcode = opcodes;
398 /* what we are for the moment */
399 lf_printf (file, "\n");
400 print_my_defines (file,
402 instruction->format_name,
405 /* output the icache entry */
406 if (options.gen.icache)
408 lf_printf (file, "\n");
409 lf_indent (file, -1);
410 print_function_name (file,
412 instruction->format_name,
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,
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,
436 instruction->format_name,
439 function_name_prefix_semantics);
440 lf_printf (file, ";\n");
441 if (options.gen.semantic_icache)
443 print_semantic_body (file,
447 print_jump(file, 1/*is-tail*/);
451 lf_printf (file, "/* goto ");
452 print_function_name (file,
454 instruction->format_name,
457 function_name_prefix_semantics);
458 lf_printf (file, "; */\n");
460 lf_indent (file, -2);
461 lf_putstr (file, "}\n");
462 lf_indent (file, -2);
463 lf_printf (file, "}\n");
466 /* print the semantics */
467 lf_printf (file, "\n");
468 lf_indent (file, -1);
469 print_function_name (file,
471 instruction->format_name,
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,
484 (options.gen.direct_access
486 : declare_variables),
488 ? get_values_from_icache
489 : do_not_use_icache));
490 print_semantic_body (file,
494 if (options.gen.direct_access)
495 print_icache_body (file,
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");
512 print_jump_definition (lf *file,
517 cache_entry *cache_rules = (cache_entry*)data;
518 if (entry->opcode_rule->with_duplicates)
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,
531 entry->expanded_bits,
537 print_jump_insn (file,
549 print_jump_internal_function (lf *file,
550 function_entry *function,
553 if (function->is_internal)
555 lf_printf (file, "\n");
556 lf_print__line_ref (file, function->line);
557 lf_indent (file, -1);
558 print_function_name (file,
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");
583 print_jump_body (lf *file,
586 cache_entry *cache_rules)
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)
597 lf_putstr (file, "engine_cache *cache_entry = NULL;\n");
601 lf_putstr (file, "int current_cpu = -1;\n");
604 /* all the switches and tables - they know about jumping */
605 print_idecode_lookups (file, entry, cache_rules);
607 /* start the simulation up */
608 if (options.gen.icache)
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");
618 lf_putstr (file, "\n");
619 lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
621 lf_putstr (file, "\n");
622 lf_putstr (file, "if (setjmp(halt))\n");
623 lf_putstr (file, " return;\n");
625 lf_putstr (file, "\n");
626 lf_putstr (file, "setjmp(restart);\n");
628 lf_putstr (file, "\n");
629 if (!options.gen.smp)
631 lf_putstr (file, "processor = processors[0];\n");
632 lf_putstr (file, "nia = cpu_get_program_counter(processor);\n");
636 lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
639 if (!options.gen.icache)
641 lf_printf (file, "\n");
642 lf_indent (file, -1);
643 lf_printf (file, "engine:\n");
644 lf_indent (file, +1);
647 print_jump(file, 0/*is_tail*/);
649 if (options.gen.icache)
651 lf_indent (file, -1);
652 lf_printf (file, "cache_miss:\n");
653 lf_indent (file, +1);
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);
664 /* print out a table of all the internals functions */
665 function_entry_traverse (file, isa->functions,
666 print_jump_internal_function,
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,
674 print_jump_definition, /* leaf */
677 lf_indent (file, -2);
678 lf_printf (file, "}\n");
683 /****************************************************************/
687 print_engine_run_function_header (lf *file,
689 function_decl_type decl_type)
692 lf_printf (file, "\n");
695 case is_function_declaration:
696 lf_print__function_type (file, "void", "INLINE_ENGINE", "\n");
698 case is_function_definition:
699 lf_print__function_type (file, "void", "INLINE_ENGINE", " ");
701 case is_function_variable:
702 lf_printf (file, "void (*");
705 indent = print_function_name (file,
707 NULL, /* format name */
709 NULL, /* expanded bits */
710 function_name_prefix_engine);
713 case is_function_definition:
714 lf_putstr (file, "\n(");
717 case is_function_declaration:
718 indent += lf_printf (file, " (");
720 case is_function_variable:
721 lf_putstr (file, ")\n(");
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);
733 case is_function_definition:
734 lf_putstr (file, "\n");
736 case is_function_variable:
737 case is_function_declaration:
738 lf_putstr (file, ";\n");
745 gen_engine_h (lf *file,
748 cache_entry *cache_rules)
751 for (entry = gen->tables; entry != NULL; entry = entry->next)
753 print_engine_run_function_header (file,
754 (options.gen.multi_sim
757 is_function_declaration);
763 gen_engine_c(lf *file,
766 cache_entry *cache_rules)
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");
779 for (entry = gen->tables; entry != NULL; entry = entry->next)
781 switch (options.gen.code)
784 print_idecode_lookups (file, entry->table, cache_rules);
786 /* output the main engine routine */
787 print_engine_run_function_header (file,
788 (options.gen.multi_sim
791 is_function_definition);
792 print_run_body (file, entry->table);
796 ERROR ("Jumps currently unimplemented");
798 print_engine_run_function_header (file,
800 is_function_definition);
801 print_jump_body (file, entry->table,