1 /* This file is part of the program psim.
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.
27 #include "ld-decode.h"
33 #include "gen-idecode.h"
34 #include "gen-icache.h"
35 #include "gen-semantics.h"
40 lf_print_opcodes(lf *file,
45 ASSERT(table->opcode != NULL);
46 lf_printf(file, "_%d_%d",
49 if (table->parent == NULL) break;
50 lf_printf(file, "__%d", table->opcode_nr);
51 table = table->parent;
56 /****************************************************************/
60 lf_print_table_name(lf *file,
63 lf_printf(file, "idecode_table");
64 lf_print_opcodes(file, table);
70 print_idecode_table(lf *file,
75 /* FIXME: I don't think the second part of this is correct! */
77 decode_table *opcode_rule;
78 /* have a look at the rule table, if all table rules follow all
79 switch rules, I can assume that all end points are leaves */
80 opcode_rule = entry->opcode_rule;
81 while (opcode_rule != NULL
82 && (opcode_rule->gen == switch_gen
83 || opcode_rule->gen == padded_switch_gen))
84 opcode_rule = opcode_rule->next;
85 while (opcode_rule != NULL
86 && (opcode_rule->gen == switch_gen
87 || opcode_rule->gen == padded_switch_gen)
88 && opcode_rule->type != normal_decode_rule)
89 opcode_rule = opcode_rule->next;
90 can_assume_leaf = opcode_rule == NULL;
93 lf_printf(file, "idecode_table_entry *table = ");
94 lf_print_table_name(file, entry);
95 lf_printf(file, ";\n");
96 lf_printf(file, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
97 i2target(hi_bit_nr, entry->opcode->first),
98 i2target(hi_bit_nr, entry->opcode->last));
99 lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
100 lf_printf(file, "while (1) {\n");
103 lf_printf(file, "/* nonzero mask -> another table */\n");
104 lf_printf(file, "while (table_entry->shift >= 0) {\n");
107 lf_printf(file, "table = ((idecode_table_entry*)\n");
108 lf_printf(file, " table_entry->function_or_table);\n");
109 lf_printf(file, "opcode = ((instruction & table_entry->mask)\n");
110 lf_printf(file, " >> table_entry->shift);\n");
111 lf_printf(file, "table_entry = table + opcode;\n");
114 lf_printf(file, "}\n");
115 lf_printf(file, "ASSERT(table_entry->shift < 0);\n");
116 lf_printf(file, "/* found the leaf */\n");
117 lf_printf(file, "if (table_entry->shift == table_function_entry) {\n");
119 if ((code & generate_jumps)) {
120 lf_printf(file, "goto *table_entry->function_or_table;\n");
123 lf_printf(file, "%s ", result);
124 if ((code & generate_with_icache)) {
125 lf_printf(file, "(((idecode_icache*)table_entry->function_or_table)\n");
126 lf_printf(file, " (%s));\n", ICACHE_FUNCTION_ACTUAL);
129 lf_printf(file, "((idecode_semantic*)table_entry->function_or_table)\n");
130 lf_printf(file, " (%s);\n", SEMANTIC_FUNCTION_ACTUAL);
133 lf_printf(file, "break;\n");
135 lf_printf(file, "}\n");
136 lf_printf(file, "/* must be a boolean */\n");
137 lf_printf(file, "opcode = (((instruction << table_entry->left)\n");
138 lf_printf(file, " >> table_entry->right)\n");
139 lf_printf(file, " != table_entry->mask);\n");
140 lf_printf(file, "table = ((idecode_table_entry*)\n");
141 lf_printf(file, " table_entry->function_or_table);\n");
142 lf_printf(file, "table_entry = table + opcode;\n");
145 lf_printf(file, "}\n");
150 print_idecode_table_start(insn_table *table,
156 /* start of the table */
157 if (table->opcode_rule->gen == array_gen) {
158 lf_printf(file, "\n");
159 lf_printf(file, "static idecode_table_entry ");
160 lf_print_table_name(file, table);
161 lf_printf(file, "[] = {\n");
166 print_idecode_table_leaf(insn_table *entry,
172 ASSERT(entry->parent != NULL);
175 /* add an entry to the table */
176 if (entry->parent->opcode_rule->gen == array_gen) {
177 if (entry->opcode == NULL) {
178 /* table leaf entry */
179 lf_printf(file, " /*%d*/ { table_function_entry, 0, 0, 0, ", entry->opcode_nr);
180 if ((code & generate_jumps))
181 lf_printf(file, "&&");
182 print_function_name(file,
183 entry->insns->file_entry->fields[insn_name],
184 entry->expanded_bits,
185 ((code & generate_with_icache)
186 ? function_name_prefix_icache
187 : function_name_prefix_semantics));
188 lf_printf(file, " },\n");
190 else if (entry->opcode_rule->gen == switch_gen
191 || entry->opcode_rule->gen == goto_switch_gen
192 || entry->opcode_rule->gen == padded_switch_gen) {
193 /* table calling switch statement */
194 lf_printf(file, " /*%d*/ { table_function_entry, 0, 0, 0, ",
196 if ((code & generate_jumps))
197 lf_printf(file, "&&");
198 lf_print_table_name(file, entry);
199 lf_printf(file, " },\n");
202 /* table `calling' another table */
203 lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
204 if (entry->opcode->is_boolean)
205 lf_printf(file, "table_boolean_entry, %d, %d, %d, ",
206 entry->opcode->first,
207 insn_bit_size - entry->opcode->last + entry->opcode->first - 1,
208 entry->opcode->boolean_constant);
210 lf_printf(file, "%d, 0, 0, MASK32(%d,%d), ",
211 insn_bit_size - entry->opcode->last - 1,
212 i2target(hi_bit_nr, entry->opcode->first),
213 i2target(hi_bit_nr, entry->opcode->last));
214 lf_print_table_name(file, entry);
215 lf_printf(file, " },\n");
221 print_idecode_table_end(insn_table *table,
227 if (table->opcode_rule->gen == array_gen) {
228 lf_printf(file, "};\n");
233 print_idecode_table_padding(insn_table *table,
240 if (table->opcode_rule->gen == array_gen) {
241 lf_printf(file, " /*%d*/ { table_function_entry, 0, 0, 0, ", opcode_nr);
242 if ((code & generate_jumps))
243 lf_printf(file, "&&");
244 lf_printf(file, "%s_illegal },\n",
245 ((code & generate_with_icache) ? "icache" : "semantic"));
250 /****************************************************************/
254 print_goto_switch_name(lf *file,
257 lf_printf(file, "case_");
258 if (entry->opcode == NULL)
259 print_function_name(file,
260 entry->insns->file_entry->fields[insn_name],
261 entry->expanded_bits,
262 ((code & generate_with_icache)
263 ? function_name_prefix_icache
264 : function_name_prefix_semantics));
266 lf_print_table_name(file, entry);
270 print_goto_switch_table_leaf(insn_table *entry,
276 ASSERT(entry->parent != NULL);
278 ASSERT(entry->parent->opcode_rule->gen == goto_switch_gen);
279 ASSERT(entry->parent->opcode);
281 lf_printf(file, "&&");
282 print_goto_switch_name(file, entry);
283 lf_printf(file, ",\n");
287 print_goto_switch_table_padding(insn_table *table,
294 ASSERT(table->opcode_rule->gen == goto_switch_gen);
296 lf_printf(file, "&&illegal_");
297 lf_print_table_name(file, table);
298 lf_printf(file, ",\n");
302 print_goto_switch_break(lf *file,
305 lf_printf(file, "goto break_");
306 lf_print_table_name(file, entry->parent);
307 lf_printf(file, ";\n");
312 print_goto_switch_table(lf *file,
315 lf_printf(file, "const static void *");
316 lf_print_table_name(file, table);
317 lf_printf(file, "[] = {\n");
319 insn_table_traverse_tree(table,
323 print_goto_switch_table_leaf,
325 print_goto_switch_table_padding);
327 lf_printf(file, "};\n");
331 void print_idecode_switch
337 idecode_switch_start(insn_table *table,
342 /* const char *result = data; */
344 ASSERT(table->opcode_rule->gen == switch_gen
345 || table->opcode_rule->gen == goto_switch_gen
346 || table->opcode_rule->gen == padded_switch_gen);
348 if (table->opcode->is_boolean
349 || table->opcode_rule->gen == switch_gen
350 || table->opcode_rule->gen == padded_switch_gen) {
351 lf_printf(file, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
352 i2target(hi_bit_nr, table->opcode->first),
353 i2target(hi_bit_nr, table->opcode->last));
355 else if (table->opcode_rule->gen == goto_switch_gen) {
356 if (table->parent != NULL
357 && (table->parent->opcode_rule->gen == switch_gen
358 || table->parent->opcode_rule->gen == goto_switch_gen
359 || table->parent->opcode_rule->gen == padded_switch_gen)) {
360 lf_printf(file, "{\n");
363 print_goto_switch_table(file, table);
364 lf_printf(file, "ASSERT(EXTRACTED32(instruction, %d, %d)\n",
365 i2target(hi_bit_nr, table->opcode->first),
366 i2target(hi_bit_nr, table->opcode->last));
367 lf_printf(file, " < (sizeof(");
368 lf_print_table_name(file, table);
369 lf_printf(file, ") / sizeof(void*)));\n");
370 lf_printf(file, "goto *");
371 lf_print_table_name(file, table);
372 lf_printf(file, "[EXTRACTED32(instruction, %d, %d)];\n",
373 i2target(hi_bit_nr, table->opcode->first),
374 i2target(hi_bit_nr, table->opcode->last));
377 ASSERT("bad switch" == NULL);
383 idecode_switch_leaf(insn_table *entry,
389 const char *result = data;
390 ASSERT(entry->parent != NULL);
392 ASSERT(entry->parent->opcode_rule->gen == switch_gen
393 || entry->parent->opcode_rule->gen == goto_switch_gen
394 || entry->parent->opcode_rule->gen == padded_switch_gen);
395 ASSERT(entry->parent->opcode);
397 if (entry->parent->opcode->is_boolean
398 && entry->opcode_nr == 0) {
399 /* boolean false target */
400 lf_printf(file, "case %d:\n", entry->parent->opcode->boolean_constant);
402 else if (entry->parent->opcode->is_boolean
403 && entry->opcode_nr != 0) {
404 /* boolean true case */
405 lf_printf(file, "default:\n");
407 else if (entry->parent->opcode_rule->gen == switch_gen
408 || entry->parent->opcode_rule->gen == padded_switch_gen) {
410 lf_printf(file, "case %d:\n", entry->opcode_nr);
412 else if (entry->parent->opcode_rule->gen == goto_switch_gen) {
413 /* lf_indent(file, -1); */
414 print_goto_switch_name(file, entry);
415 lf_printf(file, ":\n");
416 /* lf_indent(file, +1); */
419 ASSERT("bad switch" == NULL);
423 if (entry->opcode == NULL) {
424 /* switch calling leaf */
425 if ((code & generate_jumps))
426 lf_printf(file, "goto ");
427 if ((code & generate_calls))
428 lf_printf(file, "%s ", result);
429 print_function_name(file,
430 entry->insns->file_entry->fields[insn_name],
431 entry->expanded_bits,
432 ((code & generate_with_icache)
433 ? function_name_prefix_icache
434 : function_name_prefix_semantics));
435 if ((code & generate_calls))
436 lf_printf(file, "(%s)", SEMANTIC_FUNCTION_ACTUAL);
437 lf_printf(file, ";\n");
439 else if (entry->opcode_rule->gen == switch_gen
440 || entry->opcode_rule->gen == goto_switch_gen
441 || entry->opcode_rule->gen == padded_switch_gen) {
442 /* switch calling switch */
443 print_idecode_switch(file, entry, result);
446 /* switch looking up a table */
447 lf_printf(file, "{\n");
449 print_idecode_table(file, entry, result);
451 lf_printf(file, "}\n");
453 if (entry->parent->opcode->is_boolean
454 || entry->parent->opcode_rule->gen == switch_gen
455 || entry->parent->opcode_rule->gen == padded_switch_gen) {
456 lf_printf(file, "break;\n");
458 else if (entry->parent->opcode_rule->gen == goto_switch_gen) {
459 print_goto_switch_break(file, entry);
462 ASSERT("bad switch" == NULL);
470 print_idecode_switch_illegal(lf *file,
474 print_idecode_illegal(file, result);
475 lf_printf(file, "break;\n");
480 idecode_switch_end(insn_table *table,
485 const char *result = data;
487 ASSERT(table->opcode_rule->gen == switch_gen
488 || table->opcode_rule->gen == goto_switch_gen
489 || table->opcode_rule->gen == padded_switch_gen);
490 ASSERT(table->opcode);
492 if (table->opcode->is_boolean) {
493 lf_printf(file, "}\n");
495 else if (table->opcode_rule->gen == switch_gen
496 || table->opcode_rule->gen == padded_switch_gen) {
497 lf_printf(file, "default:\n");
498 switch (table->opcode_rule->gen) {
500 print_idecode_switch_illegal(file, result);
502 case padded_switch_gen:
503 lf_printf(file, " error(\"Internal error - bad switch generated\\n\");\n");
504 lf_printf(file, " break;\n");
507 ASSERT("bad switch" == NULL);
509 lf_printf(file, "}\n");
511 else if (table->opcode_rule->gen == goto_switch_gen) {
512 lf_printf(file, "illegal_");
513 lf_print_table_name(file, table);
514 lf_printf(file, ":\n");
515 print_idecode_illegal(file, result);
516 lf_printf(file, "break_");
517 lf_print_table_name(file, table);
518 lf_printf(file, ":;\n");
519 if (table->parent != NULL
520 && (table->parent->opcode_rule->gen == switch_gen
521 || table->parent->opcode_rule->gen == goto_switch_gen
522 || table->parent->opcode_rule->gen == padded_switch_gen)) {
524 lf_printf(file, "}\n");
528 ASSERT("bad switch" == NULL);
533 idecode_switch_padding(insn_table *table,
539 const char *result = data;
541 ASSERT(table->opcode_rule->gen == switch_gen
542 || table->opcode_rule->gen == goto_switch_gen
543 || table->opcode_rule->gen == padded_switch_gen);
545 switch (table->opcode_rule->gen) {
548 case padded_switch_gen:
549 lf_printf(file, "case %d:\n", opcode_nr);
550 print_idecode_switch_illegal(file, result);
552 case goto_switch_gen:
553 /* no padding needed */
556 ASSERT("bad switch" != NULL);
562 print_idecode_switch(lf *file,
566 insn_table_traverse_tree(table,
569 idecode_switch_start,
572 idecode_switch_padding);
577 print_idecode_switch_function_header(lf *file,
579 int is_function_definition)
581 lf_printf(file, "\n");
582 if ((code & generate_calls)) {
583 lf_printf(file, "static ");
584 if ((code & generate_with_icache))
585 lf_printf(file, "idecode_semantic *");
587 lf_printf(file, "unsigned_word");
588 if (is_function_definition)
589 lf_printf(file, "\n");
591 lf_printf(file, " ");
592 lf_print_table_name(file, table);
593 lf_printf(file, "\n(%s)", ICACHE_FUNCTION_FORMAL);
594 if (!is_function_definition)
595 lf_printf(file, ";");
596 lf_printf(file, "\n");
598 if ((code & generate_jumps) && is_function_definition) {
600 lf_print_table_name(file, table);
601 lf_printf(file, ":\n");
608 idecode_declare_if_switch(insn_table *table,
613 if ((table->opcode_rule->gen == switch_gen
614 || table->opcode_rule->gen == goto_switch_gen
615 || table->opcode_rule->gen == padded_switch_gen)
616 && table->parent != NULL /* don't declare the top one yet */
617 && table->parent->opcode_rule->gen == array_gen) {
618 print_idecode_switch_function_header(file,
620 0/*isnt function definition*/);
626 idecode_expand_if_switch(insn_table *table,
631 if ((table->opcode_rule->gen == switch_gen
632 || table->opcode_rule->gen == goto_switch_gen
633 || table->opcode_rule->gen == padded_switch_gen)
634 && table->parent != NULL /* don't expand the top one yet */
635 && table->parent->opcode_rule->gen == array_gen) {
636 print_idecode_switch_function_header(file,
638 1/*is function definition*/);
639 if ((code & generate_calls)) {
640 lf_printf(file, "{\n");
643 print_idecode_switch(file, table, "return");
644 if ((code & generate_calls)) {
646 lf_printf(file, "}\n");
652 /****************************************************************/
656 print_idecode_lookups(lf *file,
658 cache_table *cache_rules)
662 /* output switch function declarations where needed by tables */
663 insn_table_traverse_tree(table,
666 idecode_declare_if_switch, /* START */
669 /* output tables where needed */
670 for (depth = insn_table_depth(table);
673 insn_table_traverse_tree(table,
676 print_idecode_table_start,
677 print_idecode_table_leaf,
678 print_idecode_table_end,
679 print_idecode_table_padding);
682 /* output switch functions where needed */
683 insn_table_traverse_tree(table,
686 idecode_expand_if_switch, /* START */
692 print_idecode_body(lf *file,
697 lf_indent(file, +strlen(indent));
698 lf_putstr(file, "{\n");
700 if (table->opcode_rule->gen == switch_gen
701 || table->opcode_rule->gen == goto_switch_gen
702 || table->opcode_rule->gen == padded_switch_gen)
703 print_idecode_switch(file, table, result);
705 print_idecode_table(file, table, result);
707 lf_putstr(file, "}\n");
708 lf_indent(file, -strlen(indent));
712 /****************************************************************/
716 print_run_until_stop_body(lf *file,
720 /* Output the function to execute real code:
722 Unfortunatly, there are multiple cases to consider vis:
724 <icache> X <smp> X <events> X <keep-running-flag> X ...
726 Consequently this function is written in multiple different ways */
728 lf_putstr(file, "{\n");
730 lf_putstr(file, "jmp_buf halt;\n");
731 lf_putstr(file, "jmp_buf restart;\n");
732 lf_putstr(file, "cpu *processor = NULL;\n");
733 lf_putstr(file, "unsigned_word cia = -1;\n");
734 lf_putstr(file, "instruction_word instruction = 0;\n");
736 lf_putstr(file, "int current_cpu = -1;\n");
738 if ((code & generate_with_icache)) {
739 lf_putstr(file, "idecode_cache *cache_entry = NULL;\n");
742 if ((code & generate_with_icache)) {
743 lf_putstr(file, "\n");
744 lf_putstr(file, "{\n");
745 lf_putstr(file, " int cpu_nr;\n");
746 lf_putstr(file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
747 lf_putstr(file, " cpu_flush_icache(processors[cpu_nr]);\n");
748 lf_putstr(file, "}\n");
751 lf_putstr(file, "\n");
752 lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
754 lf_putstr(file, "\n");
755 lf_putstr(file, "if (setjmp(halt))\n");
756 lf_putstr(file, " return;\n");
758 lf_putstr(file, "\n");
759 lf_putstr(file, "setjmp(restart);\n");
764 /* CASE 1: NO SMP (with or with out instruction cache).
766 In this case, we can take advantage of the fact that the current
767 instruction address does not need to be returned to the cpu object
768 after every execution of an instruction. Instead it only needs to
769 be saved when either A. the main loop exits or B. A cpu-halt or
770 cpu-restart call forces the loop to be re-enered. The later
771 functions always save the current cpu instruction address.
773 Two subcases also exist that with and that without an instruction
776 lf_putstr(file, "\n\n");
778 lf_putstr(file, "processor = processors[0];\n");
779 lf_putstr(file, "cia = cpu_get_program_counter(processor);\n");
780 lf_putstr(file, "while (1) {\n");
782 lf_putstr(file, "if (WITH_EVENTS) {\n");
783 lf_putstr(file, " if (event_queue_tick(events)) {\n");
784 lf_putstr(file, " cpu_set_program_counter(processor, cia);\n");
785 lf_putstr(file, " event_queue_process(events);\n");
786 lf_putstr(file, " cia = cpu_get_program_counter(processor);\n");
787 lf_putstr(file, " }\n");
788 lf_putstr(file, "}\n");
790 if (!(code & generate_with_icache)) {
791 lf_putstr(file, "instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
792 print_idecode_body(file, table, "cia =", "");
795 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
796 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
800 if ((code & generate_with_icache)) {
801 lf_putstr(file, "cache_entry = cpu_icache_entry(processor, cia);\n");
802 lf_putstr(file, "if (cache_entry->address == cia) {\n");
803 lf_putstr(file, " /* cache hit */\n");
804 lf_putstr(file, " idecode_semantic *const semantic = cache_entry->semantic;\n");
805 lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n");
808 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
809 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
811 lf_putstr(file, " continue;\n");
812 lf_putstr(file, "}\n");
813 lf_putstr(file, "else {\n");
814 lf_putstr(file, " /* cache miss */\n");
815 if (!(code & generate_with_semantic_icache)) {
817 lf_putstr(file, "idecode_semantic *semantic;\n");
820 lf_putstr(file, " instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
821 lf_putstr(file, " if (WITH_MON != 0)\n");
822 lf_putstr(file, " mon_event(mon_event_icache_miss, processor, cia);\n");
823 if ((code & generate_with_semantic_icache)) {
824 print_idecode_body(file, table, "cia =", " ");
827 print_idecode_body(file, table, "semantic =", " ");
828 lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n");
832 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
833 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
835 lf_putstr(file, " continue;\n");
836 lf_putstr(file, "}\n");
840 lf_putstr(file, "}\n");
846 /* CASE 2: SMP (With or without ICACHE)
848 The complexity here comes from needing to correctly restart the
849 system when it is aborted. In particular if cpu0 requests a
850 restart, the next cpu is still cpu1. Cpu0 being restarted after
851 all the other CPU's and the event queue have been processed */");
853 lf_putstr(file, "\n\n");
855 lf_putstr(file, "current_cpu = psim_last_cpu(system);\n");
856 lf_putstr(file, "while (1) {\n");
858 lf_putstr(file, "if (WITH_EVENTS) {\n");
859 lf_putstr(file, " current_cpu += 1;\n");
860 lf_putstr(file, " if (current_cpu == nr_cpus) {\n");
861 lf_putstr(file, " if (event_queue_tick(events)) {\n");
862 lf_putstr(file, " event_queue_process(events);\n");
863 lf_putstr(file, " }\n");
864 lf_putstr(file, " current_cpu = 0;\n");
865 lf_putstr(file, " }\n");
866 lf_putstr(file, "}\n");
867 lf_putstr(file, "else {\n");
868 lf_putstr(file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
869 lf_putstr(file, "}\n");
870 lf_putstr(file, "processor = processors[current_cpu];\n");
871 lf_putstr(file, "cia = cpu_get_program_counter(processor);\n");
873 if (!(code & generate_with_icache)) {
874 lf_putstr(file, "instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
875 print_idecode_body(file, table, "cia =", "");
877 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
878 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
880 lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
881 lf_putstr(file, "continue;\n");
884 if ((code & generate_with_icache)) {
885 lf_putstr(file, "cache_entry = cpu_icache_entry(processor, cia);\n");
886 lf_putstr(file, "if (cache_entry->address == cia) {\n");
889 lf_putstr(file, "/* cache hit */\n");
890 lf_putstr(file, "idecode_semantic *semantic = cache_entry->semantic;\n");
891 lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n");
894 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
895 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
897 lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
898 lf_putstr(file, "continue;\n");
901 lf_putstr(file, "}\n");
902 lf_putstr(file, "else {\n");
905 lf_putstr(file, "/* cache miss */\n");
906 if (!(code & generate_with_semantic_icache)) {
907 lf_putstr(file, "idecode_semantic *semantic;\n");
909 lf_putstr(file, "instruction =\n");
910 lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
911 lf_putstr(file, "if (WITH_MON != 0)\n");
912 lf_putstr(file, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
913 if ((code & generate_with_semantic_icache)) {
914 print_idecode_body(file, table, "cia =", "");
917 print_idecode_body(file, table, "semantic = ", " ");
918 lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n");
922 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
923 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
925 lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
926 lf_putstr(file, "continue;\n");
929 lf_putstr(file, "}\n");
934 lf_putstr(file, "}\n");
939 lf_putstr(file, "}\n");
943 /****************************************************************/
950 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
951 lf_putstr(file, " cpu_halt(processor, nia, was_continuing, 0/*na*/);\n");
955 lf_putstr(file, "if (WITH_EVENTS) {\n");
956 lf_putstr(file, " if (event_queue_tick(events)) {\n");
957 lf_putstr(file, " cpu_set_program_counter(processor, nia);\n");
958 lf_putstr(file, " event_queue_process(events);\n");
959 lf_putstr(file, " nia = cpu_get_program_counter(processor);\n");
960 lf_putstr(file, " }\n");
961 lf_putstr(file, "}\n");
966 lf_putstr(file, "cpu_set_program_counter(processor, nia);\n");
967 lf_putstr(file, "if (WITH_EVENTS) {\n");
968 lf_putstr(file, " current_cpu += 1;\n");
969 lf_putstr(file, " if (current_cpu >= nr_cpus) {\n");
970 lf_putstr(file, " if (event_queue_tick(events)) {\n");
971 lf_putstr(file, " event_queue_process(events);\n");
972 lf_putstr(file, " }\n");
973 lf_putstr(file, " current_cpu = 0;\n");
974 lf_putstr(file, " }\n");
975 lf_putstr(file, "}\n");
976 lf_putstr(file, "else {\n");
977 lf_putstr(file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
978 lf_putstr(file, "}\n");
979 lf_putstr(file, "processor = processors[current_cpu];\n");
980 lf_putstr(file, "nia = cpu_get_program_counter(processor);\n");
983 if ((code & generate_with_icache)) {
984 lf_putstr(file, "cache_entry = cpu_icache_entry(processor, nia);\n");
985 lf_putstr(file, "if (cache_entry->address == nia) {\n");
986 lf_putstr(file, " /* cache hit */\n");
987 lf_putstr(file, " goto *cache_entry->semantic;\n");
988 lf_putstr(file, "}\n");
990 lf_putstr(file, "goto cache_miss;\n");
994 if (!(code & generate_with_icache) && is_tail) {
995 lf_printf(file, "goto idecode;\n");
1005 print_jump_insn(lf *file,
1007 insn_bits *expanded_bits,
1008 opcode_field *opcodes,
1009 cache_table *cache_rules)
1012 /* what we are for the moment */
1013 lf_printf(file, "\n");
1014 print_my_defines(file, expanded_bits, instruction->file_entry);
1016 /* output the icache entry */
1017 if ((code & generate_with_icache)) {
1018 lf_printf(file, "\n");
1019 lf_indent(file, -1);
1020 print_function_name(file,
1021 instruction->file_entry->fields[insn_name],
1023 function_name_prefix_icache);
1024 lf_printf(file, ":\n");
1025 lf_indent(file, +1);
1026 lf_printf(file, "{\n");
1027 lf_indent(file, +2);
1028 lf_putstr(file, "const unsigned_word cia = nia;\n");
1029 print_itrace(file, instruction->file_entry, 1/*putting-value-in-cache*/);
1030 print_idecode_validate(file, instruction, opcodes);
1031 lf_printf(file, "\n");
1032 lf_printf(file, "{\n");
1033 lf_indent(file, +2);
1034 print_icache_body(file,
1039 put_values_in_icache);
1040 lf_printf(file, "cache_entry->address = nia;\n");
1041 lf_printf(file, "cache_entry->semantic = &&");
1042 print_function_name(file,
1043 instruction->file_entry->fields[insn_name],
1045 function_name_prefix_semantics);
1046 lf_printf(file, ";\n");
1047 if ((code & generate_with_semantic_icache)) {
1048 print_semantic_body(file,
1052 print_jump(file, 1/*is-tail*/);
1055 lf_printf(file, "/* goto ");
1056 print_function_name(file,
1057 instruction->file_entry->fields[insn_name],
1059 function_name_prefix_semantics);
1060 lf_printf(file, "; */\n");
1062 lf_indent(file, -2);
1063 lf_putstr(file, "}\n");
1064 lf_indent(file, -2);
1065 lf_printf(file, "}\n");
1068 /* print the semantics */
1069 lf_printf(file, "\n");
1070 lf_indent(file, -1);
1071 print_function_name(file,
1072 instruction->file_entry->fields[insn_name],
1074 function_name_prefix_semantics);
1075 lf_printf(file, ":\n");
1076 lf_indent(file, +1);
1077 lf_printf(file, "{\n");
1078 lf_indent(file, +2);
1079 lf_putstr(file, "const unsigned_word cia = nia;\n");
1080 print_icache_body(file,
1084 ((code & generate_with_direct_access)
1086 : declare_variables),
1087 ((code & generate_with_icache)
1088 ? get_values_from_icache
1089 : do_not_use_icache));
1090 print_semantic_body(file,
1094 if (code & generate_with_direct_access)
1095 print_icache_body(file,
1100 ((code & generate_with_icache)
1101 ? get_values_from_icache
1102 : do_not_use_icache));
1103 print_jump(file, 1/*is tail*/);
1104 lf_indent(file, -2);
1105 lf_printf(file, "}\n");
1109 print_jump_definition(insn_table *entry,
1115 cache_table *cache_rules = (cache_table*)data;
1116 if (generate_expanded_instructions) {
1117 ASSERT(entry->nr_insn == 1
1118 && entry->opcode == NULL
1119 && entry->parent != NULL
1120 && entry->parent->opcode != NULL);
1121 ASSERT(entry->nr_insn == 1
1122 && entry->opcode == NULL
1123 && entry->parent != NULL
1124 && entry->parent->opcode != NULL
1125 && entry->parent->opcode_rule != NULL);
1126 print_jump_insn(file,
1128 entry->expanded_bits,
1133 print_jump_insn(file,
1143 print_jump_internal_function(insn_table *table,
1146 table_entry *function)
1148 if (it_is("internal", function->fields[insn_flags])) {
1149 lf_printf(file, "\n");
1150 table_entry_print_cpp_line_nr(file, function);
1151 lf_indent(file, -1);
1152 print_function_name(file,
1153 function->fields[insn_name],
1155 ((code & generate_with_icache)
1156 ? function_name_prefix_icache
1157 : function_name_prefix_semantics));
1158 lf_printf(file, ":\n");
1159 lf_indent(file, +1);
1160 lf_printf(file, "{\n");
1161 lf_indent(file, +2);
1162 lf_printf(file, "const unsigned_word cia = nia;\n");
1163 lf_print__c_code(file, function->annex);
1164 lf_print__internal_reference(file);
1165 lf_printf(file, "error(\"Internal function must longjump\\n\");\n");
1166 lf_indent(file, -2);
1167 lf_printf(file, "}\n");
1172 print_jump_until_stop_body(lf *file,
1174 cache_table *cache_rules,
1177 lf_printf(file, "{\n");
1178 lf_indent(file, +2);
1180 lf_printf(file, "int *keep_running = NULL;\n");
1181 lf_putstr(file, "jmp_buf halt;\n");
1182 lf_putstr(file, "jmp_buf restart;\n");
1183 lf_putstr(file, "cpu *processor = NULL;\n");
1184 lf_putstr(file, "unsigned_word nia = -1;\n");
1185 lf_putstr(file, "instruction_word instruction = 0;\n");
1186 if ((code & generate_with_icache)) {
1187 lf_putstr(file, "idecode_cache *cache_entry = NULL;\n");
1190 lf_putstr(file, "int current_cpu = -1;\n");
1193 /* all the switches and tables - they know about jumping */
1194 print_idecode_lookups(file, table, cache_rules);
1196 /* start the simulation up */
1197 if ((code & generate_with_icache)) {
1198 lf_putstr(file, "\n");
1199 lf_putstr(file, "{\n");
1200 lf_putstr(file, " int cpu_nr;\n");
1201 lf_putstr(file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
1202 lf_putstr(file, " cpu_flush_icache(processors[cpu_nr]);\n");
1203 lf_putstr(file, "}\n");
1206 lf_putstr(file, "\n");
1207 lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1209 lf_putstr(file, "\n");
1210 lf_putstr(file, "if (setjmp(halt))\n");
1211 lf_putstr(file, " return;\n");
1213 lf_putstr(file, "\n");
1214 lf_putstr(file, "setjmp(restart);\n");
1216 lf_putstr(file, "\n");
1217 if (!generate_smp) {
1218 lf_putstr(file, "processor = processors[0];\n");
1219 lf_putstr(file, "nia = cpu_get_program_counter(processor);\n");
1222 lf_putstr(file, "current_cpu = psim_last_cpu(system);\n");
1225 if (!(code & generate_with_icache)) {
1226 lf_printf(file, "\n");
1227 lf_indent(file, -1);
1228 lf_printf(file, "idecode:\n");
1229 lf_indent(file, +1);
1232 print_jump(file, 0/*is_tail*/);
1234 if ((code & generate_with_icache)) {
1235 lf_indent(file, -1);
1236 lf_printf(file, "cache_miss:\n");
1237 lf_indent(file, +1);
1240 lf_putstr(file, "instruction\n");
1241 lf_putstr(file, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
1242 lf_putstr(file, " processor, nia);\n");
1243 print_idecode_body(file, table, "/*IGORE*/", "");
1245 /* print out a table of all the internals functions */
1246 insn_table_traverse_function(table,
1248 print_jump_internal_function);
1250 /* print out a table of all the instructions */
1251 if (generate_expanded_instructions)
1252 insn_table_traverse_tree(table,
1256 print_jump_definition, /* leaf */
1258 NULL); /* padding */
1260 insn_table_traverse_insn(table,
1262 print_jump_definition);
1263 lf_indent(file, -2);
1264 lf_printf(file, "}\n");
1268 /****************************************************************/
1273 print_idecode_floating_point_unavailable(lf *file)
1275 if ((code & generate_jumps))
1276 lf_printf(file, "goto %s_floating_point_unavailable;\n", (code & generate_with_icache) ? "icache" : "semantic");
1277 else if ((code & generate_with_icache))
1278 lf_printf(file, "return icache_floating_point_unavailable(%s);\n",
1279 ICACHE_FUNCTION_ACTUAL);
1281 lf_printf(file, "return semantic_floating_point_unavailable(%s);\n",
1282 SEMANTIC_FUNCTION_ACTUAL);
1286 /* Output code to do any final checks on the decoded instruction.
1287 This includes things like verifying any on decoded fields have the
1288 correct value and checking that (for floating point) floating point
1289 hardware isn't disabled */
1292 print_idecode_validate(lf *file,
1294 opcode_field *opcodes)
1296 /* Validate: unchecked instruction fields
1298 If any constant fields in the instruction were not checked by the
1299 idecode tables, output code to check that they have the correct
1302 unsigned check_mask = 0;
1303 unsigned check_val = 0;
1305 opcode_field *opcode;
1307 /* form check_mask/check_val containing what needs to be checked
1308 in the instruction */
1309 for (field = instruction->fields->first;
1310 field->first < insn_bit_size;
1311 field = field->next) {
1313 check_mask <<= field->width;
1314 check_val <<= field->width;
1316 /* is it a constant that could need validating? */
1317 if (!field->is_int && !field->is_slash)
1320 /* has it been checked by a table? */
1321 for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
1322 if (field->first >= opcode->first
1323 && field->last <= opcode->last)
1329 check_mask |= (1 << field->width)-1;
1330 check_val |= field->val_int;
1333 /* if any bits not checked by opcode tables, output code to check them */
1335 lf_printf(file, "\n");
1336 lf_printf(file, "/* validate: %s */\n",
1337 instruction->file_entry->fields[insn_format]);
1338 lf_printf(file, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
1339 check_mask, check_val);
1340 lf_indent(file, +2);
1341 print_idecode_illegal(file, "return");
1342 lf_indent(file, -2);
1346 /* Validate floating point hardware
1348 If the simulator is being built with out floating point hardware
1349 (different to it being disabled in the MSR) then floating point
1350 instructions are invalid */
1352 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1353 lf_printf(file, "\n");
1354 lf_printf(file, "/* Validate: FP hardware exists */\n");
1355 lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1356 lf_indent(file, +2);
1357 print_idecode_illegal(file, "return");
1358 lf_indent(file, -2);
1362 /* Validate: Floating Point available
1364 If floating point is not available, we enter a floating point
1365 unavailable interrupt into the cache instead of the instruction
1368 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1369 ever a CSI occures we flush the instruction cache. */
1372 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1373 lf_printf(file, "\n");
1374 lf_printf(file, "/* Validate: FP available according to MSR[FP] */\n");
1375 lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n");
1376 lf_indent(file, +2);
1377 print_idecode_floating_point_unavailable(file);
1378 lf_indent(file, -2);
1384 /****************************************************************/
1388 print_idecode_run_function_header(lf *file,
1393 lf_printf(file, "\n");
1394 lf_print_function_type(file, "void", "INLINE_IDECODE", (is_definition ? " " : "\n"));
1395 indent = lf_putstr(file, (can_stop ? "idecode_run_until_stop" : "idecode_run"));
1397 lf_putstr(file, "\n");
1399 lf_indent(file, +indent);
1400 lf_putstr(file, "(psim *system,\n");
1402 lf_putstr(file, " volatile int *keep_running,\n");
1403 lf_printf(file, " event_queue *events,\n");
1404 lf_putstr(file, " cpu *const processors[],\n");
1405 lf_putstr(file, " const int nr_cpus)");
1407 lf_putstr(file, ";");
1409 lf_indent(file, -indent);
1410 lf_putstr(file, "\n");
1415 gen_idecode_h(lf *file,
1417 cache_table *cache_rules)
1419 lf_printf(file, "/* The idecode_*.h functions shall move to support */\n");
1420 lf_printf(file, "#include \"idecode_expression.h\"\n");
1421 lf_printf(file, "#include \"idecode_fields.h\"\n");
1422 lf_printf(file, "#include \"idecode_branch.h\"\n");
1423 lf_printf(file, "\n");
1424 print_icache_struct(table, cache_rules, file);
1425 lf_printf(file, "\n");
1426 lf_printf(file, "#define WITH_IDECODE_SMP %d\n", generate_smp);
1427 lf_printf(file, "\n");
1428 print_idecode_run_function_header(file, 0/*can stop*/, 1/*is definition*/);
1429 print_idecode_run_function_header(file, 1/*can stop*/, 1/*is definition*/);
1434 gen_idecode_c(lf *file,
1436 cache_table *cache_rules)
1439 lf_printf(file, "#include \"inline.c\"\n");
1440 lf_printf(file, "\n");
1441 lf_printf(file, "#include \"cpu.h\"\n");
1442 lf_printf(file, "#include \"idecode.h\"\n");
1443 lf_printf(file, "#include \"semantics.h\"\n");
1444 lf_printf(file, "#include \"icache.h\"\n");
1445 lf_printf(file, "#include \"support.h\"\n");
1446 lf_printf(file, "\n");
1447 lf_printf(file, "#include <setjmp.h>\n");
1448 lf_printf(file, "\n");
1449 lf_printf(file, "/* encodings for a negative shift field */\n");
1450 lf_printf(file, "enum {\n");
1451 lf_printf(file, " table_boolean_entry = -2,\n");
1452 lf_printf(file, " table_function_entry = -1,\n");
1453 lf_printf(file, "};\n");
1454 lf_printf(file, "\n");
1455 lf_printf(file, "typedef struct _idecode_table_entry {\n");
1456 lf_printf(file, " signed short shift; /* shift >= 0: t[(i & mask) >> shift] */\n");
1457 lf_printf(file, " unsigned char left; /* shift == -2: */\n");
1458 lf_printf(file, " unsigned char right; /* t[((i << left) >> right) != mask] */\n");
1459 lf_printf(file, " unsigned mask; /* else (shift == -1): function() */\n");
1460 lf_printf(file, " void *function_or_table;\n");
1461 lf_printf(file, "} idecode_table_entry;\n");
1462 lf_printf(file, "\n");
1463 lf_printf(file, "\n");
1465 if ((code & generate_calls)) {
1467 print_idecode_lookups(file, table, cache_rules);
1469 /* output the main idecode routine */
1470 print_idecode_run_function_header(file, 0/*can stop*/, 0/*is definition*/);
1471 print_run_until_stop_body(file, table, 0/* have stop argument */);
1473 print_idecode_run_function_header(file, 1/*can stop*/, 0/*is definition*/);
1474 print_run_until_stop_body(file, table, 1/* no stop argument */);
1477 else if ((code & generate_jumps)) {
1479 print_idecode_run_function_header(file, 0/*can stop*/, 0/*is definition*/);
1480 print_jump_until_stop_body(file, table, cache_rules, 0 /* have stop argument */);
1482 print_idecode_run_function_header(file, 1/*can stop*/, 0/*is definition*/);
1483 print_jump_until_stop_body(file, table, cache_rules, 1/* have stop argument */);
1487 error("Something is wrong!\n");