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 /****************************************************************/
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
,
74 lf_printf(file
, "/* prime the search */\n");
75 lf_printf(file
, "idecode_table_entry *table = ");
76 lf_print_table_name(file
, entry
);
77 lf_printf(file
, ";\n");
78 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
79 i2target(hi_bit_nr
, entry
->opcode
->first
),
80 i2target(hi_bit_nr
, entry
->opcode
->last
));
81 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
83 lf_printf(file
, "\n");
84 lf_printf(file
, "/* iterate until a leaf */\n");
85 lf_printf(file
, "while (1) {\n");
86 lf_printf(file
, " signed shift = table_entry->shift;\n");
87 lf_printf(file
, "if (shift == function_entry) break;\n");
88 lf_printf(file
, " if (shift >= 0) {\n");
89 lf_printf(file
, " table = ((idecode_table_entry*)\n");
90 lf_printf(file
, " table_entry->function_or_table);\n");
91 lf_printf(file
, " opcode = ((instruction & table_entry->mask)\n");
92 lf_printf(file
, " >> shift);\n");
93 lf_printf(file
, " table_entry = table + opcode;\n");
94 lf_printf(file
, " }\n");
95 lf_printf(file
, " else {\n");
96 lf_printf(file
, " /* must be a boolean */\n");
97 lf_printf(file
, " ASSERT(table_entry->shift == boolean_entry);\n");
98 lf_printf(file
, " opcode = ((instruction & table_entry->mask)\n");
99 lf_printf(file
, " != table_entry->value);\n");
100 lf_printf(file
, " table = ((idecode_table_entry*)\n");
101 lf_printf(file
, " table_entry->function_or_table);\n");
102 lf_printf(file
, " table_entry = table + opcode;\n");
103 lf_printf(file
, " }\n");
104 lf_printf(file
, "}\n");
106 lf_printf(file
, "\n");
107 lf_printf(file
, "/* call the leaf code */\n");
108 if ((code
& generate_jumps
)) {
109 lf_printf(file
, "goto *table_entry->function_or_table;\n");
112 lf_printf(file
, "%s ", result
);
113 if ((code
& generate_with_icache
)) {
114 lf_printf(file
, "(((idecode_icache*)table_entry->function_or_table)\n");
115 lf_printf(file
, " (%s));\n", ICACHE_FUNCTION_ACTUAL
);
118 lf_printf(file
, "((idecode_semantic*)table_entry->function_or_table)\n");
119 lf_printf(file
, " (%s);\n", SEMANTIC_FUNCTION_ACTUAL
);
126 print_idecode_table_start(insn_table
*table
,
132 /* start of the table */
133 if (table
->opcode_rule
->gen
== array_gen
) {
134 lf_printf(file
, "\n");
135 lf_printf(file
, "static idecode_table_entry ");
136 lf_print_table_name(file
, table
);
137 lf_printf(file
, "[] = {\n");
142 print_idecode_table_leaf(insn_table
*entry
,
148 ASSERT(entry
->parent
!= NULL
);
151 /* add an entry to the table */
152 if (entry
->parent
->opcode_rule
->gen
== array_gen
) {
153 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
154 if (entry
->opcode
== NULL
) {
155 /* table leaf entry */
156 lf_printf(file
, "function_entry, 0, 0, ");
157 if ((code
& generate_jumps
))
158 lf_printf(file
, "&&");
159 print_function_name(file
,
160 entry
->insns
->file_entry
->fields
[insn_name
],
161 entry
->expanded_bits
,
162 ((code
& generate_with_icache
)
163 ? function_name_prefix_icache
164 : function_name_prefix_semantics
));
166 else if (entry
->opcode_rule
->gen
== switch_gen
167 || entry
->opcode_rule
->gen
== goto_switch_gen
168 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
169 /* table calling switch statement */
170 lf_printf(file
, "function_entry, 0, 0, ");
171 if ((code
& generate_jumps
))
172 lf_printf(file
, "&&");
173 lf_print_table_name(file
, entry
);
175 else if (entry
->opcode
->is_boolean
) {
176 /* table `calling' boolean table */
177 lf_printf(file
, "boolean_entry, ");
178 lf_printf(file
, "MASK32(%d, %d), ",
179 i2target(hi_bit_nr
, entry
->opcode
->first
),
180 i2target(hi_bit_nr
, entry
->opcode
->last
));
181 lf_printf(file
, "INSERTED32(%d, %d, %d), ",
182 entry
->opcode
->boolean_constant
,
183 i2target(hi_bit_nr
, entry
->opcode
->first
),
184 i2target(hi_bit_nr
, entry
->opcode
->last
));
185 lf_print_table_name(file
, entry
);
188 /* table `calling' another table */
189 lf_printf(file
, "%d, ", insn_bit_size
- entry
->opcode
->last
- 1);
190 lf_printf(file
, "MASK32(%d,%d), ",
191 i2target(hi_bit_nr
, entry
->opcode
->first
),
192 i2target(hi_bit_nr
, entry
->opcode
->last
));
193 lf_printf(file
, "0, ");
194 lf_print_table_name(file
, entry
);
196 lf_printf(file
, " },\n");
201 print_idecode_table_end(insn_table
*table
,
207 if (table
->opcode_rule
->gen
== array_gen
) {
208 lf_printf(file
, "};\n");
213 print_idecode_table_padding(insn_table
*table
,
220 if (table
->opcode_rule
->gen
== array_gen
) {
221 lf_printf(file
, " /*%d*/ { function_entry, 0, 0, ", opcode_nr
);
222 if ((code
& generate_jumps
))
223 lf_printf(file
, "&&");
224 lf_printf(file
, "%s_illegal },\n",
225 ((code
& generate_with_icache
) ? "icache" : "semantic"));
230 /****************************************************************/
234 print_goto_switch_name(lf
*file
,
237 lf_printf(file
, "case_");
238 if (entry
->opcode
== NULL
)
239 print_function_name(file
,
240 entry
->insns
->file_entry
->fields
[insn_name
],
241 entry
->expanded_bits
,
242 ((code
& generate_with_icache
)
243 ? function_name_prefix_icache
244 : function_name_prefix_semantics
));
246 lf_print_table_name(file
, entry
);
250 print_goto_switch_table_leaf(insn_table
*entry
,
256 ASSERT(entry
->parent
!= NULL
);
258 ASSERT(entry
->parent
->opcode_rule
->gen
== goto_switch_gen
);
259 ASSERT(entry
->parent
->opcode
);
261 lf_printf(file
, "&&");
262 print_goto_switch_name(file
, entry
);
263 lf_printf(file
, ",\n");
267 print_goto_switch_table_padding(insn_table
*table
,
274 ASSERT(table
->opcode_rule
->gen
== goto_switch_gen
);
276 lf_printf(file
, "&&illegal_");
277 lf_print_table_name(file
, table
);
278 lf_printf(file
, ",\n");
282 print_goto_switch_break(lf
*file
,
285 lf_printf(file
, "goto break_");
286 lf_print_table_name(file
, entry
->parent
);
287 lf_printf(file
, ";\n");
292 print_goto_switch_table(lf
*file
,
295 lf_printf(file
, "const static void *");
296 lf_print_table_name(file
, table
);
297 lf_printf(file
, "[] = {\n");
299 insn_table_traverse_tree(table
,
303 print_goto_switch_table_leaf
,
305 print_goto_switch_table_padding
);
307 lf_printf(file
, "};\n");
311 void print_idecode_switch
317 idecode_switch_start(insn_table
*table
,
322 /* const char *result = data; */
324 ASSERT(table
->opcode_rule
->gen
== switch_gen
325 || table
->opcode_rule
->gen
== goto_switch_gen
326 || table
->opcode_rule
->gen
== padded_switch_gen
);
328 if (table
->opcode
->is_boolean
329 || table
->opcode_rule
->gen
== switch_gen
330 || table
->opcode_rule
->gen
== padded_switch_gen
) {
331 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
332 i2target(hi_bit_nr
, table
->opcode
->first
),
333 i2target(hi_bit_nr
, table
->opcode
->last
));
335 else if (table
->opcode_rule
->gen
== goto_switch_gen
) {
336 if (table
->parent
!= NULL
337 && (table
->parent
->opcode_rule
->gen
== switch_gen
338 || table
->parent
->opcode_rule
->gen
== goto_switch_gen
339 || table
->parent
->opcode_rule
->gen
== padded_switch_gen
)) {
340 lf_printf(file
, "{\n");
343 print_goto_switch_table(file
, table
);
344 lf_printf(file
, "ASSERT(EXTRACTED32(instruction, %d, %d)\n",
345 i2target(hi_bit_nr
, table
->opcode
->first
),
346 i2target(hi_bit_nr
, table
->opcode
->last
));
347 lf_printf(file
, " < (sizeof(");
348 lf_print_table_name(file
, table
);
349 lf_printf(file
, ") / sizeof(void*)));\n");
350 lf_printf(file
, "goto *");
351 lf_print_table_name(file
, table
);
352 lf_printf(file
, "[EXTRACTED32(instruction, %d, %d)];\n",
353 i2target(hi_bit_nr
, table
->opcode
->first
),
354 i2target(hi_bit_nr
, table
->opcode
->last
));
357 ASSERT("bad switch" == NULL
);
363 idecode_switch_leaf(insn_table
*entry
,
369 const char *result
= data
;
370 ASSERT(entry
->parent
!= NULL
);
372 ASSERT(entry
->parent
->opcode_rule
->gen
== switch_gen
373 || entry
->parent
->opcode_rule
->gen
== goto_switch_gen
374 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
);
375 ASSERT(entry
->parent
->opcode
);
377 if (entry
->parent
->opcode
->is_boolean
378 && entry
->opcode_nr
== 0) {
379 /* boolean false target */
380 lf_printf(file
, "case %d:\n", entry
->parent
->opcode
->boolean_constant
);
382 else if (entry
->parent
->opcode
->is_boolean
383 && entry
->opcode_nr
!= 0) {
384 /* boolean true case */
385 lf_printf(file
, "default:\n");
387 else if (entry
->parent
->opcode_rule
->gen
== switch_gen
388 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
) {
390 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
392 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
) {
393 /* lf_indent(file, -1); */
394 print_goto_switch_name(file
, entry
);
395 lf_printf(file
, ":\n");
396 /* lf_indent(file, +1); */
399 ASSERT("bad switch" == NULL
);
403 if (entry
->opcode
== NULL
) {
404 /* switch calling leaf */
405 if ((code
& generate_jumps
))
406 lf_printf(file
, "goto ");
407 if ((code
& generate_calls
))
408 lf_printf(file
, "%s ", result
);
409 print_function_name(file
,
410 entry
->insns
->file_entry
->fields
[insn_name
],
411 entry
->expanded_bits
,
412 ((code
& generate_with_icache
)
413 ? function_name_prefix_icache
414 : function_name_prefix_semantics
));
415 if ((code
& generate_calls
))
416 lf_printf(file
, "(%s)", SEMANTIC_FUNCTION_ACTUAL
);
417 lf_printf(file
, ";\n");
419 else if (entry
->opcode_rule
->gen
== switch_gen
420 || entry
->opcode_rule
->gen
== goto_switch_gen
421 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
422 /* switch calling switch */
423 print_idecode_switch(file
, entry
, result
);
426 /* switch looking up a table */
427 lf_printf(file
, "{\n");
429 print_idecode_table(file
, entry
, result
);
431 lf_printf(file
, "}\n");
433 if (entry
->parent
->opcode
->is_boolean
434 || entry
->parent
->opcode_rule
->gen
== switch_gen
435 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
) {
436 lf_printf(file
, "break;\n");
438 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
) {
439 print_goto_switch_break(file
, entry
);
442 ASSERT("bad switch" == NULL
);
450 print_idecode_switch_illegal(lf
*file
,
454 print_idecode_illegal(file
, result
);
455 lf_printf(file
, "break;\n");
460 idecode_switch_end(insn_table
*table
,
465 const char *result
= data
;
467 ASSERT(table
->opcode_rule
->gen
== switch_gen
468 || table
->opcode_rule
->gen
== goto_switch_gen
469 || table
->opcode_rule
->gen
== padded_switch_gen
);
470 ASSERT(table
->opcode
);
472 if (table
->opcode
->is_boolean
) {
473 lf_printf(file
, "}\n");
475 else if (table
->opcode_rule
->gen
== switch_gen
476 || table
->opcode_rule
->gen
== padded_switch_gen
) {
477 lf_printf(file
, "default:\n");
478 switch (table
->opcode_rule
->gen
) {
480 print_idecode_switch_illegal(file
, result
);
482 case padded_switch_gen
:
483 lf_printf(file
, " error(\"Internal error - bad switch generated\\n\");\n");
484 lf_printf(file
, " break;\n");
487 ASSERT("bad switch" == NULL
);
489 lf_printf(file
, "}\n");
491 else if (table
->opcode_rule
->gen
== goto_switch_gen
) {
492 lf_printf(file
, "illegal_");
493 lf_print_table_name(file
, table
);
494 lf_printf(file
, ":\n");
495 print_idecode_illegal(file
, result
);
496 lf_printf(file
, "break_");
497 lf_print_table_name(file
, table
);
498 lf_printf(file
, ":;\n");
499 if (table
->parent
!= NULL
500 && (table
->parent
->opcode_rule
->gen
== switch_gen
501 || table
->parent
->opcode_rule
->gen
== goto_switch_gen
502 || table
->parent
->opcode_rule
->gen
== padded_switch_gen
)) {
504 lf_printf(file
, "}\n");
508 ASSERT("bad switch" == NULL
);
513 idecode_switch_padding(insn_table
*table
,
519 const char *result
= data
;
521 ASSERT(table
->opcode_rule
->gen
== switch_gen
522 || table
->opcode_rule
->gen
== goto_switch_gen
523 || table
->opcode_rule
->gen
== padded_switch_gen
);
525 switch (table
->opcode_rule
->gen
) {
528 case padded_switch_gen
:
529 lf_printf(file
, "case %d:\n", opcode_nr
);
530 print_idecode_switch_illegal(file
, result
);
532 case goto_switch_gen
:
533 /* no padding needed */
536 ASSERT("bad switch" != NULL
);
542 print_idecode_switch(lf
*file
,
546 insn_table_traverse_tree(table
,
549 idecode_switch_start
,
552 idecode_switch_padding
);
557 print_idecode_switch_function_header(lf
*file
,
559 int is_function_definition
)
561 lf_printf(file
, "\n");
562 if ((code
& generate_calls
)) {
563 lf_printf(file
, "static ");
564 if ((code
& generate_with_icache
))
565 lf_printf(file
, "idecode_semantic *");
567 lf_printf(file
, "unsigned_word");
568 if (is_function_definition
)
569 lf_printf(file
, "\n");
571 lf_printf(file
, " ");
572 lf_print_table_name(file
, table
);
573 lf_printf(file
, "\n(%s)", ICACHE_FUNCTION_FORMAL
);
574 if (!is_function_definition
)
575 lf_printf(file
, ";");
576 lf_printf(file
, "\n");
578 if ((code
& generate_jumps
) && is_function_definition
) {
580 lf_print_table_name(file
, table
);
581 lf_printf(file
, ":\n");
588 idecode_declare_if_switch(insn_table
*table
,
593 if ((table
->opcode_rule
->gen
== switch_gen
594 || table
->opcode_rule
->gen
== goto_switch_gen
595 || table
->opcode_rule
->gen
== padded_switch_gen
)
596 && table
->parent
!= NULL
/* don't declare the top one yet */
597 && table
->parent
->opcode_rule
->gen
== array_gen
) {
598 print_idecode_switch_function_header(file
,
600 0/*isnt function definition*/);
606 idecode_expand_if_switch(insn_table
*table
,
611 if ((table
->opcode_rule
->gen
== switch_gen
612 || table
->opcode_rule
->gen
== goto_switch_gen
613 || table
->opcode_rule
->gen
== padded_switch_gen
)
614 && table
->parent
!= NULL
/* don't expand the top one yet */
615 && table
->parent
->opcode_rule
->gen
== array_gen
) {
616 print_idecode_switch_function_header(file
,
618 1/*is function definition*/);
619 if ((code
& generate_calls
)) {
620 lf_printf(file
, "{\n");
623 print_idecode_switch(file
, table
, "return");
624 if ((code
& generate_calls
)) {
626 lf_printf(file
, "}\n");
632 /****************************************************************/
636 print_idecode_lookups(lf
*file
,
638 cache_table
*cache_rules
)
642 /* output switch function declarations where needed by tables */
643 insn_table_traverse_tree(table
,
646 idecode_declare_if_switch
, /* START */
649 /* output tables where needed */
650 for (depth
= insn_table_depth(table
);
653 insn_table_traverse_tree(table
,
656 print_idecode_table_start
,
657 print_idecode_table_leaf
,
658 print_idecode_table_end
,
659 print_idecode_table_padding
);
662 /* output switch functions where needed */
663 insn_table_traverse_tree(table
,
666 idecode_expand_if_switch
, /* START */
672 print_idecode_body(lf
*file
,
676 if (table
->opcode_rule
->gen
== switch_gen
677 || table
->opcode_rule
->gen
== goto_switch_gen
678 || table
->opcode_rule
->gen
== padded_switch_gen
)
679 print_idecode_switch(file
, table
, result
);
681 print_idecode_table(file
, table
, result
);
685 /****************************************************************/
689 print_run_until_stop_body(lf
*file
,
693 /* Output the function to execute real code:
695 Unfortunatly, there are multiple cases to consider vis:
697 <icache> X <smp> X <events> X <keep-running-flag> X ...
699 Consequently this function is written in multiple different ways */
701 lf_putstr(file
, "{\n");
703 lf_putstr(file
, "jmp_buf halt;\n");
704 lf_putstr(file
, "jmp_buf restart;\n");
706 lf_putstr(file
, "cpu *processor = NULL;\n");
707 lf_putstr(file
, "unsigned_word cia = -1;\n");
709 lf_putstr(file
, "int last_cpu;\n");
711 lf_putstr(file
, "int current_cpu;\n");
714 if ((code
& generate_with_icache
)) {
715 lf_putstr(file
, "int cpu_nr;\n");
716 lf_putstr(file
, "\n");
717 lf_putstr(file
, "/* flush the icache of a possible break insn */\n");
718 lf_putstr(file
, "for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
719 lf_putstr(file
, " cpu_flush_icache(processors[cpu_nr]);\n");
722 lf_putstr(file
, "\n");
723 lf_putstr(file
, "/* set the halt target initially */\n");
724 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, NULL);\n");
725 lf_putstr(file
, "if (setjmp(halt))\n");
726 lf_putstr(file
, " return;\n");
728 lf_putstr(file
, "\n");
729 lf_putstr(file
, "/* where were we before the halt? */\n");
730 lf_putstr(file
, "last_cpu = psim_last_cpu(system);\n");
732 lf_putstr(file
, "\n");
733 lf_putstr(file
, "/* check for need to force event processing first */\n");
734 lf_putstr(file
, "if (WITH_EVENTS) {\n");
735 lf_putstr(file
, " if (last_cpu == nr_cpus) {\n");
736 lf_putstr(file
, " /* halted during event processing */\n");
737 lf_putstr(file
, " event_queue_process(events);\n");
738 lf_putstr(file
, " last_cpu = -1;\n");
739 lf_putstr(file
, " }\n");
740 lf_putstr(file
, " else if (last_cpu == nr_cpus - 1) {\n");
741 lf_putstr(file
, " /* last cpu did halt */\n");
742 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
743 lf_putstr(file
, " event_queue_process(events);\n");
744 lf_putstr(file
, " }\n");
745 lf_putstr(file
, " last_cpu = -1;\n");
746 lf_putstr(file
, " }\n");
747 lf_putstr(file
, "}\n");
748 lf_putstr(file
, "else {\n");
749 lf_putstr(file
, " if (last_cpu == nr_cpus - 1)\n");
750 lf_putstr(file
, " /* cpu zero is next */\n");
751 lf_putstr(file
, " last_cpu = -1;\n");
752 lf_putstr(file
, "}\n");
754 lf_putstr(file
, "\n");
755 lf_putstr(file
, "/* have ensured that the event queue can not be first */\n");
756 lf_putstr(file
, "ASSERT(last_cpu >= -1 && last_cpu < nr_cpus - 1);\n");
761 /* CASE 1: NO SMP (with or with out instruction cache).
763 In this case, we can take advantage of the fact that the current
764 instruction address does not need to be returned to the cpu object
765 after every execution of an instruction. Instead it only needs to
766 be saved when either A. the main loop exits or B. A cpu-halt or
767 cpu-restart call forces the loop to be re-enered. The later
768 functions always save the current cpu instruction address.
770 Two subcases also exist that with and that without an instruction
773 An additional complexity is the need to ensure that a 1:1 ratio
774 is maintained between the execution of an instruction and the
775 incrementing of the simulation clock */");
777 lf_putstr(file
, "\n");
779 lf_putstr(file
, "\n");
780 lf_putstr(file
, "/* now add restart target as ready to run */\n");
781 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
782 lf_putstr(file
, "if (setjmp(restart)) {\n");
783 lf_putstr(file
, " if (WITH_EVENTS) {\n");
784 lf_putstr(file
, " /* when restart, cpu must have been last, clock next */\n");
785 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
786 lf_putstr(file
, " event_queue_process(events);\n");
787 lf_putstr(file
, " }\n");
788 lf_putstr(file
, " }\n");
789 lf_putstr(file
, "}\n");
791 lf_putstr(file
, "\n");
792 lf_putstr(file
, "/* prime the main loop */\n");
793 lf_putstr(file
, "processor = processors[0];\n");
794 lf_putstr(file
, "cia = cpu_get_program_counter(processor);\n");
796 lf_putstr(file
, "\n");
797 lf_putstr(file
, "while (1) {\n");
800 if (!(code
& generate_with_icache
)) {
801 lf_putstr(file
, "instruction_word instruction =\n");
802 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
803 lf_putstr(file
, "\n");
804 print_idecode_body(file
, table
, "cia =");;
807 if ((code
& generate_with_icache
)) {
808 lf_putstr(file
, "idecode_cache *cache_entry =\n");
809 lf_putstr(file
, " cpu_icache_entry(processor, cia);\n");
810 lf_putstr(file
, "if (cache_entry->address == cia) {\n");
811 lf_putstr(file
, " /* cache hit */\n");
812 lf_putstr(file
, " idecode_semantic *const semantic = cache_entry->semantic;\n");
813 lf_putstr(file
, " cia = semantic(processor, cache_entry, cia);\n");
816 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
817 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
819 lf_putstr(file
, "}\n");
820 lf_putstr(file
, "else {\n");
821 lf_putstr(file
, " /* cache miss */\n");
822 if (!(code
& generate_with_semantic_icache
)) {
824 lf_putstr(file
, "idecode_semantic *semantic;\n");
827 lf_putstr(file
, " instruction_word instruction =\n");
828 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
829 lf_putstr(file
, " if (WITH_MON != 0)\n");
830 lf_putstr(file
, " mon_event(mon_event_icache_miss, processor, cia);\n");
831 if ((code
& generate_with_semantic_icache
)) {
832 lf_putstr(file
, "{\n");
834 print_idecode_body(file
, table
, "cia =");
836 lf_putstr(file
, "}\n");
839 print_idecode_body(file
, table
, "semantic =");
840 lf_putstr(file
, " cia = semantic(processor, cache_entry, cia);\n");
842 lf_putstr(file
, "}\n");
846 lf_putstr(file
, "\n");
847 lf_putstr(file
, "/* process any events */\n");
848 lf_putstr(file
, "if (WITH_EVENTS) {\n");
849 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
850 lf_putstr(file
, " cpu_set_program_counter(processor, cia);\n");
851 lf_putstr(file
, " event_queue_process(events);\n");
852 lf_putstr(file
, " cia = cpu_get_program_counter(processor);\n");
853 lf_putstr(file
, " }\n");
854 lf_putstr(file
, "}\n");
858 lf_putstr(file
, "\n");
859 lf_putstr(file
, "/* abort if necessary */\n");
860 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
861 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*not important*/);\n");
865 lf_putstr(file
, "}\n");
871 /* CASE 2: SMP (With or without ICACHE)
873 The complexity here comes from needing to correctly restart the
874 system when it is aborted. In particular if cpu0 requests a
875 restart, the next cpu is still cpu1. Cpu0 being restarted after
876 all the other CPU's and the event queue have been processed */");
878 lf_putstr(file
, "\n");
880 lf_putstr(file
, "\n");
881 lf_putstr(file
, "/* now establish the restart target */\n");
882 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
883 lf_putstr(file
, "if (setjmp(restart)) {\n");
884 lf_putstr(file
, " current_cpu = psim_last_cpu(system);\n");
885 lf_putstr(file
, " ASSERT(current_cpu >= 0 && current_cpu < nr_cpus);\n");
886 lf_putstr(file
, "}\n");
887 lf_putstr(file
, "else {\n");
888 lf_putstr(file
, " current_cpu = last_cpu;\n");
889 lf_putstr(file
, " ASSERT(current_cpu >= -1 && current_cpu < nr_cpus);\n");
890 lf_putstr(file
, "}\n");
893 lf_putstr(file
, "\n");
894 lf_putstr(file
, "while (1) {\n");
897 lf_putstr(file
, "\n");
898 lf_putstr(file
, "if (WITH_EVENTS) {\n");
899 lf_putstr(file
, " current_cpu += 1;\n");
900 lf_putstr(file
, " if (current_cpu == nr_cpus) {\n");
901 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
902 lf_putstr(file
, " event_queue_process(events);\n");
903 lf_putstr(file
, " }\n");
904 lf_putstr(file
, " current_cpu = 0;\n");
905 lf_putstr(file
, " }\n");
906 lf_putstr(file
, "}\n");
907 lf_putstr(file
, "else {\n");
908 lf_putstr(file
, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
909 lf_putstr(file
, "}\n");
911 lf_putstr(file
, "\n");
912 lf_putstr(file
, "{\n");
914 lf_putstr(file
, "cpu *processor = processors[current_cpu];\n");
915 lf_putstr(file
, "unsigned_word cia =\n");
916 lf_putstr(file
, " cpu_get_program_counter(processor);\n");
918 if (!(code
& generate_with_icache
)) {
919 lf_putstr(file
, "instruction_word instruction =\n");
920 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
921 print_idecode_body(file
, table
, "cia =");
923 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
924 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
926 lf_putstr(file
, "cpu_set_program_counter(processor, cia);\n");
929 if ((code
& generate_with_icache
)) {
930 lf_putstr(file
, "idecode_cache *cache_entry =\n");
931 lf_putstr(file
, " cpu_icache_entry(processor, cia);\n");
932 lf_putstr(file
, "\n");
933 lf_putstr(file
, "if (cache_entry->address == cia) {\n");
936 lf_putstr(file
, "\n");
937 lf_putstr(file
, "/* cache hit */\n");
938 lf_putstr(file
, "idecode_semantic *semantic = cache_entry->semantic;\n");
939 lf_putstr(file
, "cia = semantic(processor, cache_entry, cia);\n");
942 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
943 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
945 lf_putstr(file
, "cpu_set_program_counter(processor, cia);\n");
946 lf_putstr(file
, "\n");
949 lf_putstr(file
, "}\n");
950 lf_putstr(file
, "else {\n");
953 lf_putstr(file
, "\n");
954 lf_putstr(file
, "/* cache miss */\n");
955 if (!(code
& generate_with_semantic_icache
)) {
956 lf_putstr(file
, "idecode_semantic *semantic;\n");
958 lf_putstr(file
, "instruction_word instruction =\n");
959 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
960 lf_putstr(file
, "if (WITH_MON != 0)\n");
961 lf_putstr(file
, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
962 if ((code
& generate_with_semantic_icache
)) {
963 lf_putstr(file
, "{\n");
965 print_idecode_body(file
, table
, "cia =");
967 lf_putstr(file
, "}\n");
970 print_idecode_body(file
, table
, "semantic = ");
971 lf_putstr(file
, "cia = semantic(processor, cache_entry, cia);\n");
975 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
976 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
978 lf_putstr(file
, "cpu_set_program_counter(processor, cia);\n");
979 lf_putstr(file
, "\n");
982 lf_putstr(file
, "}\n");
987 lf_putstr(file
, "}\n");
991 lf_putstr(file
, "}\n");
996 lf_putstr(file
, "}\n");
1000 /****************************************************************/
1003 print_jump(lf
*file
,
1007 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
1008 lf_putstr(file
, " cpu_halt(processor, nia, was_continuing, 0/*na*/);\n");
1011 if (!generate_smp
) {
1012 lf_putstr(file
, "if (WITH_EVENTS) {\n");
1013 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
1014 lf_putstr(file
, " cpu_set_program_counter(processor, nia);\n");
1015 lf_putstr(file
, " event_queue_process(events);\n");
1016 lf_putstr(file
, " nia = cpu_get_program_counter(processor);\n");
1017 lf_putstr(file
, " }\n");
1018 lf_putstr(file
, "}\n");
1023 lf_putstr(file
, "cpu_set_program_counter(processor, nia);\n");
1024 lf_putstr(file
, "if (WITH_EVENTS) {\n");
1025 lf_putstr(file
, " current_cpu += 1;\n");
1026 lf_putstr(file
, " if (current_cpu >= nr_cpus) {\n");
1027 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
1028 lf_putstr(file
, " event_queue_process(events);\n");
1029 lf_putstr(file
, " }\n");
1030 lf_putstr(file
, " current_cpu = 0;\n");
1031 lf_putstr(file
, " }\n");
1032 lf_putstr(file
, "}\n");
1033 lf_putstr(file
, "else {\n");
1034 lf_putstr(file
, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
1035 lf_putstr(file
, "}\n");
1036 lf_putstr(file
, "processor = processors[current_cpu];\n");
1037 lf_putstr(file
, "nia = cpu_get_program_counter(processor);\n");
1040 if ((code
& generate_with_icache
)) {
1041 lf_putstr(file
, "cache_entry = cpu_icache_entry(processor, nia);\n");
1042 lf_putstr(file
, "if (cache_entry->address == nia) {\n");
1043 lf_putstr(file
, " /* cache hit */\n");
1044 lf_putstr(file
, " goto *cache_entry->semantic;\n");
1045 lf_putstr(file
, "}\n");
1047 lf_putstr(file
, "goto cache_miss;\n");
1051 if (!(code
& generate_with_icache
) && is_tail
) {
1052 lf_printf(file
, "goto idecode;\n");
1062 print_jump_insn(lf
*file
,
1064 insn_bits
*expanded_bits
,
1065 opcode_field
*opcodes
,
1066 cache_table
*cache_rules
)
1069 /* what we are for the moment */
1070 lf_printf(file
, "\n");
1071 print_my_defines(file
, expanded_bits
, instruction
->file_entry
);
1073 /* output the icache entry */
1074 if ((code
& generate_with_icache
)) {
1075 lf_printf(file
, "\n");
1076 lf_indent(file
, -1);
1077 print_function_name(file
,
1078 instruction
->file_entry
->fields
[insn_name
],
1080 function_name_prefix_icache
);
1081 lf_printf(file
, ":\n");
1082 lf_indent(file
, +1);
1083 lf_printf(file
, "{\n");
1084 lf_indent(file
, +2);
1085 lf_putstr(file
, "const unsigned_word cia = nia;\n");
1086 print_itrace(file
, instruction
->file_entry
, 1/*putting-value-in-cache*/);
1087 print_idecode_validate(file
, instruction
, opcodes
);
1088 lf_printf(file
, "\n");
1089 lf_printf(file
, "{\n");
1090 lf_indent(file
, +2);
1091 print_icache_body(file
,
1096 put_values_in_icache
);
1097 lf_printf(file
, "cache_entry->address = nia;\n");
1098 lf_printf(file
, "cache_entry->semantic = &&");
1099 print_function_name(file
,
1100 instruction
->file_entry
->fields
[insn_name
],
1102 function_name_prefix_semantics
);
1103 lf_printf(file
, ";\n");
1104 if ((code
& generate_with_semantic_icache
)) {
1105 print_semantic_body(file
,
1109 print_jump(file
, 1/*is-tail*/);
1112 lf_printf(file
, "/* goto ");
1113 print_function_name(file
,
1114 instruction
->file_entry
->fields
[insn_name
],
1116 function_name_prefix_semantics
);
1117 lf_printf(file
, "; */\n");
1119 lf_indent(file
, -2);
1120 lf_putstr(file
, "}\n");
1121 lf_indent(file
, -2);
1122 lf_printf(file
, "}\n");
1125 /* print the semantics */
1126 lf_printf(file
, "\n");
1127 lf_indent(file
, -1);
1128 print_function_name(file
,
1129 instruction
->file_entry
->fields
[insn_name
],
1131 function_name_prefix_semantics
);
1132 lf_printf(file
, ":\n");
1133 lf_indent(file
, +1);
1134 lf_printf(file
, "{\n");
1135 lf_indent(file
, +2);
1136 lf_putstr(file
, "const unsigned_word cia = nia;\n");
1137 print_icache_body(file
,
1141 ((code
& generate_with_direct_access
)
1143 : declare_variables
),
1144 ((code
& generate_with_icache
)
1145 ? get_values_from_icache
1146 : do_not_use_icache
));
1147 print_semantic_body(file
,
1151 if (code
& generate_with_direct_access
)
1152 print_icache_body(file
,
1157 ((code
& generate_with_icache
)
1158 ? get_values_from_icache
1159 : do_not_use_icache
));
1160 print_jump(file
, 1/*is tail*/);
1161 lf_indent(file
, -2);
1162 lf_printf(file
, "}\n");
1166 print_jump_definition(insn_table
*entry
,
1172 cache_table
*cache_rules
= (cache_table
*)data
;
1173 if (generate_expanded_instructions
) {
1174 ASSERT(entry
->nr_insn
== 1
1175 && entry
->opcode
== NULL
1176 && entry
->parent
!= NULL
1177 && entry
->parent
->opcode
!= NULL
);
1178 ASSERT(entry
->nr_insn
== 1
1179 && entry
->opcode
== NULL
1180 && entry
->parent
!= NULL
1181 && entry
->parent
->opcode
!= NULL
1182 && entry
->parent
->opcode_rule
!= NULL
);
1183 print_jump_insn(file
,
1185 entry
->expanded_bits
,
1190 print_jump_insn(file
,
1200 print_jump_internal_function(insn_table
*table
,
1203 table_entry
*function
)
1205 if (it_is("internal", function
->fields
[insn_flags
])) {
1206 lf_printf(file
, "\n");
1207 table_entry_print_cpp_line_nr(file
, function
);
1208 lf_indent(file
, -1);
1209 print_function_name(file
,
1210 function
->fields
[insn_name
],
1212 ((code
& generate_with_icache
)
1213 ? function_name_prefix_icache
1214 : function_name_prefix_semantics
));
1215 lf_printf(file
, ":\n");
1216 lf_indent(file
, +1);
1217 lf_printf(file
, "{\n");
1218 lf_indent(file
, +2);
1219 lf_printf(file
, "const unsigned_word cia = nia;\n");
1220 lf_print__c_code(file
, function
->annex
);
1221 lf_print__internal_reference(file
);
1222 lf_printf(file
, "error(\"Internal function must longjump\\n\");\n");
1223 lf_indent(file
, -2);
1224 lf_printf(file
, "}\n");
1229 print_jump_until_stop_body(lf
*file
,
1231 cache_table
*cache_rules
,
1234 lf_printf(file
, "{\n");
1235 lf_indent(file
, +2);
1237 lf_printf(file
, "int *keep_running = NULL;\n");
1238 lf_putstr(file
, "jmp_buf halt;\n");
1239 lf_putstr(file
, "jmp_buf restart;\n");
1240 lf_putstr(file
, "cpu *processor = NULL;\n");
1241 lf_putstr(file
, "unsigned_word nia = -1;\n");
1242 lf_putstr(file
, "instruction_word instruction = 0;\n");
1243 if ((code
& generate_with_icache
)) {
1244 lf_putstr(file
, "idecode_cache *cache_entry = NULL;\n");
1247 lf_putstr(file
, "int current_cpu = -1;\n");
1250 /* all the switches and tables - they know about jumping */
1251 print_idecode_lookups(file
, table
, cache_rules
);
1253 /* start the simulation up */
1254 if ((code
& generate_with_icache
)) {
1255 lf_putstr(file
, "\n");
1256 lf_putstr(file
, "{\n");
1257 lf_putstr(file
, " int cpu_nr;\n");
1258 lf_putstr(file
, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
1259 lf_putstr(file
, " cpu_flush_icache(processors[cpu_nr]);\n");
1260 lf_putstr(file
, "}\n");
1263 lf_putstr(file
, "\n");
1264 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1266 lf_putstr(file
, "\n");
1267 lf_putstr(file
, "if (setjmp(halt))\n");
1268 lf_putstr(file
, " return;\n");
1270 lf_putstr(file
, "\n");
1271 lf_putstr(file
, "setjmp(restart);\n");
1273 lf_putstr(file
, "\n");
1274 if (!generate_smp
) {
1275 lf_putstr(file
, "processor = processors[0];\n");
1276 lf_putstr(file
, "nia = cpu_get_program_counter(processor);\n");
1279 lf_putstr(file
, "current_cpu = psim_last_cpu(system);\n");
1282 if (!(code
& generate_with_icache
)) {
1283 lf_printf(file
, "\n");
1284 lf_indent(file
, -1);
1285 lf_printf(file
, "idecode:\n");
1286 lf_indent(file
, +1);
1289 print_jump(file
, 0/*is_tail*/);
1291 if ((code
& generate_with_icache
)) {
1292 lf_indent(file
, -1);
1293 lf_printf(file
, "cache_miss:\n");
1294 lf_indent(file
, +1);
1297 lf_putstr(file
, "instruction\n");
1298 lf_putstr(file
, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
1299 lf_putstr(file
, " processor, nia);\n");
1300 print_idecode_body(file
, table
, "/*IGORE*/");
1302 /* print out a table of all the internals functions */
1303 insn_table_traverse_function(table
,
1305 print_jump_internal_function
);
1307 /* print out a table of all the instructions */
1308 if (generate_expanded_instructions
)
1309 insn_table_traverse_tree(table
,
1313 print_jump_definition
, /* leaf */
1315 NULL
); /* padding */
1317 insn_table_traverse_insn(table
,
1319 print_jump_definition
);
1320 lf_indent(file
, -2);
1321 lf_printf(file
, "}\n");
1325 /****************************************************************/
1330 print_idecode_floating_point_unavailable(lf
*file
)
1332 if ((code
& generate_jumps
))
1333 lf_printf(file
, "goto %s_floating_point_unavailable;\n", (code
& generate_with_icache
) ? "icache" : "semantic");
1334 else if ((code
& generate_with_icache
))
1335 lf_printf(file
, "return icache_floating_point_unavailable(%s);\n",
1336 ICACHE_FUNCTION_ACTUAL
);
1338 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
1339 SEMANTIC_FUNCTION_ACTUAL
);
1343 /* Output code to do any final checks on the decoded instruction.
1344 This includes things like verifying any on decoded fields have the
1345 correct value and checking that (for floating point) floating point
1346 hardware isn't disabled */
1349 print_idecode_validate(lf
*file
,
1351 opcode_field
*opcodes
)
1353 /* Validate: unchecked instruction fields
1355 If any constant fields in the instruction were not checked by the
1356 idecode tables, output code to check that they have the correct
1359 unsigned check_mask
= 0;
1360 unsigned check_val
= 0;
1362 opcode_field
*opcode
;
1364 /* form check_mask/check_val containing what needs to be checked
1365 in the instruction */
1366 for (field
= instruction
->fields
->first
;
1367 field
->first
< insn_bit_size
;
1368 field
= field
->next
) {
1370 check_mask
<<= field
->width
;
1371 check_val
<<= field
->width
;
1373 /* is it a constant that could need validating? */
1374 if (!field
->is_int
&& !field
->is_slash
)
1377 /* has it been checked by a table? */
1378 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1379 if (field
->first
>= opcode
->first
1380 && field
->last
<= opcode
->last
)
1386 check_mask
|= (1 << field
->width
)-1;
1387 check_val
|= field
->val_int
;
1390 /* if any bits not checked by opcode tables, output code to check them */
1392 lf_printf(file
, "\n");
1393 lf_printf(file
, "/* validate: %s */\n",
1394 instruction
->file_entry
->fields
[insn_format
]);
1395 lf_printf(file
, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
1396 check_mask
, check_val
);
1397 lf_indent(file
, +2);
1398 print_idecode_illegal(file
, "return");
1399 lf_indent(file
, -2);
1403 /* Validate floating point hardware
1405 If the simulator is being built with out floating point hardware
1406 (different to it being disabled in the MSR) then floating point
1407 instructions are invalid */
1409 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1410 lf_printf(file
, "\n");
1411 lf_printf(file
, "/* Validate: FP hardware exists */\n");
1412 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1413 lf_indent(file
, +2);
1414 print_idecode_illegal(file
, "return");
1415 lf_indent(file
, -2);
1419 /* Validate: Floating Point available
1421 If floating point is not available, we enter a floating point
1422 unavailable interrupt into the cache instead of the instruction
1425 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1426 ever a CSI occures we flush the instruction cache. */
1429 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1430 lf_printf(file
, "\n");
1431 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
1432 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
1433 lf_indent(file
, +2);
1434 print_idecode_floating_point_unavailable(file
);
1435 lf_indent(file
, -2);
1441 /****************************************************************/
1445 print_idecode_run_function_header(lf
*file
,
1450 lf_printf(file
, "\n");
1451 lf_print_function_type(file
, "void", "INLINE_IDECODE", (is_definition
? " " : "\n"));
1452 indent
= lf_putstr(file
, (can_stop
? "idecode_run_until_stop" : "idecode_run"));
1454 lf_putstr(file
, "\n");
1456 lf_indent(file
, +indent
);
1457 lf_putstr(file
, "(psim *system,\n");
1459 lf_putstr(file
, " volatile int *keep_running,\n");
1460 lf_printf(file
, " event_queue *events,\n");
1461 lf_putstr(file
, " cpu *const processors[],\n");
1462 lf_putstr(file
, " const int nr_cpus)");
1464 lf_putstr(file
, ";");
1466 lf_indent(file
, -indent
);
1467 lf_putstr(file
, "\n");
1472 gen_idecode_h(lf
*file
,
1474 cache_table
*cache_rules
)
1476 lf_printf(file
, "/* The idecode_*.h functions shall move to support */\n");
1477 lf_printf(file
, "#include \"idecode_expression.h\"\n");
1478 lf_printf(file
, "#include \"idecode_fields.h\"\n");
1479 lf_printf(file
, "#include \"idecode_branch.h\"\n");
1480 lf_printf(file
, "\n");
1481 print_icache_struct(table
, cache_rules
, file
);
1482 lf_printf(file
, "\n");
1483 lf_printf(file
, "#define WITH_IDECODE_SMP %d\n", generate_smp
);
1484 lf_printf(file
, "\n");
1485 print_idecode_run_function_header(file
, 0/*can stop*/, 1/*is definition*/);
1486 print_idecode_run_function_header(file
, 1/*can stop*/, 1/*is definition*/);
1491 gen_idecode_c(lf
*file
,
1493 cache_table
*cache_rules
)
1496 lf_printf(file
, "#include \"inline.c\"\n");
1497 lf_printf(file
, "\n");
1498 lf_printf(file
, "#include \"cpu.h\"\n");
1499 lf_printf(file
, "#include \"idecode.h\"\n");
1500 lf_printf(file
, "#include \"semantics.h\"\n");
1501 lf_printf(file
, "#include \"icache.h\"\n");
1502 lf_printf(file
, "#include \"support.h\"\n");
1503 lf_printf(file
, "\n");
1504 lf_printf(file
, "#include <setjmp.h>\n");
1505 lf_printf(file
, "\n");
1506 lf_printf(file
, "enum {\n");
1507 lf_printf(file
, " /* greater or equal to zero => table */\n");
1508 lf_printf(file
, " function_entry = -1,\n");
1509 lf_printf(file
, " boolean_entry = -2,\n");
1510 lf_printf(file
, "};\n");
1511 lf_printf(file
, "\n");
1512 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
1513 lf_printf(file
, " int shift;\n");
1514 lf_printf(file
, " instruction_word mask;\n");
1515 lf_printf(file
, " instruction_word value;");
1516 lf_printf(file
, " void *function_or_table;\n");
1517 lf_printf(file
, "} idecode_table_entry;\n");
1518 lf_printf(file
, "\n");
1519 lf_printf(file
, "\n");
1521 if ((code
& generate_calls
)) {
1523 print_idecode_lookups(file
, table
, cache_rules
);
1525 /* output the main idecode routine */
1526 print_idecode_run_function_header(file
, 0/*can stop*/, 0/*is definition*/);
1527 print_run_until_stop_body(file
, table
, 0/* have stop argument */);
1529 print_idecode_run_function_header(file
, 1/*can stop*/, 0/*is definition*/);
1530 print_run_until_stop_body(file
, table
, 1/* no stop argument */);
1533 else if ((code
& generate_jumps
)) {
1535 print_idecode_run_function_header(file
, 0/*can stop*/, 0/*is definition*/);
1536 print_jump_until_stop_body(file
, table
, cache_rules
, 0 /* have stop argument */);
1538 print_idecode_run_function_header(file
, 1/*can stop*/, 0/*is definition*/);
1539 print_jump_until_stop_body(file
, table
, cache_rules
, 1/* have stop argument */);
1543 error("Something is wrong!\n");