1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, 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.
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 /****************************************************************/
59 error_leaf_contains_multiple_insn(insn_table *entry)
63 ASSERT(entry->opcode == NULL && entry->nr_insn > 1);
64 for (i = entry->insns; i != NULL; i = i->next) {
65 fprintf(stderr, "%s:%d: %s %s\n",
66 i->file_entry->file_name,
67 i->file_entry->line_nr,
68 i->file_entry->fields[insn_name],
70 ? "was not uniquely decoded"
71 : "decodes to the same entry"));
76 /****************************************************************/
80 lf_print_table_name(lf *file,
83 lf_printf(file, "idecode_table");
84 lf_print_opcodes(file, table);
90 print_idecode_table(lf *file,
94 lf_printf(file, "/* prime the search */\n");
95 lf_printf(file, "idecode_table_entry *table = ");
96 lf_print_table_name(file, entry);
97 lf_printf(file, ";\n");
98 lf_printf(file, "int opcode = EXTRACTED%d(instruction, %d, %d);\n",
100 i2target(hi_bit_nr, entry->opcode->first),
101 i2target(hi_bit_nr, entry->opcode->last));
102 lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
104 lf_printf(file, "\n");
105 lf_printf(file, "/* iterate until a leaf */\n");
106 lf_printf(file, "while (1) {\n");
107 lf_printf(file, " signed shift = table_entry->shift;\n");
108 lf_printf(file, "if (shift == function_entry) break;\n");
109 lf_printf(file, " if (shift >= 0) {\n");
110 lf_printf(file, " table = ((idecode_table_entry*)\n");
111 lf_printf(file, " table_entry->function_or_table);\n");
112 lf_printf(file, " opcode = ((instruction & table_entry->mask)\n");
113 lf_printf(file, " >> shift);\n");
114 lf_printf(file, " table_entry = table + opcode;\n");
115 lf_printf(file, " }\n");
116 lf_printf(file, " else {\n");
117 lf_printf(file, " /* must be a boolean */\n");
118 lf_printf(file, " ASSERT(table_entry->shift == boolean_entry);\n");
119 lf_printf(file, " opcode = ((instruction & table_entry->mask)\n");
120 lf_printf(file, " != table_entry->value);\n");
121 lf_printf(file, " table = ((idecode_table_entry*)\n");
122 lf_printf(file, " table_entry->function_or_table);\n");
123 lf_printf(file, " table_entry = table + opcode;\n");
124 lf_printf(file, " }\n");
125 lf_printf(file, "}\n");
127 lf_printf(file, "\n");
128 lf_printf(file, "/* call the leaf code */\n");
129 if ((code & generate_jumps)) {
130 lf_printf(file, "goto *table_entry->function_or_table;\n");
133 lf_printf(file, "%s ", result);
134 if ((code & generate_with_icache)) {
135 lf_printf(file, "(((idecode_icache*)table_entry->function_or_table)\n");
136 lf_printf(file, " (");
137 print_icache_function_actual(file);
138 lf_printf(file, "));\n");
141 lf_printf(file, "((idecode_semantic*)table_entry->function_or_table)\n");
142 lf_printf(file, " (");
143 print_semantic_function_actual(file);
144 lf_printf(file, ");\n");
151 print_idecode_table_start(insn_table *table,
157 /* start of the table */
158 if (table->opcode_rule->gen == array_gen) {
159 lf_printf(file, "\n");
160 lf_printf(file, "static idecode_table_entry ");
161 lf_print_table_name(file, table);
162 lf_printf(file, "[] = {\n");
167 print_idecode_table_leaf(insn_table *entry,
173 ASSERT(entry->parent != NULL);
176 /* add an entry to the table */
177 if (entry->parent->opcode_rule->gen == array_gen) {
178 lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
179 if (entry->opcode == NULL) {
180 if (entry->nr_insn != 1) {
181 error_leaf_contains_multiple_insn(entry);
183 /* table leaf entry */
184 lf_printf(file, "function_entry, 0, 0, ");
185 if ((code & generate_jumps))
186 lf_printf(file, "&&");
187 print_function_name(file,
188 entry->insns->file_entry->fields[insn_name],
189 entry->expanded_bits,
190 ((code & generate_with_icache)
191 ? function_name_prefix_icache
192 : function_name_prefix_semantics));
194 else if (entry->opcode_rule->gen == switch_gen
195 || entry->opcode_rule->gen == goto_switch_gen
196 || entry->opcode_rule->gen == padded_switch_gen) {
197 /* table calling switch statement */
198 lf_printf(file, "function_entry, 0, 0, ");
199 if ((code & generate_jumps))
200 lf_printf(file, "&&");
201 lf_print_table_name(file, entry);
203 else if (entry->opcode->is_boolean) {
204 /* table `calling' boolean table */
205 lf_printf(file, "boolean_entry, ");
206 lf_printf(file, "MASK32(%d, %d), ",
207 i2target(hi_bit_nr, entry->opcode->first),
208 i2target(hi_bit_nr, entry->opcode->last));
209 lf_printf(file, "INSERTED32(%d, %d, %d), ",
210 entry->opcode->boolean_constant,
211 i2target(hi_bit_nr, entry->opcode->first),
212 i2target(hi_bit_nr, entry->opcode->last));
213 lf_print_table_name(file, entry);
216 /* table `calling' another table */
217 lf_printf(file, "%d, ", insn_bit_size - entry->opcode->last - 1);
218 lf_printf(file, "MASK%d(%d,%d), ",
220 i2target(hi_bit_nr, entry->opcode->first),
221 i2target(hi_bit_nr, entry->opcode->last));
222 lf_printf(file, "0, ");
223 lf_print_table_name(file, entry);
225 lf_printf(file, " },\n");
230 print_idecode_table_end(insn_table *table,
236 if (table->opcode_rule->gen == array_gen) {
237 lf_printf(file, "};\n");
242 print_idecode_table_padding(insn_table *table,
249 if (table->opcode_rule->gen == array_gen) {
250 lf_printf(file, " /*%d*/ { function_entry, 0, 0, ", opcode_nr);
251 if ((code & generate_jumps))
252 lf_printf(file, "&&");
253 lf_printf(file, "%s_illegal },\n",
254 ((code & generate_with_icache) ? "icache" : "semantic"));
259 /****************************************************************/
263 print_goto_switch_name(lf *file,
266 lf_printf(file, "case_");
267 if (entry->opcode == NULL)
268 print_function_name(file,
269 entry->insns->file_entry->fields[insn_name],
270 entry->expanded_bits,
271 ((code & generate_with_icache)
272 ? function_name_prefix_icache
273 : function_name_prefix_semantics));
275 lf_print_table_name(file, entry);
279 print_goto_switch_table_leaf(insn_table *entry,
285 ASSERT(entry->parent != NULL);
287 ASSERT(entry->parent->opcode_rule->gen == goto_switch_gen);
288 ASSERT(entry->parent->opcode);
290 lf_printf(file, "&&");
291 print_goto_switch_name(file, entry);
292 lf_printf(file, ",\n");
296 print_goto_switch_table_padding(insn_table *table,
303 ASSERT(table->opcode_rule->gen == goto_switch_gen);
305 lf_printf(file, "&&illegal_");
306 lf_print_table_name(file, table);
307 lf_printf(file, ",\n");
311 print_goto_switch_break(lf *file,
314 lf_printf(file, "goto break_");
315 lf_print_table_name(file, entry->parent);
316 lf_printf(file, ";\n");
321 print_goto_switch_table(lf *file,
324 lf_printf(file, "const static void *");
325 lf_print_table_name(file, table);
326 lf_printf(file, "[] = {\n");
328 insn_table_traverse_tree(table,
332 print_goto_switch_table_leaf,
334 print_goto_switch_table_padding);
336 lf_printf(file, "};\n");
340 void print_idecode_switch
346 print_idecode_switch_start(insn_table *table,
351 /* const char *result = data; */
353 ASSERT(table->opcode_rule->gen == switch_gen
354 || table->opcode_rule->gen == goto_switch_gen
355 || table->opcode_rule->gen == padded_switch_gen);
357 if (table->opcode->is_boolean
358 || table->opcode_rule->gen == switch_gen
359 || table->opcode_rule->gen == padded_switch_gen) {
360 lf_printf(file, "switch (EXTRACTED%d(instruction, %d, %d)) {\n",
362 i2target(hi_bit_nr, table->opcode->first),
363 i2target(hi_bit_nr, table->opcode->last));
365 else if (table->opcode_rule->gen == goto_switch_gen) {
366 if (table->parent != NULL
367 && (table->parent->opcode_rule->gen == switch_gen
368 || table->parent->opcode_rule->gen == goto_switch_gen
369 || table->parent->opcode_rule->gen == padded_switch_gen)) {
370 lf_printf(file, "{\n");
373 print_goto_switch_table(file, table);
374 lf_printf(file, "ASSERT(EXTRACTED%d(instruction, %d, %d)\n",
376 i2target(hi_bit_nr, table->opcode->first),
377 i2target(hi_bit_nr, table->opcode->last));
378 lf_printf(file, " < (sizeof(");
379 lf_print_table_name(file, table);
380 lf_printf(file, ") / sizeof(void*)));\n");
381 lf_printf(file, "goto *");
382 lf_print_table_name(file, table);
383 lf_printf(file, "[EXTRACTED%d(instruction, %d, %d)];\n",
385 i2target(hi_bit_nr, table->opcode->first),
386 i2target(hi_bit_nr, table->opcode->last));
389 ASSERT("bad switch" == NULL);
395 print_idecode_switch_leaf(insn_table *entry,
401 const char *result = data;
402 ASSERT(entry->parent != NULL);
404 ASSERT(entry->parent->opcode_rule->gen == switch_gen
405 || entry->parent->opcode_rule->gen == goto_switch_gen
406 || entry->parent->opcode_rule->gen == padded_switch_gen);
407 ASSERT(entry->parent->opcode);
409 if (entry->parent->opcode->is_boolean
410 && entry->opcode_nr == 0) {
411 /* boolean false target */
412 lf_printf(file, "case %d:\n", entry->parent->opcode->boolean_constant);
414 else if (entry->parent->opcode->is_boolean
415 && entry->opcode_nr != 0) {
416 /* boolean true case */
417 lf_printf(file, "default:\n");
419 else if (entry->parent->opcode_rule->gen == switch_gen
420 || entry->parent->opcode_rule->gen == padded_switch_gen) {
422 lf_printf(file, "case %d:\n", entry->opcode_nr);
424 else if (entry->parent->opcode_rule->gen == goto_switch_gen) {
425 /* lf_indent(file, -1); */
426 print_goto_switch_name(file, entry);
427 lf_printf(file, ":\n");
428 /* lf_indent(file, +1); */
431 ASSERT("bad switch" == NULL);
435 if (entry->opcode == NULL) {
436 /* switch calling leaf */
437 if (entry->nr_insn != 1) {
438 error_leaf_contains_multiple_insn(entry);
440 if ((code & generate_jumps))
441 lf_printf(file, "goto ");
442 if ((code & generate_calls))
443 lf_printf(file, "%s ", result);
444 print_function_name(file,
445 entry->insns->file_entry->fields[insn_name],
446 entry->expanded_bits,
447 ((code & generate_with_icache)
448 ? function_name_prefix_icache
449 : function_name_prefix_semantics));
450 if ((code & generate_calls)) {
451 lf_printf(file, "(");
452 print_semantic_function_actual(file);
453 lf_printf(file, ")");
455 lf_printf(file, ";\n");
457 else if (entry->opcode_rule->gen == switch_gen
458 || entry->opcode_rule->gen == goto_switch_gen
459 || entry->opcode_rule->gen == padded_switch_gen) {
460 /* switch calling switch */
461 print_idecode_switch(file, entry, result);
464 /* switch looking up a table */
465 lf_printf(file, "{\n");
467 print_idecode_table(file, entry, result);
469 lf_printf(file, "}\n");
471 if (entry->parent->opcode->is_boolean
472 || entry->parent->opcode_rule->gen == switch_gen
473 || entry->parent->opcode_rule->gen == padded_switch_gen) {
474 lf_printf(file, "break;\n");
476 else if (entry->parent->opcode_rule->gen == goto_switch_gen) {
477 print_goto_switch_break(file, entry);
480 ASSERT("bad switch" == NULL);
488 print_idecode_switch_illegal(lf *file,
492 print_idecode_invalid(file, result, invalid_illegal);
493 lf_printf(file, "break;\n");
498 print_idecode_switch_end(insn_table *table,
503 const char *result = data;
505 ASSERT(table->opcode_rule->gen == switch_gen
506 || table->opcode_rule->gen == goto_switch_gen
507 || table->opcode_rule->gen == padded_switch_gen);
508 ASSERT(table->opcode);
510 if (table->opcode->is_boolean) {
511 lf_printf(file, "}\n");
513 else if (table->opcode_rule->gen == switch_gen
514 || table->opcode_rule->gen == padded_switch_gen) {
515 lf_printf(file, "default:\n");
516 switch (table->opcode_rule->gen) {
518 print_idecode_switch_illegal(file, result);
520 case padded_switch_gen:
521 lf_printf(file, " error(\"Internal error - bad switch generated\\n\");\n");
522 lf_printf(file, " break;\n");
525 ASSERT("bad switch" == NULL);
527 lf_printf(file, "}\n");
529 else if (table->opcode_rule->gen == goto_switch_gen) {
530 lf_printf(file, "illegal_");
531 lf_print_table_name(file, table);
532 lf_printf(file, ":\n");
533 print_idecode_invalid(file, result, invalid_illegal);
534 lf_printf(file, "break_");
535 lf_print_table_name(file, table);
536 lf_printf(file, ":;\n");
537 if (table->parent != NULL
538 && (table->parent->opcode_rule->gen == switch_gen
539 || table->parent->opcode_rule->gen == goto_switch_gen
540 || table->parent->opcode_rule->gen == padded_switch_gen)) {
542 lf_printf(file, "}\n");
546 ASSERT("bad switch" == NULL);
551 print_idecode_switch_padding(insn_table *table,
557 const char *result = data;
559 ASSERT(table->opcode_rule->gen == switch_gen
560 || table->opcode_rule->gen == goto_switch_gen
561 || table->opcode_rule->gen == padded_switch_gen);
563 switch (table->opcode_rule->gen) {
566 case padded_switch_gen:
567 lf_printf(file, "case %d:\n", opcode_nr);
568 print_idecode_switch_illegal(file, result);
570 case goto_switch_gen:
571 /* no padding needed */
574 ASSERT("bad switch" != NULL);
580 print_idecode_switch(lf *file,
584 insn_table_traverse_tree(table,
587 print_idecode_switch_start,
588 print_idecode_switch_leaf,
589 print_idecode_switch_end,
590 print_idecode_switch_padding);
595 print_idecode_switch_function_header(lf *file,
597 int is_function_definition)
599 lf_printf(file, "\n");
600 if ((code & generate_calls)) {
601 lf_printf(file, "static ");
602 if ((code & generate_with_icache))
603 lf_printf(file, "idecode_semantic *");
605 lf_printf(file, "unsigned_word");
606 if (is_function_definition)
607 lf_printf(file, "\n");
609 lf_printf(file, " ");
610 lf_print_table_name(file, table);
611 lf_printf(file, "\n(");
612 print_icache_function_formal(file);
613 lf_printf(file, ")");
614 if (!is_function_definition)
615 lf_printf(file, ";");
616 lf_printf(file, "\n");
618 if ((code & generate_jumps) && is_function_definition) {
620 lf_print_table_name(file, table);
621 lf_printf(file, ":\n");
628 idecode_declare_if_switch(insn_table *table,
633 if ((table->opcode_rule->gen == switch_gen
634 || table->opcode_rule->gen == goto_switch_gen
635 || table->opcode_rule->gen == padded_switch_gen)
636 && table->parent != NULL /* don't declare the top one yet */
637 && table->parent->opcode_rule->gen == array_gen) {
638 print_idecode_switch_function_header(file,
640 0/*isnt function definition*/);
646 idecode_expand_if_switch(insn_table *table,
651 if ((table->opcode_rule->gen == switch_gen
652 || table->opcode_rule->gen == goto_switch_gen
653 || table->opcode_rule->gen == padded_switch_gen)
654 && table->parent != NULL /* don't expand the top one yet */
655 && table->parent->opcode_rule->gen == array_gen) {
656 print_idecode_switch_function_header(file,
658 1/*is function definition*/);
659 if ((code & generate_calls)) {
660 lf_printf(file, "{\n");
663 print_idecode_switch(file, table, "return");
664 if ((code & generate_calls)) {
666 lf_printf(file, "}\n");
672 /****************************************************************/
676 print_idecode_lookups(lf *file,
678 cache_table *cache_rules)
682 /* output switch function declarations where needed by tables */
683 insn_table_traverse_tree(table,
686 idecode_declare_if_switch, /* START */
689 /* output tables where needed */
690 for (depth = insn_table_depth(table);
693 insn_table_traverse_tree(table,
696 print_idecode_table_start,
697 print_idecode_table_leaf,
698 print_idecode_table_end,
699 print_idecode_table_padding);
702 /* output switch functions where needed */
703 insn_table_traverse_tree(table,
706 idecode_expand_if_switch, /* START */
712 print_idecode_body(lf *file,
716 if (table->opcode_rule->gen == switch_gen
717 || table->opcode_rule->gen == goto_switch_gen
718 || table->opcode_rule->gen == padded_switch_gen)
719 print_idecode_switch(file, table, result);
721 print_idecode_table(file, table, result);
725 /****************************************************************/
729 print_idecode_issue_function_body(lf *file,
733 lf_printf(file, "{\n");
735 lf_printf(file, "address_word nia;\n");
736 if (!(code & generate_with_icache)) {
737 print_idecode_body(file, table, "nia =");;
740 error("FIXME - idecode with cache?\n");
741 lf_putstr(file, "idecode_cache *cache_entry =\n");
742 lf_putstr(file, " cpu_icache_entry(processor, cia);\n");
743 lf_putstr(file, "if (cache_entry->address == cia) {\n");
744 lf_putstr(file, " /* cache hit */\n");
745 lf_putstr(file, " idecode_semantic *const semantic = cache_entry->semantic;\n");
746 lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n");
749 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
750 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
752 lf_putstr(file, "}\n");
753 lf_putstr(file, "else {\n");
754 lf_putstr(file, " /* cache miss */\n");
755 if (!(code & generate_with_semantic_icache)) {
757 lf_putstr(file, "idecode_semantic *semantic;\n");
760 lf_putstr(file, " instruction_word instruction =\n");
761 lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
762 lf_putstr(file, " if (WITH_MON != 0)\n");
763 lf_putstr(file, " mon_event(mon_event_icache_miss, processor, cia);\n");
764 if ((code & generate_with_semantic_icache)) {
765 lf_putstr(file, "{\n");
767 print_idecode_body(file, table, "cia =");
769 lf_putstr(file, "}\n");
772 print_idecode_body(file, table, "semantic =");
773 lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n");
775 lf_putstr(file, "}\n");
777 lf_printf(file, "return nia;\n");
779 lf_printf(file, "}\n");
783 /****************************************************************/
790 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
791 lf_putstr(file, " cpu_halt(processor, nia, was_continuing, 0/*na*/);\n");
795 lf_putstr(file, "if (WITH_EVENTS) {\n");
796 lf_putstr(file, " if (event_queue_tick(events)) {\n");
797 lf_putstr(file, " cpu_set_program_counter(processor, nia);\n");
798 lf_putstr(file, " event_queue_process(events);\n");
799 lf_putstr(file, " nia = cpu_get_program_counter(processor);\n");
800 lf_putstr(file, " }\n");
801 lf_putstr(file, "}\n");
806 lf_putstr(file, "cpu_set_program_counter(processor, nia);\n");
807 lf_putstr(file, "if (WITH_EVENTS) {\n");
808 lf_putstr(file, " current_cpu += 1;\n");
809 lf_putstr(file, " if (current_cpu >= nr_cpus) {\n");
810 lf_putstr(file, " if (event_queue_tick(events)) {\n");
811 lf_putstr(file, " event_queue_process(events);\n");
812 lf_putstr(file, " }\n");
813 lf_putstr(file, " current_cpu = 0;\n");
814 lf_putstr(file, " }\n");
815 lf_putstr(file, "}\n");
816 lf_putstr(file, "else {\n");
817 lf_putstr(file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
818 lf_putstr(file, "}\n");
819 lf_putstr(file, "processor = processors[current_cpu];\n");
820 lf_putstr(file, "nia = cpu_get_program_counter(processor);\n");
823 if ((code & generate_with_icache)) {
824 lf_putstr(file, "cache_entry = cpu_icache_entry(processor, nia);\n");
825 lf_putstr(file, "if (cache_entry->address == nia) {\n");
826 lf_putstr(file, " /* cache hit */\n");
827 lf_putstr(file, " goto *cache_entry->semantic;\n");
828 lf_putstr(file, "}\n");
830 lf_putstr(file, "goto cache_miss;\n");
834 if (!(code & generate_with_icache) && is_tail) {
835 lf_printf(file, "goto idecode;\n");
845 print_jump_insn(lf *file,
847 insn_bits *expanded_bits,
848 opcode_field *opcodes,
849 cache_table *cache_rules)
852 /* what we are for the moment */
853 lf_printf(file, "\n");
854 print_my_defines(file, expanded_bits, instruction->file_entry);
856 /* output the icache entry */
857 if ((code & generate_with_icache)) {
858 lf_printf(file, "\n");
860 print_function_name(file,
861 instruction->file_entry->fields[insn_name],
863 function_name_prefix_icache);
864 lf_printf(file, ":\n");
866 lf_printf(file, "{\n");
868 lf_putstr(file, "const unsigned_word cia = nia;\n");
869 print_itrace(file, instruction->file_entry, 1/*putting-value-in-cache*/);
870 print_idecode_validate(file, instruction, opcodes);
871 lf_printf(file, "\n");
872 lf_printf(file, "{\n");
874 print_icache_body(file,
879 put_values_in_icache);
880 lf_printf(file, "cache_entry->address = nia;\n");
881 lf_printf(file, "cache_entry->semantic = &&");
882 print_function_name(file,
883 instruction->file_entry->fields[insn_name],
885 function_name_prefix_semantics);
886 lf_printf(file, ";\n");
887 if ((code & generate_with_semantic_icache)) {
888 print_semantic_body(file,
892 print_jump(file, 1/*is-tail*/);
895 lf_printf(file, "/* goto ");
896 print_function_name(file,
897 instruction->file_entry->fields[insn_name],
899 function_name_prefix_semantics);
900 lf_printf(file, "; */\n");
903 lf_putstr(file, "}\n");
905 lf_printf(file, "}\n");
908 /* print the semantics */
909 lf_printf(file, "\n");
911 print_function_name(file,
912 instruction->file_entry->fields[insn_name],
914 function_name_prefix_semantics);
915 lf_printf(file, ":\n");
917 lf_printf(file, "{\n");
919 lf_putstr(file, "const unsigned_word cia = nia;\n");
920 print_icache_body(file,
924 ((code & generate_with_direct_access)
926 : declare_variables),
927 ((code & generate_with_icache)
928 ? get_values_from_icache
929 : do_not_use_icache));
930 print_semantic_body(file,
934 if (code & generate_with_direct_access)
935 print_icache_body(file,
940 ((code & generate_with_icache)
941 ? get_values_from_icache
942 : do_not_use_icache));
943 print_jump(file, 1/*is tail*/);
945 lf_printf(file, "}\n");
949 print_jump_definition(insn_table *entry,
955 cache_table *cache_rules = (cache_table*)data;
956 if (generate_expanded_instructions) {
957 ASSERT(entry->nr_insn == 1
958 && entry->opcode == NULL
959 && entry->parent != NULL
960 && entry->parent->opcode != NULL);
961 ASSERT(entry->nr_insn == 1
962 && entry->opcode == NULL
963 && entry->parent != NULL
964 && entry->parent->opcode != NULL
965 && entry->parent->opcode_rule != NULL);
966 print_jump_insn(file,
968 entry->expanded_bits,
973 print_jump_insn(file,
983 print_jump_internal_function(insn_table *table,
986 table_entry *function)
988 if (it_is("internal", function->fields[insn_flags])) {
989 lf_printf(file, "\n");
990 table_entry_print_cpp_line_nr(file, function);
992 print_function_name(file,
993 function->fields[insn_name],
995 ((code & generate_with_icache)
996 ? function_name_prefix_icache
997 : function_name_prefix_semantics));
998 lf_printf(file, ":\n");
1000 lf_printf(file, "{\n");
1001 lf_indent(file, +2);
1002 lf_printf(file, "const unsigned_word cia = nia;\n");
1003 lf_print__c_code(file, function->annex);
1004 lf_print__internal_reference(file);
1005 lf_printf(file, "error(\"Internal function must longjump\\n\");\n");
1006 lf_indent(file, -2);
1007 lf_printf(file, "}\n");
1012 print_jump_until_stop_body(lf *file,
1014 cache_table *cache_rules,
1017 lf_printf(file, "{\n");
1018 lf_indent(file, +2);
1020 lf_printf(file, "int *keep_running = NULL;\n");
1021 lf_putstr(file, "jmp_buf halt;\n");
1022 lf_putstr(file, "jmp_buf restart;\n");
1023 lf_putstr(file, "cpu *processor = NULL;\n");
1024 lf_putstr(file, "unsigned_word nia = -1;\n");
1025 lf_putstr(file, "instruction_word instruction = 0;\n");
1026 if ((code & generate_with_icache)) {
1027 lf_putstr(file, "idecode_cache *cache_entry = NULL;\n");
1030 lf_putstr(file, "int current_cpu = -1;\n");
1033 /* all the switches and tables - they know about jumping */
1034 print_idecode_lookups(file, table, cache_rules);
1036 /* start the simulation up */
1037 if ((code & generate_with_icache)) {
1038 lf_putstr(file, "\n");
1039 lf_putstr(file, "{\n");
1040 lf_putstr(file, " int cpu_nr;\n");
1041 lf_putstr(file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
1042 lf_putstr(file, " cpu_flush_icache(processors[cpu_nr]);\n");
1043 lf_putstr(file, "}\n");
1046 lf_putstr(file, "\n");
1047 lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1049 lf_putstr(file, "\n");
1050 lf_putstr(file, "if (setjmp(halt))\n");
1051 lf_putstr(file, " return;\n");
1053 lf_putstr(file, "\n");
1054 lf_putstr(file, "setjmp(restart);\n");
1056 lf_putstr(file, "\n");
1057 if (!generate_smp) {
1058 lf_putstr(file, "processor = processors[0];\n");
1059 lf_putstr(file, "nia = cpu_get_program_counter(processor);\n");
1062 lf_putstr(file, "current_cpu = psim_last_cpu(system);\n");
1065 if (!(code & generate_with_icache)) {
1066 lf_printf(file, "\n");
1067 lf_indent(file, -1);
1068 lf_printf(file, "idecode:\n");
1069 lf_indent(file, +1);
1072 print_jump(file, 0/*is_tail*/);
1074 if ((code & generate_with_icache)) {
1075 lf_indent(file, -1);
1076 lf_printf(file, "cache_miss:\n");
1077 lf_indent(file, +1);
1080 lf_putstr(file, "instruction\n");
1081 lf_putstr(file, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
1082 lf_putstr(file, " processor, nia);\n");
1083 print_idecode_body(file, table, "/*IGORE*/");
1085 /* print out a table of all the internals functions */
1086 insn_table_traverse_function(table,
1088 print_jump_internal_function);
1090 /* print out a table of all the instructions */
1091 if (generate_expanded_instructions)
1092 insn_table_traverse_tree(table,
1096 print_jump_definition, /* leaf */
1098 NULL); /* padding */
1100 insn_table_traverse_insn(table,
1102 print_jump_definition);
1103 lf_indent(file, -2);
1104 lf_printf(file, "}\n");
1108 /****************************************************************/
1112 /* Output code to do any final checks on the decoded instruction.
1113 This includes things like verifying any on decoded fields have the
1114 correct value and checking that (for floating point) floating point
1115 hardware isn't disabled */
1118 print_idecode_validate(lf *file,
1120 opcode_field *opcodes)
1122 /* Validate: unchecked instruction fields
1124 If any constant fields in the instruction were not checked by the
1125 idecode tables, output code to check that they have the correct
1128 insn_int check_mask = 0;
1129 insn_int check_val = 0;
1131 opcode_field *opcode;
1133 /* form check_mask/check_val containing what needs to be checked
1134 in the instruction */
1135 for (field = instruction->fields->first;
1136 field->first < insn_bit_size;
1137 field = field->next) {
1139 check_mask <<= field->width;
1140 check_val <<= field->width;
1142 /* is it a constant that could need validating? */
1143 if (!field->is_int && !field->is_reserved)
1146 /* has it been checked by a table? */
1147 for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
1148 if (field->first >= opcode->first
1149 && field->last <= opcode->last)
1155 check_mask |= (1 << field->width)-1;
1156 check_val |= field->val_int;
1159 /* if any bits not checked by opcode tables, output code to check them */
1161 lf_printf(file, "\n");
1162 lf_indent_suppress(file);
1163 lf_printf(file, "#if defined(WITH_RESERVED_BITS)\n");
1164 lf_printf(file, "/* validate: %s */\n",
1165 instruction->file_entry->fields[insn_format]);
1166 lf_printf(file, "if (WITH_RESERVED_BITS\n");
1167 if (insn_bit_size > 32) {
1168 lf_printf(file, " && (instruction & 0x%08x%08xLL) != 0x%08x%08xLL) {\n",
1169 (unsigned long)(check_mask >> 32),
1170 (unsigned long)(check_mask),
1171 (unsigned long)(check_val >> 32),
1172 (unsigned long)(check_val));
1175 lf_printf(file, " && (instruction & 0x%08x) != 0x%08x) {\n",
1176 (unsigned long)(check_mask),
1177 (unsigned long)(check_val));
1179 lf_indent(file, +2);
1180 print_idecode_invalid(file, "return", invalid_illegal);
1181 lf_indent(file, -2);
1182 lf_printf(file, "}\n");
1183 lf_indent_suppress(file);
1184 lf_printf(file, "#endif\n");
1188 /* Validate: Floating Point hardware
1190 If the simulator is being built with out floating point hardware
1191 (different to it being disabled in the MSR) then floating point
1192 instructions are invalid */
1194 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1195 lf_printf(file, "\n");
1196 lf_indent_suppress(file);
1197 lf_printf(file, "#if defined(CURRENT_FLOATING_POINT\n");
1198 lf_printf(file, "/* Validate: FP hardware exists */\n");
1199 lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
1200 lf_indent(file, +2);
1201 print_idecode_invalid(file, "return", invalid_illegal);
1202 lf_indent(file, -2);
1203 lf_printf(file, "}\n");
1204 lf_indent_suppress(file);
1205 lf_printf(file, "#endif\n");
1209 /* Validate: Floating Point available
1211 If floating point is not available, we enter a floating point
1212 unavailable interrupt into the cache instead of the instruction
1215 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1216 ever a CSI occures we flush the instruction cache. */
1219 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1220 lf_printf(file, "\n");
1221 lf_indent_suppress(file);
1222 lf_printf(file, "#if defined(IS_FP_AVAILABLE)\n");
1223 lf_printf(file, "/* Validate: FP available according to processor */\n");
1224 lf_printf(file, "if (!IS_FP_AVAILABLE) {\n");
1225 lf_indent(file, +2);
1226 print_idecode_invalid(file, "return", invalid_fp_unavailable);
1227 lf_indent(file, -2);
1228 lf_printf(file, "}\n");
1229 lf_indent_suppress(file);
1230 lf_printf(file, "#endif\n");
1234 /* Validate: Validate Instruction in correct slot
1236 Some architectures place restrictions on the slot that an
1237 instruction can be issued in */
1240 if (it_is("s", instruction->file_entry->fields[insn_options])
1241 || (code & generate_with_idecode_slot_verification)) {
1242 lf_printf(file, "\n");
1243 lf_indent_suppress(file);
1244 lf_printf(file, "#if defined(IS_WRONG_SLOT)\n");
1245 lf_printf(file, "/* Validate: Instruction issued in correct slot */\n");
1246 lf_printf(file, "if (IS_WRONG_SLOT) {\n");
1247 lf_indent(file, +2);
1248 print_idecode_invalid(file, "return", invalid_wrong_slot);
1249 lf_indent(file, -2);
1250 lf_printf(file, "}\n");
1251 lf_indent_suppress(file);
1252 lf_printf(file, "#endif\n");
1259 /****************************************************************/
1263 print_idecode_issue_function_header(lf *file,
1264 int is_function_definition)
1267 lf_printf(file, "\n");
1268 lf_print_function_type_function(file, print_semantic_function_type, "INLINE_IDECODE",
1269 (is_function_definition ? "\n" : " "));
1270 indent = print_function_name(file, "issue", NULL, function_name_prefix_idecode);
1271 if (is_function_definition)
1272 lf_indent(file, +indent);
1274 lf_putstr(file, "\n");
1275 lf_putstr(file, "(");
1276 print_semantic_function_formal(file);
1277 lf_putstr(file, ")");
1278 if (is_function_definition)
1279 lf_indent(file, -indent);
1281 lf_printf(file, ";");
1282 lf_printf(file, "\n");
1287 gen_idecode_h(lf *file,
1289 cache_table *cache_rules)
1291 lf_printf(file, "typedef unsigned%d %sinstruction_word;\n",
1292 insn_bit_size, global_name_prefix);
1293 lf_printf(file, "\n");
1294 print_icache_struct(table, cache_rules, file);
1295 lf_printf(file, "\n");
1296 if ((code & generate_with_icache)) {
1297 error("FIXME - idecode with icache incomplete");
1300 print_idecode_issue_function_header(file, 0/*is definition*/);
1306 print_idecode_globals(lf *file,
1308 cache_table *cache_rules)
1310 lf_printf(file, "enum {\n");
1311 lf_printf(file, " /* greater or equal to zero => table */\n");
1312 lf_printf(file, " function_entry = -1,\n");
1313 lf_printf(file, " boolean_entry = -2,\n");
1314 lf_printf(file, "};\n");
1315 lf_printf(file, "\n");
1316 lf_printf(file, "typedef struct _idecode_table_entry {\n");
1317 lf_printf(file, " int shift;\n");
1318 lf_printf(file, " unsigned%d mask;\n", insn_bit_size);
1319 lf_printf(file, " unsigned%d value;\n", insn_bit_size);
1320 lf_printf(file, " void *function_or_table;\n");
1321 lf_printf(file, "} idecode_table_entry;\n");
1326 gen_idecode_c(lf *file,
1328 cache_table *cache_rules)
1331 lf_printf(file, "#include \"engine.h\"\n");
1332 lf_printf(file, "#include \"%sidecode.h\"\n", global_name_prefix);
1333 lf_printf(file, "#include \"%ssemantics.h\"\n", global_name_prefix);
1334 lf_printf(file, "#include \"%sicache.h\"\n", global_name_prefix);
1335 lf_printf(file, "#include \"%ssupport.h\"\n", global_name_prefix);
1336 lf_printf(file, "\n");
1337 lf_printf(file, "\n");
1339 print_idecode_globals(file, table, cache_rules);
1340 lf_printf(file, "\n");
1342 if ((code & generate_calls)) {
1344 print_idecode_lookups(file, table, cache_rules);
1346 /* output the main idecode routine */
1347 if ((code & generate_with_icache)) {
1348 error("FIXME - handle the icache");
1351 print_idecode_issue_function_header(file, 1/*is definition*/);
1352 print_idecode_issue_function_body(file, table, 0/* have stop argument */);
1356 else if ((code & generate_jumps)) {
1358 lf_printf(file, "/* this file is intentionally left blank - generating a jump engine */\n");
1362 error("Something is wrong!\n");