1 /* This file is part of the program psim.
3 Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney
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 3 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, see <http://www.gnu.org/licenses/>.
26 #include "ld-decode.h"
32 #include "gen-idecode.h"
33 #include "gen-icache.h"
34 #include "gen-semantics.h"
39 lf_print_opcodes(lf
*file
,
44 ASSERT(table
->opcode
!= NULL
);
45 lf_printf(file
, "_%d_%d",
48 if (table
->parent
== NULL
) break;
49 lf_printf(file
, "__%d", table
->opcode_nr
);
50 table
= table
->parent
;
55 /****************************************************************/
59 lf_print_table_name(lf
*file
,
62 lf_printf(file
, "idecode_table");
63 lf_print_opcodes(file
, table
);
69 print_idecode_table(lf
*file
,
73 lf_printf(file
, "/* prime the search */\n");
74 lf_printf(file
, "idecode_table_entry *table = ");
75 lf_print_table_name(file
, entry
);
76 lf_printf(file
, ";\n");
77 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
78 i2target(hi_bit_nr
, entry
->opcode
->first
),
79 i2target(hi_bit_nr
, entry
->opcode
->last
));
80 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
82 lf_printf(file
, "\n");
83 lf_printf(file
, "/* iterate until a leaf */\n");
84 lf_printf(file
, "while (1) {\n");
85 lf_printf(file
, " signed shift = table_entry->shift;\n");
86 lf_printf(file
, "if (shift == function_entry) break;\n");
87 lf_printf(file
, " if (shift >= 0) {\n");
88 lf_printf(file
, " table = ((idecode_table_entry*)\n");
89 lf_printf(file
, " table_entry->function_or_table);\n");
90 lf_printf(file
, " opcode = ((instruction & table_entry->mask)\n");
91 lf_printf(file
, " >> shift);\n");
92 lf_printf(file
, " table_entry = table + opcode;\n");
93 lf_printf(file
, " }\n");
94 lf_printf(file
, " else {\n");
95 lf_printf(file
, " /* must be a boolean */\n");
96 lf_printf(file
, " ASSERT(table_entry->shift == boolean_entry);\n");
97 lf_printf(file
, " opcode = ((instruction & table_entry->mask)\n");
98 lf_printf(file
, " != table_entry->value);\n");
99 lf_printf(file
, " table = ((idecode_table_entry*)\n");
100 lf_printf(file
, " table_entry->function_or_table);\n");
101 lf_printf(file
, " table_entry = table + opcode;\n");
102 lf_printf(file
, " }\n");
103 lf_printf(file
, "}\n");
105 lf_printf(file
, "\n");
106 lf_printf(file
, "/* call the leaf code */\n");
107 if ((code
& generate_jumps
)) {
108 lf_printf(file
, "goto *table_entry->function_or_table;\n");
111 lf_printf(file
, "%s ", result
);
112 if ((code
& generate_with_icache
)) {
113 lf_printf(file
, "(((idecode_icache*)table_entry->function_or_table)\n");
114 lf_printf(file
, " (%s));\n", ICACHE_FUNCTION_ACTUAL
);
117 lf_printf(file
, "((idecode_semantic*)table_entry->function_or_table)\n");
118 lf_printf(file
, " (%s);\n", SEMANTIC_FUNCTION_ACTUAL
);
125 print_idecode_table_start(insn_table
*table
,
131 /* start of the table */
132 if (table
->opcode_rule
->gen
== array_gen
) {
133 lf_printf(file
, "\n");
134 lf_printf(file
, "static idecode_table_entry ");
135 lf_print_table_name(file
, table
);
136 lf_printf(file
, "[] = {\n");
141 print_idecode_table_leaf(insn_table
*entry
,
147 ASSERT(entry
->parent
!= NULL
);
150 /* add an entry to the table */
151 if (entry
->parent
->opcode_rule
->gen
== array_gen
) {
152 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
153 if (entry
->opcode
== NULL
) {
154 /* table leaf entry */
155 lf_printf(file
, "function_entry, 0, 0, ");
156 if ((code
& generate_jumps
))
157 lf_printf(file
, "&&");
158 print_function_name(file
,
159 entry
->insns
->file_entry
->fields
[insn_name
],
160 entry
->expanded_bits
,
161 ((code
& generate_with_icache
)
162 ? function_name_prefix_icache
163 : function_name_prefix_semantics
));
165 else if (entry
->opcode_rule
->gen
== switch_gen
166 || entry
->opcode_rule
->gen
== goto_switch_gen
167 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
168 /* table calling switch statement */
169 lf_printf(file
, "function_entry, 0, 0, ");
170 if ((code
& generate_jumps
))
171 lf_printf(file
, "&&");
172 lf_print_table_name(file
, entry
);
174 else if (entry
->opcode
->is_boolean
) {
175 /* table `calling' boolean table */
176 lf_printf(file
, "boolean_entry, ");
177 lf_printf(file
, "MASK32(%d, %d), ",
178 i2target(hi_bit_nr
, entry
->opcode
->first
),
179 i2target(hi_bit_nr
, entry
->opcode
->last
));
180 lf_printf(file
, "INSERTED32(%d, %d, %d), ",
181 entry
->opcode
->boolean_constant
,
182 i2target(hi_bit_nr
, entry
->opcode
->first
),
183 i2target(hi_bit_nr
, entry
->opcode
->last
));
184 lf_print_table_name(file
, entry
);
187 /* table `calling' another table */
188 lf_printf(file
, "%d, ", insn_bit_size
- entry
->opcode
->last
- 1);
189 lf_printf(file
, "MASK32(%d,%d), ",
190 i2target(hi_bit_nr
, entry
->opcode
->first
),
191 i2target(hi_bit_nr
, entry
->opcode
->last
));
192 lf_printf(file
, "0, ");
193 lf_print_table_name(file
, entry
);
195 lf_printf(file
, " },\n");
200 print_idecode_table_end(insn_table
*table
,
206 if (table
->opcode_rule
->gen
== array_gen
) {
207 lf_printf(file
, "};\n");
212 print_idecode_table_padding(insn_table
*table
,
219 if (table
->opcode_rule
->gen
== array_gen
) {
220 lf_printf(file
, " /*%d*/ { function_entry, 0, 0, ", opcode_nr
);
221 if ((code
& generate_jumps
))
222 lf_printf(file
, "&&");
223 lf_printf(file
, "%s_illegal },\n",
224 ((code
& generate_with_icache
) ? "icache" : "semantic"));
229 /****************************************************************/
233 print_goto_switch_name(lf
*file
,
236 lf_printf(file
, "case_");
237 if (entry
->opcode
== NULL
)
238 print_function_name(file
,
239 entry
->insns
->file_entry
->fields
[insn_name
],
240 entry
->expanded_bits
,
241 ((code
& generate_with_icache
)
242 ? function_name_prefix_icache
243 : function_name_prefix_semantics
));
245 lf_print_table_name(file
, entry
);
249 print_goto_switch_table_leaf(insn_table
*entry
,
255 ASSERT(entry
->parent
!= NULL
);
257 ASSERT(entry
->parent
->opcode_rule
->gen
== goto_switch_gen
);
258 ASSERT(entry
->parent
->opcode
);
260 lf_printf(file
, "&&");
261 print_goto_switch_name(file
, entry
);
262 lf_printf(file
, ",\n");
266 print_goto_switch_table_padding(insn_table
*table
,
273 ASSERT(table
->opcode_rule
->gen
== goto_switch_gen
);
275 lf_printf(file
, "&&illegal_");
276 lf_print_table_name(file
, table
);
277 lf_printf(file
, ",\n");
281 print_goto_switch_break(lf
*file
,
284 lf_printf(file
, "goto break_");
285 lf_print_table_name(file
, entry
->parent
);
286 lf_printf(file
, ";\n");
291 print_goto_switch_table(lf
*file
,
294 lf_printf(file
, "const static void *");
295 lf_print_table_name(file
, table
);
296 lf_printf(file
, "[] = {\n");
298 insn_table_traverse_tree(table
,
302 print_goto_switch_table_leaf
,
304 print_goto_switch_table_padding
);
306 lf_printf(file
, "};\n");
310 void print_idecode_switch
316 idecode_switch_start(insn_table
*table
,
321 /* const char *result = data; */
323 ASSERT(table
->opcode_rule
->gen
== switch_gen
324 || table
->opcode_rule
->gen
== goto_switch_gen
325 || table
->opcode_rule
->gen
== padded_switch_gen
);
327 if (table
->opcode
->is_boolean
328 || table
->opcode_rule
->gen
== switch_gen
329 || table
->opcode_rule
->gen
== padded_switch_gen
) {
330 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
331 i2target(hi_bit_nr
, table
->opcode
->first
),
332 i2target(hi_bit_nr
, table
->opcode
->last
));
334 else if (table
->opcode_rule
->gen
== goto_switch_gen
) {
335 if (table
->parent
!= NULL
336 && (table
->parent
->opcode_rule
->gen
== switch_gen
337 || table
->parent
->opcode_rule
->gen
== goto_switch_gen
338 || table
->parent
->opcode_rule
->gen
== padded_switch_gen
)) {
339 lf_printf(file
, "{\n");
342 print_goto_switch_table(file
, table
);
343 lf_printf(file
, "ASSERT(EXTRACTED32(instruction, %d, %d)\n",
344 i2target(hi_bit_nr
, table
->opcode
->first
),
345 i2target(hi_bit_nr
, table
->opcode
->last
));
346 lf_printf(file
, " < (sizeof(");
347 lf_print_table_name(file
, table
);
348 lf_printf(file
, ") / sizeof(void*)));\n");
349 lf_printf(file
, "goto *");
350 lf_print_table_name(file
, table
);
351 lf_printf(file
, "[EXTRACTED32(instruction, %d, %d)];\n",
352 i2target(hi_bit_nr
, table
->opcode
->first
),
353 i2target(hi_bit_nr
, table
->opcode
->last
));
356 ASSERT("bad switch" == NULL
);
362 idecode_switch_leaf(insn_table
*entry
,
368 const char *result
= data
;
369 ASSERT(entry
->parent
!= NULL
);
371 ASSERT(entry
->parent
->opcode_rule
->gen
== switch_gen
372 || entry
->parent
->opcode_rule
->gen
== goto_switch_gen
373 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
);
374 ASSERT(entry
->parent
->opcode
);
376 if (entry
->parent
->opcode
->is_boolean
377 && entry
->opcode_nr
== 0) {
378 /* boolean false target */
379 lf_printf(file
, "case %d:\n", entry
->parent
->opcode
->boolean_constant
);
381 else if (entry
->parent
->opcode
->is_boolean
382 && entry
->opcode_nr
!= 0) {
383 /* boolean true case */
384 lf_printf(file
, "default:\n");
386 else if (entry
->parent
->opcode_rule
->gen
== switch_gen
387 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
) {
389 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
391 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
) {
392 /* lf_indent(file, -1); */
393 print_goto_switch_name(file
, entry
);
394 lf_printf(file
, ":\n");
395 /* lf_indent(file, +1); */
398 ASSERT("bad switch" == NULL
);
402 if (entry
->opcode
== NULL
) {
403 /* switch calling leaf */
404 if ((code
& generate_jumps
))
405 lf_printf(file
, "goto ");
406 if ((code
& generate_calls
))
407 lf_printf(file
, "%s ", result
);
408 print_function_name(file
,
409 entry
->insns
->file_entry
->fields
[insn_name
],
410 entry
->expanded_bits
,
411 ((code
& generate_with_icache
)
412 ? function_name_prefix_icache
413 : function_name_prefix_semantics
));
414 if ((code
& generate_calls
))
415 lf_printf(file
, "(%s)", SEMANTIC_FUNCTION_ACTUAL
);
416 lf_printf(file
, ";\n");
418 else if (entry
->opcode_rule
->gen
== switch_gen
419 || entry
->opcode_rule
->gen
== goto_switch_gen
420 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
421 /* switch calling switch */
422 print_idecode_switch(file
, entry
, result
);
425 /* switch looking up a table */
426 lf_printf(file
, "{\n");
428 print_idecode_table(file
, entry
, result
);
430 lf_printf(file
, "}\n");
432 if (entry
->parent
->opcode
->is_boolean
433 || entry
->parent
->opcode_rule
->gen
== switch_gen
434 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
) {
435 lf_printf(file
, "break;\n");
437 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
) {
438 print_goto_switch_break(file
, entry
);
441 ASSERT("bad switch" == NULL
);
449 print_idecode_switch_illegal(lf
*file
,
453 print_idecode_illegal(file
, result
);
454 lf_printf(file
, "break;\n");
459 idecode_switch_end(insn_table
*table
,
464 const char *result
= data
;
466 ASSERT(table
->opcode_rule
->gen
== switch_gen
467 || table
->opcode_rule
->gen
== goto_switch_gen
468 || table
->opcode_rule
->gen
== padded_switch_gen
);
469 ASSERT(table
->opcode
);
471 if (table
->opcode
->is_boolean
) {
472 lf_printf(file
, "}\n");
474 else if (table
->opcode_rule
->gen
== switch_gen
475 || table
->opcode_rule
->gen
== padded_switch_gen
) {
476 lf_printf(file
, "default:\n");
477 switch (table
->opcode_rule
->gen
) {
479 print_idecode_switch_illegal(file
, result
);
481 case padded_switch_gen
:
482 lf_printf(file
, " error(\"Internal error - bad switch generated\\n\");\n");
483 lf_printf(file
, " break;\n");
486 ASSERT("bad switch" == NULL
);
488 lf_printf(file
, "}\n");
490 else if (table
->opcode_rule
->gen
== goto_switch_gen
) {
491 lf_printf(file
, "illegal_");
492 lf_print_table_name(file
, table
);
493 lf_printf(file
, ":\n");
494 print_idecode_illegal(file
, result
);
495 lf_printf(file
, "break_");
496 lf_print_table_name(file
, table
);
497 lf_printf(file
, ":;\n");
498 if (table
->parent
!= NULL
499 && (table
->parent
->opcode_rule
->gen
== switch_gen
500 || table
->parent
->opcode_rule
->gen
== goto_switch_gen
501 || table
->parent
->opcode_rule
->gen
== padded_switch_gen
)) {
503 lf_printf(file
, "}\n");
507 ASSERT("bad switch" == NULL
);
512 idecode_switch_padding(insn_table
*table
,
518 const char *result
= data
;
520 ASSERT(table
->opcode_rule
->gen
== switch_gen
521 || table
->opcode_rule
->gen
== goto_switch_gen
522 || table
->opcode_rule
->gen
== padded_switch_gen
);
524 switch (table
->opcode_rule
->gen
) {
527 case padded_switch_gen
:
528 lf_printf(file
, "case %d:\n", opcode_nr
);
529 print_idecode_switch_illegal(file
, result
);
531 case goto_switch_gen
:
532 /* no padding needed */
535 ASSERT("bad switch" != NULL
);
541 print_idecode_switch(lf
*file
,
545 insn_table_traverse_tree(table
,
548 idecode_switch_start
,
551 idecode_switch_padding
);
556 print_idecode_switch_function_header(lf
*file
,
558 int is_function_definition
)
560 lf_printf(file
, "\n");
561 if ((code
& generate_calls
)) {
562 lf_printf(file
, "static ");
563 if ((code
& generate_with_icache
))
564 lf_printf(file
, "idecode_semantic *");
566 lf_printf(file
, "unsigned_word");
567 if (is_function_definition
)
568 lf_printf(file
, "\n");
570 lf_printf(file
, " ");
571 lf_print_table_name(file
, table
);
572 lf_printf(file
, "\n(%s)", ICACHE_FUNCTION_FORMAL
);
573 if (!is_function_definition
)
574 lf_printf(file
, ";");
575 lf_printf(file
, "\n");
577 if ((code
& generate_jumps
) && is_function_definition
) {
579 lf_print_table_name(file
, table
);
580 lf_printf(file
, ":\n");
587 idecode_declare_if_switch(insn_table
*table
,
592 if ((table
->opcode_rule
->gen
== switch_gen
593 || table
->opcode_rule
->gen
== goto_switch_gen
594 || table
->opcode_rule
->gen
== padded_switch_gen
)
595 && table
->parent
!= NULL
/* don't declare the top one yet */
596 && table
->parent
->opcode_rule
->gen
== array_gen
) {
597 print_idecode_switch_function_header(file
,
599 0/*isnt function definition*/);
605 idecode_expand_if_switch(insn_table
*table
,
610 if ((table
->opcode_rule
->gen
== switch_gen
611 || table
->opcode_rule
->gen
== goto_switch_gen
612 || table
->opcode_rule
->gen
== padded_switch_gen
)
613 && table
->parent
!= NULL
/* don't expand the top one yet */
614 && table
->parent
->opcode_rule
->gen
== array_gen
) {
615 print_idecode_switch_function_header(file
,
617 1/*is function definition*/);
618 if ((code
& generate_calls
)) {
619 lf_printf(file
, "{\n");
622 print_idecode_switch(file
, table
, "return");
623 if ((code
& generate_calls
)) {
625 lf_printf(file
, "}\n");
631 /****************************************************************/
635 print_idecode_lookups(lf
*file
,
637 cache_table
*cache_rules
)
641 /* output switch function declarations where needed by tables */
642 insn_table_traverse_tree(table
,
645 idecode_declare_if_switch
, /* START */
648 /* output tables where needed */
649 for (depth
= insn_table_depth(table
);
652 insn_table_traverse_tree(table
,
655 print_idecode_table_start
,
656 print_idecode_table_leaf
,
657 print_idecode_table_end
,
658 print_idecode_table_padding
);
661 /* output switch functions where needed */
662 insn_table_traverse_tree(table
,
665 idecode_expand_if_switch
, /* START */
671 print_idecode_body(lf
*file
,
675 if (table
->opcode_rule
->gen
== switch_gen
676 || table
->opcode_rule
->gen
== goto_switch_gen
677 || table
->opcode_rule
->gen
== padded_switch_gen
)
678 print_idecode_switch(file
, table
, result
);
680 print_idecode_table(file
, table
, result
);
684 /****************************************************************/
688 print_run_until_stop_body(lf
*file
,
692 /* Output the function to execute real code:
694 Unfortunatly, there are multiple cases to consider vis:
696 <icache> X <smp> X <events> X <keep-running-flag> X ...
698 Consequently this function is written in multiple different ways */
700 lf_putstr(file
, "{\n");
702 lf_putstr(file
, "jmp_buf halt;\n");
703 lf_putstr(file
, "jmp_buf restart;\n");
705 lf_putstr(file
, "cpu *processor = NULL;\n");
706 lf_putstr(file
, "unsigned_word cia = -1;\n");
708 lf_putstr(file
, "int last_cpu;\n");
710 lf_putstr(file
, "int current_cpu;\n");
713 if ((code
& generate_with_icache
)) {
714 lf_putstr(file
, "int cpu_nr;\n");
715 lf_putstr(file
, "\n");
716 lf_putstr(file
, "/* flush the icache of a possible break insn */\n");
717 lf_putstr(file
, "for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
718 lf_putstr(file
, " cpu_flush_icache(processors[cpu_nr]);\n");
721 lf_putstr(file
, "\n");
722 lf_putstr(file
, "/* set the halt target initially */\n");
723 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, NULL);\n");
724 lf_putstr(file
, "if (setjmp(halt))\n");
725 lf_putstr(file
, " return;\n");
727 lf_putstr(file
, "\n");
728 lf_putstr(file
, "/* where were we before the halt? */\n");
729 lf_putstr(file
, "last_cpu = psim_last_cpu(system);\n");
731 lf_putstr(file
, "\n");
732 lf_putstr(file
, "/* check for need to force event processing first */\n");
733 lf_putstr(file
, "if (WITH_EVENTS) {\n");
734 lf_putstr(file
, " if (last_cpu == nr_cpus) {\n");
735 lf_putstr(file
, " /* halted during event processing */\n");
736 lf_putstr(file
, " event_queue_process(events);\n");
737 lf_putstr(file
, " last_cpu = -1;\n");
738 lf_putstr(file
, " }\n");
739 lf_putstr(file
, " else if (last_cpu == nr_cpus - 1) {\n");
740 lf_putstr(file
, " /* last cpu did halt */\n");
741 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
742 lf_putstr(file
, " event_queue_process(events);\n");
743 lf_putstr(file
, " }\n");
744 lf_putstr(file
, " last_cpu = -1;\n");
745 lf_putstr(file
, " }\n");
746 lf_putstr(file
, "}\n");
747 lf_putstr(file
, "else {\n");
748 lf_putstr(file
, " if (last_cpu == nr_cpus - 1)\n");
749 lf_putstr(file
, " /* cpu zero is next */\n");
750 lf_putstr(file
, " last_cpu = -1;\n");
751 lf_putstr(file
, "}\n");
753 lf_putstr(file
, "\n");
754 lf_putstr(file
, "/* have ensured that the event queue can not be first */\n");
755 lf_putstr(file
, "ASSERT(last_cpu >= -1 && last_cpu < nr_cpus - 1);\n");
760 /* CASE 1: NO SMP (with or with out instruction cache).\n\
762 In this case, we can take advantage of the fact that the current\n\
763 instruction address does not need to be returned to the cpu object\n\
764 after every execution of an instruction. Instead it only needs to\n\
765 be saved when either A. the main loop exits or B. A cpu-halt or\n\
766 cpu-restart call forces the loop to be re-enered. The later\n\
767 functions always save the current cpu instruction address.\n\
769 Two subcases also exist that with and that without an instruction\n\
772 An additional complexity is the need to ensure that a 1:1 ratio\n\
773 is maintained between the execution of an instruction and the\n\
774 incrementing of the simulation clock */");
776 lf_putstr(file
, "\n");
778 lf_putstr(file
, "\n");
779 lf_putstr(file
, "/* now add restart target as ready to run */\n");
780 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
781 lf_putstr(file
, "if (setjmp(restart)) {\n");
782 lf_putstr(file
, " if (WITH_EVENTS) {\n");
783 lf_putstr(file
, " /* when restart, cpu must have been last, clock next */\n");
784 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
785 lf_putstr(file
, " event_queue_process(events);\n");
786 lf_putstr(file
, " }\n");
787 lf_putstr(file
, " }\n");
788 lf_putstr(file
, "}\n");
790 lf_putstr(file
, "\n");
791 lf_putstr(file
, "/* prime the main loop */\n");
792 lf_putstr(file
, "processor = processors[0];\n");
793 lf_putstr(file
, "cia = cpu_get_program_counter(processor);\n");
795 lf_putstr(file
, "\n");
796 lf_putstr(file
, "while (1) {\n");
799 if (!(code
& generate_with_icache
)) {
800 lf_putstr(file
, "instruction_word instruction =\n");
801 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
802 lf_putstr(file
, "\n");
803 print_idecode_body(file
, table
, "cia =");;
806 if ((code
& generate_with_icache
)) {
807 lf_putstr(file
, "idecode_cache *cache_entry =\n");
808 lf_putstr(file
, " cpu_icache_entry(processor, cia);\n");
809 lf_putstr(file
, "if (cache_entry->address == cia) {\n");
810 lf_putstr(file
, " /* cache hit */\n");
811 lf_putstr(file
, " idecode_semantic *const semantic = cache_entry->semantic;\n");
812 lf_putstr(file
, " cia = semantic(processor, cache_entry, cia);\n");
815 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
816 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
818 lf_putstr(file
, "}\n");
819 lf_putstr(file
, "else {\n");
820 lf_putstr(file
, " /* cache miss */\n");
821 if (!(code
& generate_with_semantic_icache
)) {
823 lf_putstr(file
, "idecode_semantic *semantic;\n");
826 lf_putstr(file
, " instruction_word instruction =\n");
827 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
828 lf_putstr(file
, " if (WITH_MON != 0)\n");
829 lf_putstr(file
, " mon_event(mon_event_icache_miss, processor, cia);\n");
830 if ((code
& generate_with_semantic_icache
)) {
831 lf_putstr(file
, "{\n");
833 print_idecode_body(file
, table
, "cia =");
835 lf_putstr(file
, "}\n");
838 print_idecode_body(file
, table
, "semantic =");
839 lf_putstr(file
, " cia = semantic(processor, cache_entry, cia);\n");
841 lf_putstr(file
, "}\n");
845 lf_putstr(file
, "\n");
846 lf_putstr(file
, "/* process any events */\n");
847 lf_putstr(file
, "if (WITH_EVENTS) {\n");
848 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
849 lf_putstr(file
, " cpu_set_program_counter(processor, cia);\n");
850 lf_putstr(file
, " event_queue_process(events);\n");
851 lf_putstr(file
, " cia = cpu_get_program_counter(processor);\n");
852 lf_putstr(file
, " }\n");
853 lf_putstr(file
, "}\n");
857 lf_putstr(file
, "\n");
858 lf_putstr(file
, "/* abort if necessary */\n");
859 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
860 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*not important*/);\n");
864 lf_putstr(file
, "}\n");
870 /* CASE 2: SMP (With or without ICACHE)\n\
872 The complexity here comes from needing to correctly restart the\n\
873 system when it is aborted. In particular if cpu0 requests a\n\
874 restart, the next cpu is still cpu1. Cpu0 being restarted after\n\
875 all the other CPU's and the event queue have been processed */");
877 lf_putstr(file
, "\n");
879 lf_putstr(file
, "\n");
880 lf_putstr(file
, "/* now establish the restart target */\n");
881 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
882 lf_putstr(file
, "if (setjmp(restart)) {\n");
883 lf_putstr(file
, " current_cpu = psim_last_cpu(system);\n");
884 lf_putstr(file
, " ASSERT(current_cpu >= 0 && current_cpu < nr_cpus);\n");
885 lf_putstr(file
, "}\n");
886 lf_putstr(file
, "else {\n");
887 lf_putstr(file
, " current_cpu = last_cpu;\n");
888 lf_putstr(file
, " ASSERT(current_cpu >= -1 && current_cpu < nr_cpus);\n");
889 lf_putstr(file
, "}\n");
892 lf_putstr(file
, "\n");
893 lf_putstr(file
, "while (1) {\n");
896 lf_putstr(file
, "\n");
897 lf_putstr(file
, "if (WITH_EVENTS) {\n");
898 lf_putstr(file
, " current_cpu += 1;\n");
899 lf_putstr(file
, " if (current_cpu == nr_cpus) {\n");
900 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
901 lf_putstr(file
, " event_queue_process(events);\n");
902 lf_putstr(file
, " }\n");
903 lf_putstr(file
, " current_cpu = 0;\n");
904 lf_putstr(file
, " }\n");
905 lf_putstr(file
, "}\n");
906 lf_putstr(file
, "else {\n");
907 lf_putstr(file
, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
908 lf_putstr(file
, "}\n");
910 lf_putstr(file
, "\n");
911 lf_putstr(file
, "{\n");
913 lf_putstr(file
, "cpu *processor = processors[current_cpu];\n");
914 lf_putstr(file
, "unsigned_word cia =\n");
915 lf_putstr(file
, " cpu_get_program_counter(processor);\n");
917 if (!(code
& generate_with_icache
)) {
918 lf_putstr(file
, "instruction_word instruction =\n");
919 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
920 print_idecode_body(file
, table
, "cia =");
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");
928 if ((code
& generate_with_icache
)) {
929 lf_putstr(file
, "idecode_cache *cache_entry =\n");
930 lf_putstr(file
, " cpu_icache_entry(processor, cia);\n");
931 lf_putstr(file
, "\n");
932 lf_putstr(file
, "if (cache_entry->address == cia) {\n");
935 lf_putstr(file
, "\n");
936 lf_putstr(file
, "/* cache hit */\n");
937 lf_putstr(file
, "idecode_semantic *semantic = cache_entry->semantic;\n");
938 lf_putstr(file
, "cia = semantic(processor, cache_entry, cia);\n");
941 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
942 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
944 lf_putstr(file
, "cpu_set_program_counter(processor, cia);\n");
945 lf_putstr(file
, "\n");
948 lf_putstr(file
, "}\n");
949 lf_putstr(file
, "else {\n");
952 lf_putstr(file
, "\n");
953 lf_putstr(file
, "/* cache miss */\n");
954 if (!(code
& generate_with_semantic_icache
)) {
955 lf_putstr(file
, "idecode_semantic *semantic;\n");
957 lf_putstr(file
, "instruction_word instruction =\n");
958 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
959 lf_putstr(file
, "if (WITH_MON != 0)\n");
960 lf_putstr(file
, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
961 if ((code
& generate_with_semantic_icache
)) {
962 lf_putstr(file
, "{\n");
964 print_idecode_body(file
, table
, "cia =");
966 lf_putstr(file
, "}\n");
969 print_idecode_body(file
, table
, "semantic = ");
970 lf_putstr(file
, "cia = semantic(processor, cache_entry, cia);\n");
974 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
975 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
977 lf_putstr(file
, "cpu_set_program_counter(processor, cia);\n");
978 lf_putstr(file
, "\n");
981 lf_putstr(file
, "}\n");
986 lf_putstr(file
, "}\n");
990 lf_putstr(file
, "}\n");
995 lf_putstr(file
, "}\n");
999 /****************************************************************/
1002 print_jump(lf
*file
,
1006 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
1007 lf_putstr(file
, " cpu_halt(processor, nia, was_continuing, 0/*na*/);\n");
1010 if (!generate_smp
) {
1011 lf_putstr(file
, "if (WITH_EVENTS) {\n");
1012 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
1013 lf_putstr(file
, " cpu_set_program_counter(processor, nia);\n");
1014 lf_putstr(file
, " event_queue_process(events);\n");
1015 lf_putstr(file
, " nia = cpu_get_program_counter(processor);\n");
1016 lf_putstr(file
, " }\n");
1017 lf_putstr(file
, "}\n");
1022 lf_putstr(file
, "cpu_set_program_counter(processor, nia);\n");
1023 lf_putstr(file
, "if (WITH_EVENTS) {\n");
1024 lf_putstr(file
, " current_cpu += 1;\n");
1025 lf_putstr(file
, " if (current_cpu >= nr_cpus) {\n");
1026 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
1027 lf_putstr(file
, " event_queue_process(events);\n");
1028 lf_putstr(file
, " }\n");
1029 lf_putstr(file
, " current_cpu = 0;\n");
1030 lf_putstr(file
, " }\n");
1031 lf_putstr(file
, "}\n");
1032 lf_putstr(file
, "else {\n");
1033 lf_putstr(file
, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
1034 lf_putstr(file
, "}\n");
1035 lf_putstr(file
, "processor = processors[current_cpu];\n");
1036 lf_putstr(file
, "nia = cpu_get_program_counter(processor);\n");
1039 if ((code
& generate_with_icache
)) {
1040 lf_putstr(file
, "cache_entry = cpu_icache_entry(processor, nia);\n");
1041 lf_putstr(file
, "if (cache_entry->address == nia) {\n");
1042 lf_putstr(file
, " /* cache hit */\n");
1043 lf_putstr(file
, " goto *cache_entry->semantic;\n");
1044 lf_putstr(file
, "}\n");
1046 lf_putstr(file
, "goto cache_miss;\n");
1050 if (!(code
& generate_with_icache
) && is_tail
) {
1051 lf_printf(file
, "goto idecode;\n");
1061 print_jump_insn(lf
*file
,
1063 insn_bits
*expanded_bits
,
1064 opcode_field
*opcodes
,
1065 cache_table
*cache_rules
)
1068 /* what we are for the moment */
1069 lf_printf(file
, "\n");
1070 print_my_defines(file
, expanded_bits
, instruction
->file_entry
);
1072 /* output the icache entry */
1073 if ((code
& generate_with_icache
)) {
1074 lf_printf(file
, "\n");
1075 lf_indent(file
, -1);
1076 print_function_name(file
,
1077 instruction
->file_entry
->fields
[insn_name
],
1079 function_name_prefix_icache
);
1080 lf_printf(file
, ":\n");
1081 lf_indent(file
, +1);
1082 lf_printf(file
, "{\n");
1083 lf_indent(file
, +2);
1084 lf_putstr(file
, "const unsigned_word cia = nia;\n");
1085 print_itrace(file
, instruction
->file_entry
, 1/*putting-value-in-cache*/);
1086 print_idecode_validate(file
, instruction
, opcodes
);
1087 lf_printf(file
, "\n");
1088 lf_printf(file
, "{\n");
1089 lf_indent(file
, +2);
1090 print_icache_body(file
,
1095 put_values_in_icache
);
1096 lf_printf(file
, "cache_entry->address = nia;\n");
1097 lf_printf(file
, "cache_entry->semantic = &&");
1098 print_function_name(file
,
1099 instruction
->file_entry
->fields
[insn_name
],
1101 function_name_prefix_semantics
);
1102 lf_printf(file
, ";\n");
1103 if ((code
& generate_with_semantic_icache
)) {
1104 print_semantic_body(file
,
1108 print_jump(file
, 1/*is-tail*/);
1111 lf_printf(file
, "/* goto ");
1112 print_function_name(file
,
1113 instruction
->file_entry
->fields
[insn_name
],
1115 function_name_prefix_semantics
);
1116 lf_printf(file
, "; */\n");
1118 lf_indent(file
, -2);
1119 lf_putstr(file
, "}\n");
1120 lf_indent(file
, -2);
1121 lf_printf(file
, "}\n");
1124 /* print the semantics */
1125 lf_printf(file
, "\n");
1126 lf_indent(file
, -1);
1127 print_function_name(file
,
1128 instruction
->file_entry
->fields
[insn_name
],
1130 function_name_prefix_semantics
);
1131 lf_printf(file
, ":\n");
1132 lf_indent(file
, +1);
1133 lf_printf(file
, "{\n");
1134 lf_indent(file
, +2);
1135 lf_putstr(file
, "const unsigned_word cia = nia;\n");
1136 print_icache_body(file
,
1140 ((code
& generate_with_direct_access
)
1142 : declare_variables
),
1143 ((code
& generate_with_icache
)
1144 ? get_values_from_icache
1145 : do_not_use_icache
));
1146 print_semantic_body(file
,
1150 if (code
& generate_with_direct_access
)
1151 print_icache_body(file
,
1156 ((code
& generate_with_icache
)
1157 ? get_values_from_icache
1158 : do_not_use_icache
));
1159 print_jump(file
, 1/*is tail*/);
1160 lf_indent(file
, -2);
1161 lf_printf(file
, "}\n");
1165 print_jump_definition(insn_table
*entry
,
1171 cache_table
*cache_rules
= (cache_table
*)data
;
1172 if (generate_expanded_instructions
) {
1173 ASSERT(entry
->nr_insn
== 1
1174 && entry
->opcode
== NULL
1175 && entry
->parent
!= NULL
1176 && entry
->parent
->opcode
!= NULL
);
1177 ASSERT(entry
->nr_insn
== 1
1178 && entry
->opcode
== NULL
1179 && entry
->parent
!= NULL
1180 && entry
->parent
->opcode
!= NULL
1181 && entry
->parent
->opcode_rule
!= NULL
);
1182 print_jump_insn(file
,
1184 entry
->expanded_bits
,
1189 print_jump_insn(file
,
1199 print_jump_internal_function(insn_table
*table
,
1202 table_entry
*function
)
1204 if (it_is("internal", function
->fields
[insn_flags
])) {
1205 lf_printf(file
, "\n");
1206 table_entry_print_cpp_line_nr(file
, function
);
1207 lf_indent(file
, -1);
1208 print_function_name(file
,
1209 function
->fields
[insn_name
],
1211 ((code
& generate_with_icache
)
1212 ? function_name_prefix_icache
1213 : function_name_prefix_semantics
));
1214 lf_printf(file
, ":\n");
1215 lf_indent(file
, +1);
1216 lf_printf(file
, "{\n");
1217 lf_indent(file
, +2);
1218 lf_printf(file
, "const unsigned_word cia = nia;\n");
1219 lf_print__c_code(file
, function
->annex
);
1220 lf_print__internal_reference(file
);
1221 lf_printf(file
, "error(\"Internal function must longjump\\n\");\n");
1222 lf_indent(file
, -2);
1223 lf_printf(file
, "}\n");
1228 print_jump_until_stop_body(lf
*file
,
1230 cache_table
*cache_rules
,
1233 lf_printf(file
, "{\n");
1234 lf_indent(file
, +2);
1236 lf_printf(file
, "int *keep_running = NULL;\n");
1237 lf_putstr(file
, "jmp_buf halt;\n");
1238 lf_putstr(file
, "jmp_buf restart;\n");
1239 lf_putstr(file
, "cpu *processor = NULL;\n");
1240 lf_putstr(file
, "unsigned_word nia = -1;\n");
1241 lf_putstr(file
, "instruction_word instruction = 0;\n");
1242 if ((code
& generate_with_icache
)) {
1243 lf_putstr(file
, "idecode_cache *cache_entry = NULL;\n");
1246 lf_putstr(file
, "int current_cpu = -1;\n");
1249 /* all the switches and tables - they know about jumping */
1250 print_idecode_lookups(file
, table
, cache_rules
);
1252 /* start the simulation up */
1253 if ((code
& generate_with_icache
)) {
1254 lf_putstr(file
, "\n");
1255 lf_putstr(file
, "{\n");
1256 lf_putstr(file
, " int cpu_nr;\n");
1257 lf_putstr(file
, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
1258 lf_putstr(file
, " cpu_flush_icache(processors[cpu_nr]);\n");
1259 lf_putstr(file
, "}\n");
1262 lf_putstr(file
, "\n");
1263 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1265 lf_putstr(file
, "\n");
1266 lf_putstr(file
, "if (setjmp(halt))\n");
1267 lf_putstr(file
, " return;\n");
1269 lf_putstr(file
, "\n");
1270 lf_putstr(file
, "setjmp(restart);\n");
1272 lf_putstr(file
, "\n");
1273 if (!generate_smp
) {
1274 lf_putstr(file
, "processor = processors[0];\n");
1275 lf_putstr(file
, "nia = cpu_get_program_counter(processor);\n");
1278 lf_putstr(file
, "current_cpu = psim_last_cpu(system);\n");
1281 if (!(code
& generate_with_icache
)) {
1282 lf_printf(file
, "\n");
1283 lf_indent(file
, -1);
1284 lf_printf(file
, "idecode:\n");
1285 lf_indent(file
, +1);
1288 print_jump(file
, 0/*is_tail*/);
1290 if ((code
& generate_with_icache
)) {
1291 lf_indent(file
, -1);
1292 lf_printf(file
, "cache_miss:\n");
1293 lf_indent(file
, +1);
1296 lf_putstr(file
, "instruction\n");
1297 lf_putstr(file
, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
1298 lf_putstr(file
, " processor, nia);\n");
1299 print_idecode_body(file
, table
, "/*IGORE*/");
1301 /* print out a table of all the internals functions */
1302 insn_table_traverse_function(table
,
1304 print_jump_internal_function
);
1306 /* print out a table of all the instructions */
1307 if (generate_expanded_instructions
)
1308 insn_table_traverse_tree(table
,
1312 print_jump_definition
, /* leaf */
1314 NULL
); /* padding */
1316 insn_table_traverse_insn(table
,
1318 print_jump_definition
);
1319 lf_indent(file
, -2);
1320 lf_printf(file
, "}\n");
1324 /****************************************************************/
1329 print_idecode_floating_point_unavailable(lf
*file
)
1331 if ((code
& generate_jumps
))
1332 lf_printf(file
, "goto %s_floating_point_unavailable;\n", (code
& generate_with_icache
) ? "icache" : "semantic");
1333 else if ((code
& generate_with_icache
))
1334 lf_printf(file
, "return icache_floating_point_unavailable(%s);\n",
1335 ICACHE_FUNCTION_ACTUAL
);
1337 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
1338 SEMANTIC_FUNCTION_ACTUAL
);
1342 /* Output code to do any final checks on the decoded instruction.
1343 This includes things like verifying any on decoded fields have the
1344 correct value and checking that (for floating point) floating point
1345 hardware isn't disabled */
1348 print_idecode_validate(lf
*file
,
1350 opcode_field
*opcodes
)
1352 /* Validate: unchecked instruction fields
1354 If any constant fields in the instruction were not checked by the
1355 idecode tables, output code to check that they have the correct
1358 unsigned check_mask
= 0;
1359 unsigned check_val
= 0;
1361 opcode_field
*opcode
;
1363 /* form check_mask/check_val containing what needs to be checked
1364 in the instruction */
1365 for (field
= instruction
->fields
->first
;
1366 field
->first
< insn_bit_size
;
1367 field
= field
->next
) {
1369 check_mask
<<= field
->width
;
1370 check_val
<<= field
->width
;
1372 /* is it a constant that could need validating? */
1373 if (!field
->is_int
&& !field
->is_slash
)
1376 /* has it been checked by a table? */
1377 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1378 if (field
->first
>= opcode
->first
1379 && field
->last
<= opcode
->last
)
1385 check_mask
|= (1 << field
->width
)-1;
1386 check_val
|= field
->val_int
;
1389 /* if any bits not checked by opcode tables, output code to check them */
1391 lf_printf(file
, "\n");
1392 lf_printf(file
, "/* validate: %s */\n",
1393 instruction
->file_entry
->fields
[insn_format
]);
1394 lf_printf(file
, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
1395 check_mask
, check_val
);
1396 lf_indent(file
, +2);
1397 print_idecode_illegal(file
, "return");
1398 lf_indent(file
, -2);
1402 /* Validate floating point hardware
1404 If the simulator is being built with out floating point hardware
1405 (different to it being disabled in the MSR) then floating point
1406 instructions are invalid */
1408 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1409 lf_printf(file
, "\n");
1410 lf_printf(file
, "/* Validate: FP hardware exists */\n");
1411 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1412 lf_indent(file
, +2);
1413 print_idecode_illegal(file
, "return");
1414 lf_indent(file
, -2);
1418 /* Validate: Floating Point available
1420 If floating point is not available, we enter a floating point
1421 unavailable interrupt into the cache instead of the instruction
1424 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1425 ever a CSI occures we flush the instruction cache. */
1428 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1429 lf_printf(file
, "\n");
1430 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
1431 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
1432 lf_indent(file
, +2);
1433 print_idecode_floating_point_unavailable(file
);
1434 lf_indent(file
, -2);
1440 /****************************************************************/
1444 print_idecode_run_function_header(lf
*file
,
1449 lf_printf(file
, "\n");
1450 lf_print_function_type(file
, "void", "PSIM_INLINE_IDECODE", (is_definition
? " " : "\n"));
1451 indent
= lf_putstr(file
, (can_stop
? "idecode_run_until_stop" : "idecode_run"));
1453 lf_putstr(file
, "\n");
1455 lf_indent(file
, +indent
);
1456 lf_putstr(file
, "(psim *system,\n");
1458 lf_putstr(file
, " volatile int *keep_running,\n");
1459 lf_printf(file
, " event_queue *events,\n");
1460 lf_putstr(file
, " cpu *const processors[],\n");
1461 lf_putstr(file
, " const int nr_cpus)");
1463 lf_putstr(file
, ";");
1465 lf_indent(file
, -indent
);
1466 lf_putstr(file
, "\n");
1471 gen_idecode_h(lf
*file
,
1473 cache_table
*cache_rules
)
1475 lf_printf(file
, "/* The idecode_*.h functions shall move to support */\n");
1476 lf_printf(file
, "#include \"idecode_expression.h\"\n");
1477 lf_printf(file
, "#include \"idecode_fields.h\"\n");
1478 lf_printf(file
, "#include \"idecode_branch.h\"\n");
1479 lf_printf(file
, "\n");
1480 print_icache_struct(table
, cache_rules
, file
);
1481 lf_printf(file
, "\n");
1482 lf_printf(file
, "#define WITH_IDECODE_SMP %d\n", generate_smp
);
1483 lf_printf(file
, "\n");
1484 print_idecode_run_function_header(file
, 0/*can stop*/, 1/*is definition*/);
1485 print_idecode_run_function_header(file
, 1/*can stop*/, 1/*is definition*/);
1490 gen_idecode_c(lf
*file
,
1492 cache_table
*cache_rules
)
1495 lf_printf(file
, "#include \"inline.c\"\n");
1496 lf_printf(file
, "\n");
1497 lf_printf(file
, "#include \"cpu.h\"\n");
1498 lf_printf(file
, "#include \"idecode.h\"\n");
1499 lf_printf(file
, "#include \"semantics.h\"\n");
1500 lf_printf(file
, "#include \"icache.h\"\n");
1501 lf_printf(file
, "#ifdef HAVE_COMMON_FPU\n");
1502 lf_printf(file
, "#include \"sim-inline.h\"\n");
1503 lf_printf(file
, "#include \"sim-fpu.h\"\n");
1504 lf_printf(file
, "#endif\n");
1505 lf_printf(file
, "#include \"support.h\"\n");
1506 lf_printf(file
, "\n");
1507 lf_printf(file
, "#include <setjmp.h>\n");
1508 lf_printf(file
, "\n");
1509 lf_printf(file
, "enum {\n");
1510 lf_printf(file
, " /* greater or equal to zero => table */\n");
1511 lf_printf(file
, " function_entry = -1,\n");
1512 lf_printf(file
, " boolean_entry = -2,\n");
1513 lf_printf(file
, "};\n");
1514 lf_printf(file
, "\n");
1515 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
1516 lf_printf(file
, " int shift;\n");
1517 lf_printf(file
, " instruction_word mask;\n");
1518 lf_printf(file
, " instruction_word value;");
1519 lf_printf(file
, " void *function_or_table;\n");
1520 lf_printf(file
, "} idecode_table_entry;\n");
1521 lf_printf(file
, "\n");
1522 lf_printf(file
, "\n");
1524 if ((code
& generate_calls
)) {
1526 print_idecode_lookups(file
, table
, cache_rules
);
1528 /* output the main idecode routine */
1529 print_idecode_run_function_header(file
, 0/*can stop*/, 0/*is definition*/);
1530 print_run_until_stop_body(file
, table
, 0/* have stop argument */);
1532 print_idecode_run_function_header(file
, 1/*can stop*/, 0/*is definition*/);
1533 print_run_until_stop_body(file
, table
, 1/* no stop argument */);
1536 else if ((code
& generate_jumps
)) {
1538 print_idecode_run_function_header(file
, 0/*can stop*/, 0/*is definition*/);
1539 print_jump_until_stop_body(file
, table
, cache_rules
, 0 /* have stop argument */);
1541 print_idecode_run_function_header(file
, 1/*can stop*/, 0/*is definition*/);
1542 print_jump_until_stop_body(file
, table
, cache_rules
, 1/* have stop argument */);
1546 error("Something is wrong!\n");