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
)
62 ASSERT(entry
->opcode
== NULL
&& entry
->nr_insn
> 1);
63 for (i
= entry
->insns
; i
!= NULL
; i
= i
->next
) {
64 fprintf(stderr
, "%s:%d: %s %s\n",
65 i
->file_entry
->file_name
,
66 i
->file_entry
->line_nr
,
67 i
->file_entry
->fields
[insn_name
],
69 ? "was not uniquely decoded"
70 : "decodes to the same entry"));
75 /****************************************************************/
79 lf_print_table_name(lf
*file
,
82 lf_printf(file
, "idecode_table");
83 lf_print_opcodes(file
, table
);
89 print_idecode_table(lf
*file
,
93 lf_printf(file
, "/* prime the search */\n");
94 lf_printf(file
, "idecode_table_entry *table = ");
95 lf_print_table_name(file
, entry
);
96 lf_printf(file
, ";\n");
97 lf_printf(file
, "int opcode = EXTRACTED%d(instruction, %d, %d);\n",
99 i2target(hi_bit_nr
, entry
->opcode
->first
),
100 i2target(hi_bit_nr
, entry
->opcode
->last
));
101 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
103 lf_printf(file
, "\n");
104 lf_printf(file
, "/* iterate until a leaf */\n");
105 lf_printf(file
, "while (1) {\n");
106 lf_printf(file
, " signed shift = table_entry->shift;\n");
107 lf_printf(file
, "if (shift == function_entry) break;\n");
108 lf_printf(file
, " if (shift >= 0) {\n");
109 lf_printf(file
, " table = ((idecode_table_entry*)\n");
110 lf_printf(file
, " table_entry->function_or_table);\n");
111 lf_printf(file
, " opcode = ((instruction & table_entry->mask)\n");
112 lf_printf(file
, " >> shift);\n");
113 lf_printf(file
, " table_entry = table + opcode;\n");
114 lf_printf(file
, " }\n");
115 lf_printf(file
, " else {\n");
116 lf_printf(file
, " /* must be a boolean */\n");
117 lf_printf(file
, " ASSERT(table_entry->shift == boolean_entry);\n");
118 lf_printf(file
, " opcode = ((instruction & table_entry->mask)\n");
119 lf_printf(file
, " != table_entry->value);\n");
120 lf_printf(file
, " table = ((idecode_table_entry*)\n");
121 lf_printf(file
, " table_entry->function_or_table);\n");
122 lf_printf(file
, " table_entry = table + opcode;\n");
123 lf_printf(file
, " }\n");
124 lf_printf(file
, "}\n");
126 lf_printf(file
, "\n");
127 lf_printf(file
, "/* call the leaf code */\n");
128 if ((code
& generate_jumps
)) {
129 lf_printf(file
, "goto *table_entry->function_or_table;\n");
132 lf_printf(file
, "%s ", result
);
133 if ((code
& generate_with_icache
)) {
134 lf_printf(file
, "(((idecode_icache*)table_entry->function_or_table)\n");
135 lf_printf(file
, " (");
136 print_icache_function_actual(file
);
137 lf_printf(file
, "));\n");
140 lf_printf(file
, "((idecode_semantic*)table_entry->function_or_table)\n");
141 lf_printf(file
, " (");
142 print_semantic_function_actual(file
);
143 lf_printf(file
, ");\n");
150 print_idecode_table_start(insn_table
*table
,
156 /* start of the table */
157 if (table
->opcode_rule
->gen
== array_gen
) {
158 lf_printf(file
, "\n");
159 lf_printf(file
, "static idecode_table_entry ");
160 lf_print_table_name(file
, table
);
161 lf_printf(file
, "[] = {\n");
166 print_idecode_table_leaf(insn_table
*entry
,
172 ASSERT(entry
->parent
!= NULL
);
175 /* add an entry to the table */
176 if (entry
->parent
->opcode_rule
->gen
== array_gen
) {
177 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
178 if (entry
->opcode
== NULL
) {
179 if (entry
->nr_insn
!= 1) {
180 error_leaf_contains_multiple_insn(entry
);
182 /* table leaf entry */
183 lf_printf(file
, "function_entry, 0, 0, ");
184 if ((code
& generate_jumps
))
185 lf_printf(file
, "&&");
186 print_function_name(file
,
187 entry
->insns
->file_entry
->fields
[insn_name
],
188 entry
->expanded_bits
,
189 ((code
& generate_with_icache
)
190 ? function_name_prefix_icache
191 : function_name_prefix_semantics
));
193 else if (entry
->opcode_rule
->gen
== switch_gen
194 || entry
->opcode_rule
->gen
== goto_switch_gen
195 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
196 /* table calling switch statement */
197 lf_printf(file
, "function_entry, 0, 0, ");
198 if ((code
& generate_jumps
))
199 lf_printf(file
, "&&");
200 lf_print_table_name(file
, entry
);
202 else if (entry
->opcode
->is_boolean
) {
203 /* table `calling' boolean table */
204 lf_printf(file
, "boolean_entry, ");
205 lf_printf(file
, "MASK32(%d, %d), ",
206 i2target(hi_bit_nr
, entry
->opcode
->first
),
207 i2target(hi_bit_nr
, entry
->opcode
->last
));
208 lf_printf(file
, "INSERTED32(%d, %d, %d), ",
209 entry
->opcode
->boolean_constant
,
210 i2target(hi_bit_nr
, entry
->opcode
->first
),
211 i2target(hi_bit_nr
, entry
->opcode
->last
));
212 lf_print_table_name(file
, entry
);
215 /* table `calling' another table */
216 lf_printf(file
, "%d, ", insn_bit_size
- entry
->opcode
->last
- 1);
217 lf_printf(file
, "MASK%d(%d,%d), ",
219 i2target(hi_bit_nr
, entry
->opcode
->first
),
220 i2target(hi_bit_nr
, entry
->opcode
->last
));
221 lf_printf(file
, "0, ");
222 lf_print_table_name(file
, entry
);
224 lf_printf(file
, " },\n");
229 print_idecode_table_end(insn_table
*table
,
235 if (table
->opcode_rule
->gen
== array_gen
) {
236 lf_printf(file
, "};\n");
241 print_idecode_table_padding(insn_table
*table
,
248 if (table
->opcode_rule
->gen
== array_gen
) {
249 lf_printf(file
, " /*%d*/ { function_entry, 0, 0, ", opcode_nr
);
250 if ((code
& generate_jumps
))
251 lf_printf(file
, "&&");
252 lf_printf(file
, "%s_illegal },\n",
253 ((code
& generate_with_icache
) ? "icache" : "semantic"));
258 /****************************************************************/
262 print_goto_switch_name(lf
*file
,
265 lf_printf(file
, "case_");
266 if (entry
->opcode
== NULL
)
267 print_function_name(file
,
268 entry
->insns
->file_entry
->fields
[insn_name
],
269 entry
->expanded_bits
,
270 ((code
& generate_with_icache
)
271 ? function_name_prefix_icache
272 : function_name_prefix_semantics
));
274 lf_print_table_name(file
, entry
);
278 print_goto_switch_table_leaf(insn_table
*entry
,
284 ASSERT(entry
->parent
!= NULL
);
286 ASSERT(entry
->parent
->opcode_rule
->gen
== goto_switch_gen
);
287 ASSERT(entry
->parent
->opcode
);
289 lf_printf(file
, "&&");
290 print_goto_switch_name(file
, entry
);
291 lf_printf(file
, ",\n");
295 print_goto_switch_table_padding(insn_table
*table
,
302 ASSERT(table
->opcode_rule
->gen
== goto_switch_gen
);
304 lf_printf(file
, "&&illegal_");
305 lf_print_table_name(file
, table
);
306 lf_printf(file
, ",\n");
310 print_goto_switch_break(lf
*file
,
313 lf_printf(file
, "goto break_");
314 lf_print_table_name(file
, entry
->parent
);
315 lf_printf(file
, ";\n");
320 print_goto_switch_table(lf
*file
,
323 lf_printf(file
, "const static void *");
324 lf_print_table_name(file
, table
);
325 lf_printf(file
, "[] = {\n");
327 insn_table_traverse_tree(table
,
331 print_goto_switch_table_leaf
,
333 print_goto_switch_table_padding
);
335 lf_printf(file
, "};\n");
339 void print_idecode_switch
345 print_idecode_switch_start(insn_table
*table
,
350 /* const char *result = data; */
352 ASSERT(table
->opcode_rule
->gen
== switch_gen
353 || table
->opcode_rule
->gen
== goto_switch_gen
354 || table
->opcode_rule
->gen
== padded_switch_gen
);
356 if (table
->opcode
->is_boolean
357 || table
->opcode_rule
->gen
== switch_gen
358 || table
->opcode_rule
->gen
== padded_switch_gen
) {
359 lf_printf(file
, "switch (EXTRACTED%d(instruction, %d, %d)) {\n",
361 i2target(hi_bit_nr
, table
->opcode
->first
),
362 i2target(hi_bit_nr
, table
->opcode
->last
));
364 else if (table
->opcode_rule
->gen
== goto_switch_gen
) {
365 if (table
->parent
!= NULL
366 && (table
->parent
->opcode_rule
->gen
== switch_gen
367 || table
->parent
->opcode_rule
->gen
== goto_switch_gen
368 || table
->parent
->opcode_rule
->gen
== padded_switch_gen
)) {
369 lf_printf(file
, "{\n");
372 print_goto_switch_table(file
, table
);
373 lf_printf(file
, "ASSERT(EXTRACTED%d(instruction, %d, %d)\n",
375 i2target(hi_bit_nr
, table
->opcode
->first
),
376 i2target(hi_bit_nr
, table
->opcode
->last
));
377 lf_printf(file
, " < (sizeof(");
378 lf_print_table_name(file
, table
);
379 lf_printf(file
, ") / sizeof(void*)));\n");
380 lf_printf(file
, "goto *");
381 lf_print_table_name(file
, table
);
382 lf_printf(file
, "[EXTRACTED%d(instruction, %d, %d)];\n",
384 i2target(hi_bit_nr
, table
->opcode
->first
),
385 i2target(hi_bit_nr
, table
->opcode
->last
));
388 ASSERT("bad switch" == NULL
);
394 print_idecode_switch_leaf(insn_table
*entry
,
400 const char *result
= data
;
401 ASSERT(entry
->parent
!= NULL
);
403 ASSERT(entry
->parent
->opcode_rule
->gen
== switch_gen
404 || entry
->parent
->opcode_rule
->gen
== goto_switch_gen
405 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
);
406 ASSERT(entry
->parent
->opcode
);
408 if (entry
->parent
->opcode
->is_boolean
409 && entry
->opcode_nr
== 0) {
410 /* boolean false target */
411 lf_printf(file
, "case %d:\n", entry
->parent
->opcode
->boolean_constant
);
413 else if (entry
->parent
->opcode
->is_boolean
414 && entry
->opcode_nr
!= 0) {
415 /* boolean true case */
416 lf_printf(file
, "default:\n");
418 else if (entry
->parent
->opcode_rule
->gen
== switch_gen
419 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
) {
421 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
423 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
) {
424 /* lf_indent(file, -1); */
425 print_goto_switch_name(file
, entry
);
426 lf_printf(file
, ":\n");
427 /* lf_indent(file, +1); */
430 ASSERT("bad switch" == NULL
);
434 if (entry
->opcode
== NULL
) {
435 /* switch calling leaf */
436 if (entry
->nr_insn
!= 1) {
437 error_leaf_contains_multiple_insn(entry
);
439 if ((code
& generate_jumps
))
440 lf_printf(file
, "goto ");
441 if ((code
& generate_calls
))
442 lf_printf(file
, "%s ", result
);
443 print_function_name(file
,
444 entry
->insns
->file_entry
->fields
[insn_name
],
445 entry
->expanded_bits
,
446 ((code
& generate_with_icache
)
447 ? function_name_prefix_icache
448 : function_name_prefix_semantics
));
449 if ((code
& generate_calls
)) {
450 lf_printf(file
, "(");
451 print_semantic_function_actual(file
);
452 lf_printf(file
, ")");
454 lf_printf(file
, ";\n");
456 else if (entry
->opcode_rule
->gen
== switch_gen
457 || entry
->opcode_rule
->gen
== goto_switch_gen
458 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
459 /* switch calling switch */
460 print_idecode_switch(file
, entry
, result
);
463 /* switch looking up a table */
464 lf_printf(file
, "{\n");
466 print_idecode_table(file
, entry
, result
);
468 lf_printf(file
, "}\n");
470 if (entry
->parent
->opcode
->is_boolean
471 || entry
->parent
->opcode_rule
->gen
== switch_gen
472 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
) {
473 lf_printf(file
, "break;\n");
475 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
) {
476 print_goto_switch_break(file
, entry
);
479 ASSERT("bad switch" == NULL
);
487 print_idecode_switch_illegal(lf
*file
,
491 print_idecode_invalid(file
, result
, invalid_illegal
);
492 lf_printf(file
, "break;\n");
497 print_idecode_switch_end(insn_table
*table
,
502 const char *result
= data
;
504 ASSERT(table
->opcode_rule
->gen
== switch_gen
505 || table
->opcode_rule
->gen
== goto_switch_gen
506 || table
->opcode_rule
->gen
== padded_switch_gen
);
507 ASSERT(table
->opcode
);
509 if (table
->opcode
->is_boolean
) {
510 lf_printf(file
, "}\n");
512 else if (table
->opcode_rule
->gen
== switch_gen
513 || table
->opcode_rule
->gen
== padded_switch_gen
) {
514 lf_printf(file
, "default:\n");
515 switch (table
->opcode_rule
->gen
) {
517 print_idecode_switch_illegal(file
, result
);
519 case padded_switch_gen
:
520 lf_printf(file
, " error(\"Internal error - bad switch generated\\n\");\n");
521 lf_printf(file
, " break;\n");
524 ASSERT("bad switch" == NULL
);
526 lf_printf(file
, "}\n");
528 else if (table
->opcode_rule
->gen
== goto_switch_gen
) {
529 lf_printf(file
, "illegal_");
530 lf_print_table_name(file
, table
);
531 lf_printf(file
, ":\n");
532 print_idecode_invalid(file
, result
, invalid_illegal
);
533 lf_printf(file
, "break_");
534 lf_print_table_name(file
, table
);
535 lf_printf(file
, ":;\n");
536 if (table
->parent
!= NULL
537 && (table
->parent
->opcode_rule
->gen
== switch_gen
538 || table
->parent
->opcode_rule
->gen
== goto_switch_gen
539 || table
->parent
->opcode_rule
->gen
== padded_switch_gen
)) {
541 lf_printf(file
, "}\n");
545 ASSERT("bad switch" == NULL
);
550 print_idecode_switch_padding(insn_table
*table
,
556 const char *result
= data
;
558 ASSERT(table
->opcode_rule
->gen
== switch_gen
559 || table
->opcode_rule
->gen
== goto_switch_gen
560 || table
->opcode_rule
->gen
== padded_switch_gen
);
562 switch (table
->opcode_rule
->gen
) {
565 case padded_switch_gen
:
566 lf_printf(file
, "case %d:\n", opcode_nr
);
567 print_idecode_switch_illegal(file
, result
);
569 case goto_switch_gen
:
570 /* no padding needed */
573 ASSERT("bad switch" != NULL
);
579 print_idecode_switch(lf
*file
,
583 insn_table_traverse_tree(table
,
586 print_idecode_switch_start
,
587 print_idecode_switch_leaf
,
588 print_idecode_switch_end
,
589 print_idecode_switch_padding
);
594 print_idecode_switch_function_header(lf
*file
,
596 int is_function_definition
)
598 lf_printf(file
, "\n");
599 if ((code
& generate_calls
)) {
600 lf_printf(file
, "static ");
601 if ((code
& generate_with_icache
))
602 lf_printf(file
, "idecode_semantic *");
604 lf_printf(file
, "unsigned_word");
605 if (is_function_definition
)
606 lf_printf(file
, "\n");
608 lf_printf(file
, " ");
609 lf_print_table_name(file
, table
);
610 lf_printf(file
, "\n(");
611 print_icache_function_formal(file
);
612 lf_printf(file
, ")");
613 if (!is_function_definition
)
614 lf_printf(file
, ";");
615 lf_printf(file
, "\n");
617 if ((code
& generate_jumps
) && is_function_definition
) {
619 lf_print_table_name(file
, table
);
620 lf_printf(file
, ":\n");
627 idecode_declare_if_switch(insn_table
*table
,
632 if ((table
->opcode_rule
->gen
== switch_gen
633 || table
->opcode_rule
->gen
== goto_switch_gen
634 || table
->opcode_rule
->gen
== padded_switch_gen
)
635 && table
->parent
!= NULL
/* don't declare the top one yet */
636 && table
->parent
->opcode_rule
->gen
== array_gen
) {
637 print_idecode_switch_function_header(file
,
639 0/*isnt function definition*/);
645 idecode_expand_if_switch(insn_table
*table
,
650 if ((table
->opcode_rule
->gen
== switch_gen
651 || table
->opcode_rule
->gen
== goto_switch_gen
652 || table
->opcode_rule
->gen
== padded_switch_gen
)
653 && table
->parent
!= NULL
/* don't expand the top one yet */
654 && table
->parent
->opcode_rule
->gen
== array_gen
) {
655 print_idecode_switch_function_header(file
,
657 1/*is function definition*/);
658 if ((code
& generate_calls
)) {
659 lf_printf(file
, "{\n");
662 print_idecode_switch(file
, table
, "return");
663 if ((code
& generate_calls
)) {
665 lf_printf(file
, "}\n");
671 /****************************************************************/
675 print_idecode_lookups(lf
*file
,
677 cache_table
*cache_rules
)
681 /* output switch function declarations where needed by tables */
682 insn_table_traverse_tree(table
,
685 idecode_declare_if_switch
, /* START */
688 /* output tables where needed */
689 for (depth
= insn_table_depth(table
);
692 insn_table_traverse_tree(table
,
695 print_idecode_table_start
,
696 print_idecode_table_leaf
,
697 print_idecode_table_end
,
698 print_idecode_table_padding
);
701 /* output switch functions where needed */
702 insn_table_traverse_tree(table
,
705 idecode_expand_if_switch
, /* START */
711 print_idecode_body(lf
*file
,
715 if (table
->opcode_rule
->gen
== switch_gen
716 || table
->opcode_rule
->gen
== goto_switch_gen
717 || table
->opcode_rule
->gen
== padded_switch_gen
)
718 print_idecode_switch(file
, table
, result
);
720 print_idecode_table(file
, table
, result
);
724 /****************************************************************/
728 print_idecode_issue_function_body(lf
*file
,
732 lf_printf(file
, "{\n");
734 lf_printf(file
, "%sinstruction_address nia;\n", global_name_prefix
);
735 if (!(code
& generate_with_icache
)) {
736 print_idecode_body(file
, table
, "nia =");;
739 error("FIXME - idecode with cache?\n");
740 lf_putstr(file
, "idecode_cache *cache_entry =\n");
741 lf_putstr(file
, " cpu_icache_entry(cpu, cia);\n");
742 lf_putstr(file
, "if (cache_entry->address == cia) {\n");
743 lf_putstr(file
, " /* cache hit */\n");
744 lf_putstr(file
, " idecode_semantic *const semantic = cache_entry->semantic;\n");
745 lf_putstr(file
, " cia = semantic(cpu, cache_entry, cia);\n");
748 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
749 lf_putstr(file
, " cpu_halt(cpu, cia, was_continuing, 0/*ignore*/);\n");
751 lf_putstr(file
, "}\n");
752 lf_putstr(file
, "else {\n");
753 lf_putstr(file
, " /* cache miss */\n");
754 if (!(code
& generate_with_semantic_icache
)) {
756 lf_putstr(file
, "idecode_semantic *semantic;\n");
759 lf_putstr(file
, " instruction_word instruction =\n");
760 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(cpu), cpu, cia);\n");
761 lf_putstr(file
, " if (WITH_MON != 0)\n");
762 lf_putstr(file
, " mon_event(mon_event_icache_miss, cpu, cia);\n");
763 if ((code
& generate_with_semantic_icache
)) {
764 lf_putstr(file
, "{\n");
766 print_idecode_body(file
, table
, "cia =");
768 lf_putstr(file
, "}\n");
771 print_idecode_body(file
, table
, "semantic =");
772 lf_putstr(file
, " cia = semantic(cpu, cache_entry, cia);\n");
774 lf_putstr(file
, "}\n");
776 lf_printf(file
, "return nia;\n");
778 lf_printf(file
, "}\n");
782 /****************************************************************/
789 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
790 lf_putstr(file
, " cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n");
794 lf_putstr(file
, "if (WITH_EVENTS) {\n");
795 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
796 lf_putstr(file
, " cpu_set_program_counter(cpu, nia);\n");
797 lf_putstr(file
, " event_queue_process(events);\n");
798 lf_putstr(file
, " nia = cpu_get_program_counter(cpu);\n");
799 lf_putstr(file
, " }\n");
800 lf_putstr(file
, "}\n");
805 lf_putstr(file
, "cpu_set_program_counter(cpu, nia);\n");
806 lf_putstr(file
, "if (WITH_EVENTS) {\n");
807 lf_putstr(file
, " current_cpu += 1;\n");
808 lf_putstr(file
, " if (current_cpu >= nr_cpus) {\n");
809 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
810 lf_putstr(file
, " event_queue_process(events);\n");
811 lf_putstr(file
, " }\n");
812 lf_putstr(file
, " current_cpu = 0;\n");
813 lf_putstr(file
, " }\n");
814 lf_putstr(file
, "}\n");
815 lf_putstr(file
, "else {\n");
816 lf_putstr(file
, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
817 lf_putstr(file
, "}\n");
818 lf_putstr(file
, "cpu = cpus[current_cpu];\n");
819 lf_putstr(file
, "nia = cpu_get_program_counter(cpu);\n");
822 if ((code
& generate_with_icache
)) {
823 lf_putstr(file
, "cache_entry = cpu_icache_entry(cpu, nia);\n");
824 lf_putstr(file
, "if (cache_entry->address == nia) {\n");
825 lf_putstr(file
, " /* cache hit */\n");
826 lf_putstr(file
, " goto *cache_entry->semantic;\n");
827 lf_putstr(file
, "}\n");
829 lf_putstr(file
, "goto cache_miss;\n");
833 if (!(code
& generate_with_icache
) && is_tail
) {
834 lf_printf(file
, "goto idecode;\n");
844 print_jump_insn(lf
*file
,
846 insn_bits
*expanded_bits
,
847 opcode_field
*opcodes
,
848 cache_table
*cache_rules
)
851 /* what we are for the moment */
852 lf_printf(file
, "\n");
853 print_my_defines(file
, expanded_bits
, instruction
->file_entry
);
855 /* output the icache entry */
856 if ((code
& generate_with_icache
)) {
857 lf_printf(file
, "\n");
859 print_function_name(file
,
860 instruction
->file_entry
->fields
[insn_name
],
862 function_name_prefix_icache
);
863 lf_printf(file
, ":\n");
865 lf_printf(file
, "{\n");
867 lf_putstr(file
, "const unsigned_word cia = nia;\n");
868 print_itrace(file
, instruction
->file_entry
, 1/*putting-value-in-cache*/);
869 print_idecode_validate(file
, instruction
, opcodes
);
870 lf_printf(file
, "\n");
871 lf_printf(file
, "{\n");
873 print_icache_body(file
,
878 put_values_in_icache
);
879 lf_printf(file
, "cache_entry->address = nia;\n");
880 lf_printf(file
, "cache_entry->semantic = &&");
881 print_function_name(file
,
882 instruction
->file_entry
->fields
[insn_name
],
884 function_name_prefix_semantics
);
885 lf_printf(file
, ";\n");
886 if ((code
& generate_with_semantic_icache
)) {
887 print_semantic_body(file
,
891 print_jump(file
, 1/*is-tail*/);
894 lf_printf(file
, "/* goto ");
895 print_function_name(file
,
896 instruction
->file_entry
->fields
[insn_name
],
898 function_name_prefix_semantics
);
899 lf_printf(file
, "; */\n");
902 lf_putstr(file
, "}\n");
904 lf_printf(file
, "}\n");
907 /* print the semantics */
908 lf_printf(file
, "\n");
910 print_function_name(file
,
911 instruction
->file_entry
->fields
[insn_name
],
913 function_name_prefix_semantics
);
914 lf_printf(file
, ":\n");
916 lf_printf(file
, "{\n");
918 lf_putstr(file
, "const unsigned_word cia = nia;\n");
919 print_icache_body(file
,
923 ((code
& generate_with_direct_access
)
925 : declare_variables
),
926 ((code
& generate_with_icache
)
927 ? get_values_from_icache
928 : do_not_use_icache
));
929 print_semantic_body(file
,
933 if (code
& generate_with_direct_access
)
934 print_icache_body(file
,
939 ((code
& generate_with_icache
)
940 ? get_values_from_icache
941 : do_not_use_icache
));
942 print_jump(file
, 1/*is tail*/);
944 lf_printf(file
, "}\n");
948 print_jump_definition(insn_table
*entry
,
954 cache_table
*cache_rules
= (cache_table
*)data
;
955 if (generate_expanded_instructions
) {
956 ASSERT(entry
->nr_insn
== 1
957 && entry
->opcode
== NULL
958 && entry
->parent
!= NULL
959 && entry
->parent
->opcode
!= NULL
);
960 ASSERT(entry
->nr_insn
== 1
961 && entry
->opcode
== NULL
962 && entry
->parent
!= NULL
963 && entry
->parent
->opcode
!= NULL
964 && entry
->parent
->opcode_rule
!= NULL
);
965 print_jump_insn(file
,
967 entry
->expanded_bits
,
972 print_jump_insn(file
,
981 print_jump_internal_function(insn_table
*table
,
984 table_entry
*function
)
986 if (it_is("internal", function
->fields
[insn_flags
])) {
987 lf_printf(file
, "\n");
988 table_entry_print_cpp_line_nr(file
, function
);
990 print_function_name(file
,
991 function
->fields
[insn_name
],
993 ((code
& generate_with_icache
)
994 ? function_name_prefix_icache
995 : function_name_prefix_semantics
));
996 lf_printf(file
, ":\n");
998 lf_printf(file
, "{\n");
1000 lf_printf(file
, "const unsigned_word cia = nia;\n");
1001 lf_print__c_code(file
, function
->annex
);
1002 lf_print__internal_reference(file
);
1003 lf_printf(file
, "error(\"Internal function must longjump\\n\");\n");
1004 lf_indent(file
, -2);
1005 lf_printf(file
, "}\n");
1011 print_jump_until_stop_body(lf
*file
,
1013 cache_table
*cache_rules
,
1016 lf_printf(file
, "{\n");
1017 lf_indent(file
, +2);
1019 lf_printf(file
, "int *keep_running = NULL;\n");
1020 lf_putstr(file
, "jmp_buf halt;\n");
1021 lf_putstr(file
, "jmp_buf restart;\n");
1022 lf_putstr(file
, "sim_cpu *cpu = NULL;\n");
1023 lf_putstr(file
, "unsigned_word nia = -1;\n");
1024 lf_putstr(file
, "instruction_word instruction = 0;\n");
1025 if ((code
& generate_with_icache
)) {
1026 lf_putstr(file
, "idecode_cache *cache_entry = NULL;\n");
1029 lf_putstr(file
, "int current_cpu = -1;\n");
1032 /* all the switches and tables - they know about jumping */
1033 print_idecode_lookups(file
, table
, cache_rules
);
1035 /* start the simulation up */
1036 if ((code
& generate_with_icache
)) {
1037 lf_putstr(file
, "\n");
1038 lf_putstr(file
, "{\n");
1039 lf_putstr(file
, " int cpu_nr;\n");
1040 lf_putstr(file
, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
1041 lf_putstr(file
, " cpu_flush_icache(cpus[cpu_nr]);\n");
1042 lf_putstr(file
, "}\n");
1045 lf_putstr(file
, "\n");
1046 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1048 lf_putstr(file
, "\n");
1049 lf_putstr(file
, "if (setjmp(halt))\n");
1050 lf_putstr(file
, " return;\n");
1052 lf_putstr(file
, "\n");
1053 lf_putstr(file
, "setjmp(restart);\n");
1055 lf_putstr(file
, "\n");
1056 if (!generate_smp
) {
1057 lf_putstr(file
, "cpu = cpus[0];\n");
1058 lf_putstr(file
, "nia = cpu_get_program_counter(cpu);\n");
1061 lf_putstr(file
, "current_cpu = psim_last_cpu(system);\n");
1064 if (!(code
& generate_with_icache
)) {
1065 lf_printf(file
, "\n");
1066 lf_indent(file
, -1);
1067 lf_printf(file
, "idecode:\n");
1068 lf_indent(file
, +1);
1071 print_jump(file
, 0/*is_tail*/);
1073 if ((code
& generate_with_icache
)) {
1074 lf_indent(file
, -1);
1075 lf_printf(file
, "cache_miss:\n");
1076 lf_indent(file
, +1);
1079 lf_putstr(file
, "instruction\n");
1080 lf_putstr(file
, " = vm_instruction_map_read(cpu_instruction_map(cpu),\n");
1081 lf_putstr(file
, " cpu, nia);\n");
1082 print_idecode_body(file
, table
, "/*IGORE*/");
1084 /* print out a table of all the internals functions */
1085 insn_table_traverse_function(table
,
1087 print_jump_internal_function
);
1089 /* print out a table of all the instructions */
1090 if (generate_expanded_instructions
)
1091 insn_table_traverse_tree(table
,
1095 print_jump_definition
, /* leaf */
1097 NULL
); /* padding */
1099 insn_table_traverse_insn(table
,
1101 print_jump_definition
);
1102 lf_indent(file
, -2);
1103 lf_printf(file
, "}\n");
1107 /****************************************************************/
1111 /* Output code to do any final checks on the decoded instruction.
1112 This includes things like verifying any on decoded fields have the
1113 correct value and checking that (for floating point) floating point
1114 hardware isn't disabled */
1117 print_idecode_validate(lf
*file
,
1119 opcode_field
*opcodes
)
1121 /* Validate: unchecked instruction fields
1123 If any constant fields in the instruction were not checked by the
1124 idecode tables, output code to check that they have the correct
1127 insn_int check_mask
= 0;
1128 insn_int check_val
= 0;
1130 opcode_field
*opcode
;
1132 /* form check_mask/check_val containing what needs to be checked
1133 in the instruction */
1134 for (field
= instruction
->fields
->first
;
1135 field
->first
< insn_bit_size
;
1136 field
= field
->next
) {
1138 check_mask
<<= field
->width
;
1139 check_val
<<= field
->width
;
1141 /* is it a constant that could need validating? */
1142 if (!field
->is_int
&& !field
->is_reserved
)
1145 /* has it been checked by a table? */
1146 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1147 if (field
->first
>= opcode
->first
1148 && field
->last
<= opcode
->last
)
1154 check_mask
|= (1 << field
->width
)-1;
1155 check_val
|= field
->val_int
;
1158 /* if any bits not checked by opcode tables, output code to check them */
1160 lf_printf(file
, "\n");
1161 lf_indent_suppress(file
);
1162 lf_printf(file
, "#if defined(WITH_RESERVED_BITS)\n");
1163 lf_printf(file
, "/* validate: %s */\n",
1164 instruction
->file_entry
->fields
[insn_format
]);
1165 lf_printf(file
, "if (WITH_RESERVED_BITS\n");
1166 if (insn_bit_size
> 32) {
1167 lf_printf(file
, " && (instruction & 0x%08lx%08lxLL) != 0x%08lx%08lxLL) {\n",
1168 (unsigned long)(check_mask
>> 32),
1169 (unsigned long)(check_mask
),
1170 (unsigned long)(check_val
>> 32),
1171 (unsigned long)(check_val
));
1174 lf_printf(file
, " && (instruction & 0x%08lx) != 0x%08lx) {\n",
1175 (unsigned long)(check_mask
),
1176 (unsigned long)(check_val
));
1178 lf_indent(file
, +2);
1179 print_idecode_invalid(file
, "return", invalid_illegal
);
1180 lf_indent(file
, -2);
1181 lf_printf(file
, "}\n");
1182 lf_indent_suppress(file
);
1183 lf_printf(file
, "#endif\n");
1187 /* Validate: Floating Point hardware
1189 If the simulator is being built with out floating point hardware
1190 (different to it being disabled in the MSR) then floating point
1191 instructions are invalid */
1193 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1194 lf_printf(file
, "\n");
1195 lf_indent_suppress(file
);
1196 lf_printf(file
, "#if defined(CURRENT_FLOATING_POINT\n");
1197 lf_printf(file
, "/* Validate: FP hardware exists */\n");
1198 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
1199 lf_indent(file
, +2);
1200 print_idecode_invalid(file
, "return", invalid_illegal
);
1201 lf_indent(file
, -2);
1202 lf_printf(file
, "}\n");
1203 lf_indent_suppress(file
);
1204 lf_printf(file
, "#endif\n");
1208 /* Validate: Floating Point available
1210 If floating point is not available, we enter a floating point
1211 unavailable interrupt into the cache instead of the instruction
1214 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1215 ever a CSI occures we flush the instruction cache. */
1218 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1219 lf_printf(file
, "\n");
1220 lf_indent_suppress(file
);
1221 lf_printf(file
, "#if defined(IS_FP_AVAILABLE)\n");
1222 lf_printf(file
, "/* Validate: FP available according to cpu */\n");
1223 lf_printf(file
, "if (!IS_FP_AVAILABLE) {\n");
1224 lf_indent(file
, +2);
1225 print_idecode_invalid(file
, "return", invalid_fp_unavailable
);
1226 lf_indent(file
, -2);
1227 lf_printf(file
, "}\n");
1228 lf_indent_suppress(file
);
1229 lf_printf(file
, "#endif\n");
1233 /* Validate: Validate Instruction in correct slot
1235 Some architectures place restrictions on the slot that an
1236 instruction can be issued in */
1239 if (it_is("s", instruction
->file_entry
->fields
[insn_options
])
1240 || (code
& generate_with_idecode_slot_verification
)) {
1241 lf_printf(file
, "\n");
1242 lf_indent_suppress(file
);
1243 lf_printf(file
, "#if defined(IS_WRONG_SLOT)\n");
1244 lf_printf(file
, "/* Validate: Instruction issued in correct slot */\n");
1245 lf_printf(file
, "if (IS_WRONG_SLOT) {\n");
1246 lf_indent(file
, +2);
1247 print_idecode_invalid(file
, "return", invalid_wrong_slot
);
1248 lf_indent(file
, -2);
1249 lf_printf(file
, "}\n");
1250 lf_indent_suppress(file
);
1251 lf_printf(file
, "#endif\n");
1258 /****************************************************************/
1262 print_idecode_issue_function_header(lf
*file
,
1263 int is_function_definition
)
1266 lf_printf(file
, "\n");
1267 lf_print_function_type_function(file
, print_semantic_function_type
, "INLINE_IDECODE",
1268 (is_function_definition
? "\n" : " "));
1269 indent
= print_function_name(file
, "issue", NULL
, function_name_prefix_idecode
);
1270 if (is_function_definition
)
1271 lf_indent(file
, +indent
);
1273 lf_putstr(file
, "\n");
1274 lf_putstr(file
, "(");
1275 print_semantic_function_formal(file
);
1276 lf_putstr(file
, ")");
1277 if (is_function_definition
)
1278 lf_indent(file
, -indent
);
1280 lf_printf(file
, ";");
1281 lf_printf(file
, "\n");
1286 gen_idecode_h (lf
*file
,
1288 cache_table
*cache_rules
)
1290 lf_printf(file
, "typedef unsigned%d %sinstruction_word;\n",
1291 insn_bit_size
, global_name_prefix
);
1293 if ((code
& generate_with_semantic_delayed_branch
))
1295 lf_printf (file
, "typedef struct _%sinstruction_address {\n",
1296 global_name_prefix
);
1297 lf_printf (file
, " address_word ip; /* instruction pointer */\n");
1298 lf_printf (file
, " address_word dp; /* delayed-slot pointer */\n");
1299 lf_printf (file
, "} %sinstruction_address;\n", global_name_prefix
);
1303 lf_printf (file
, "typedef address_word %sinstruction_address;\n",
1304 global_name_prefix
);
1307 lf_printf(file
, "\n");
1308 print_icache_struct(table
, cache_rules
, file
);
1309 lf_printf(file
, "\n");
1310 if ((code
& generate_with_icache
))
1312 error("FIXME - idecode with icache incomplete");
1316 print_idecode_issue_function_header(file
, 0/*is definition*/);
1322 print_idecode_globals(lf
*file
,
1324 cache_table
*cache_rules
)
1326 lf_printf(file
, "enum {\n");
1327 lf_printf(file
, " /* greater or equal to zero => table */\n");
1328 lf_printf(file
, " function_entry = -1,\n");
1329 lf_printf(file
, " boolean_entry = -2,\n");
1330 lf_printf(file
, "};\n");
1331 lf_printf(file
, "\n");
1332 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
1333 lf_printf(file
, " int shift;\n");
1334 lf_printf(file
, " unsigned%d mask;\n", insn_bit_size
);
1335 lf_printf(file
, " unsigned%d value;\n", insn_bit_size
);
1336 lf_printf(file
, " void *function_or_table;\n");
1337 lf_printf(file
, "} idecode_table_entry;\n");
1342 gen_idecode_c(lf
*file
,
1344 cache_table
*cache_rules
)
1347 lf_printf(file
, "#include \"sim-main.h\"\n");
1348 lf_printf(file
, "#include \"%sidecode.h\"\n", global_name_prefix
);
1349 lf_printf(file
, "#include \"%ssemantics.h\"\n", global_name_prefix
);
1350 lf_printf(file
, "#include \"%sicache.h\"\n", global_name_prefix
);
1351 lf_printf(file
, "#include \"%ssupport.h\"\n", global_name_prefix
);
1352 lf_printf(file
, "\n");
1353 lf_printf(file
, "\n");
1355 print_idecode_globals(file
, table
, cache_rules
);
1356 lf_printf(file
, "\n");
1358 if ((code
& generate_calls
)) {
1360 print_idecode_lookups(file
, table
, cache_rules
);
1362 /* output the main idecode routine */
1363 if ((code
& generate_with_icache
)) {
1364 error("FIXME - handle the icache");
1367 print_idecode_issue_function_header(file
, 1/*is definition*/);
1368 print_idecode_issue_function_body(file
, table
, 0/* have stop argument */);
1372 else if ((code
& generate_jumps
)) {
1374 lf_printf(file
, "/* this file is intentionally left blank - generating a jump engine */\n");
1378 error("Something is wrong!\n");