1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, 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 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 /* int can_assume_leaf; */
74 decode_table
*opcode_rule
;
76 /* have a look at the rule table, if all table rules follow all
77 switch rules, I can assume that all end points are leaves */
78 opcode_rule
= entry
->opcode_rule
;
79 while (opcode_rule
!= NULL
80 && (opcode_rule
->gen
== switch_gen
81 || opcode_rule
->gen
== padded_switch_gen
))
82 opcode_rule
= opcode_rule
->next
;
85 /* FIXME: I don't get this bit! */
86 while (opcode_rule
!= NULL
87 && (opcode_rule
->gen
== switch_gen
88 || opcode_rule
->gen
== padded_switch_gen
)
89 && opcode_rule
->type
!= normal_decode_rule
)
90 opcode_rule
= opcode_rule
->next
;
91 can_assume_leaf
= opcode_rule
== NULL
;
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 = EXTRACTED32(instruction, %d, %d);\n",
98 i2target(hi_bit_nr
, entry
->opcode
->first
),
99 i2target(hi_bit_nr
, entry
->opcode
->last
));
100 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
101 lf_printf(file
, "while (1) {\n");
104 lf_printf(file
, "/* nonzero mask -> another table */\n");
105 lf_printf(file
, "while (table_entry->shift >= 0) {\n");
108 lf_printf(file
, "table = ((idecode_table_entry*)\n");
109 lf_printf(file
, " table_entry->function_or_table);\n");
110 lf_printf(file
, "opcode = ((instruction & table_entry->mask)\n");
111 lf_printf(file
, " >> table_entry->shift);\n");
112 lf_printf(file
, "table_entry = table + opcode;\n");
115 lf_printf(file
, "}\n");
116 lf_printf(file
, "ASSERT(table_entry->shift < 0);\n");
117 lf_printf(file
, "/* found the leaf */\n");
118 lf_printf(file
, "if (table_entry->shift == table_function_entry) {\n");
120 if ((code
& generate_jumps
)) {
121 lf_printf(file
, "goto *table_entry->function_or_table;\n");
124 lf_printf(file
, "%s ", result
);
125 if ((code
& generate_with_icache
)) {
126 lf_printf(file
, "(((idecode_icache*)table_entry->function_or_table)\n");
127 lf_printf(file
, " (%s));\n", ICACHE_FUNCTION_ACTUAL
);
130 lf_printf(file
, "((idecode_semantic*)table_entry->function_or_table)\n");
131 lf_printf(file
, " (%s);\n", SEMANTIC_FUNCTION_ACTUAL
);
134 lf_printf(file
, "break;\n");
136 lf_printf(file
, "}\n");
137 lf_printf(file
, "/* must be a boolean */\n");
138 lf_printf(file
, "opcode = (((instruction << table_entry->left)\n");
139 lf_printf(file
, " >> table_entry->right)\n");
140 lf_printf(file
, " != table_entry->mask);\n");
141 lf_printf(file
, "table = ((idecode_table_entry*)\n");
142 lf_printf(file
, " table_entry->function_or_table);\n");
143 lf_printf(file
, "table_entry = table + opcode;\n");
146 lf_printf(file
, "}\n");
151 print_idecode_table_start(insn_table
*table
,
157 /* start of the table */
158 if (table
->opcode_rule
->gen
== array_gen
) {
159 lf_printf(file
, "\n");
160 lf_printf(file
, "static idecode_table_entry ");
161 lf_print_table_name(file
, table
);
162 lf_printf(file
, "[] = {\n");
167 print_idecode_table_leaf(insn_table
*entry
,
173 ASSERT(entry
->parent
!= NULL
);
176 /* add an entry to the table */
177 if (entry
->parent
->opcode_rule
->gen
== array_gen
) {
178 if (entry
->opcode
== NULL
) {
179 /* table leaf entry */
180 lf_printf(file
, " /*%d*/ { table_function_entry, 0, 0, 0, ", entry
->opcode_nr
);
181 if ((code
& generate_jumps
))
182 lf_printf(file
, "&&");
183 print_function_name(file
,
184 entry
->insns
->file_entry
->fields
[insn_name
],
185 entry
->expanded_bits
,
186 ((code
& generate_with_icache
)
187 ? function_name_prefix_icache
188 : function_name_prefix_semantics
));
189 lf_printf(file
, " },\n");
191 else if (entry
->opcode_rule
->gen
== switch_gen
192 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
193 /* table calling switch statement */
194 lf_printf(file
, " /*%d*/ { table_function_entry, 0, 0, 0, ",
196 if ((code
& generate_jumps
))
197 lf_printf(file
, "&&");
198 lf_print_table_name(file
, entry
);
199 lf_printf(file
, " },\n");
202 /* table `calling' another table */
203 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
204 if (entry
->opcode
->is_boolean
)
205 lf_printf(file
, "table_boolean_entry, %d, %d, %d, ",
206 entry
->opcode
->first
,
207 insn_bit_size
- entry
->opcode
->last
+ entry
->opcode
->first
- 1,
208 entry
->opcode
->boolean_constant
);
210 lf_printf(file
, "%d, 0, 0, MASK32(%d,%d), ",
211 insn_bit_size
- entry
->opcode
->last
- 1,
212 i2target(hi_bit_nr
, entry
->opcode
->first
),
213 i2target(hi_bit_nr
, entry
->opcode
->last
));
214 lf_print_table_name(file
, entry
);
215 lf_printf(file
, " },\n");
221 print_idecode_table_end(insn_table
*table
,
227 if (table
->opcode_rule
->gen
== array_gen
) {
228 lf_printf(file
, "};\n");
233 print_idecode_table_padding(insn_table
*table
,
240 if (table
->opcode_rule
->gen
== array_gen
) {
241 lf_printf(file
, " /*%d*/ { table_function_entry, 0, 0, 0, ", opcode_nr
);
242 if ((code
& generate_jumps
))
243 lf_printf(file
, "&&");
244 lf_printf(file
, "%s_illegal },\n",
245 ((code
& generate_with_icache
) ? "icache" : "semantic"));
250 /****************************************************************/
253 void print_idecode_switch
260 idecode_switch_start(insn_table
*table
,
265 /* const char *result = data; */
267 ASSERT(table
->opcode_rule
->gen
== switch_gen
268 || table
->opcode_rule
->gen
== padded_switch_gen
269 || table
->opcode_rule
->gen
== goto_gen
);
271 switch (table
->opcode_rule
->gen
) {
273 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
274 i2target(hi_bit_nr
, table
->opcode
->first
),
275 i2target(hi_bit_nr
, table
->opcode
->last
));
282 idecode_switch_leaf(insn_table
*entry
,
288 const char *result
= data
;
289 ASSERT(entry
->parent
!= NULL
);
291 ASSERT(entry
->parent
->opcode_rule
->gen
== switch_gen
292 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
);
293 ASSERT(entry
->parent
->opcode
);
295 if (entry
->parent
->opcode
->is_boolean
296 && entry
->opcode_nr
== 0)
297 lf_printf(file
, "case %d:\n", entry
->parent
->opcode
->boolean_constant
);
298 else if (!entry
->parent
->opcode
->is_boolean
)
299 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
301 lf_printf(file
, "default:\n");
304 if (entry
->opcode
== NULL
) {
305 /* switch calling leaf */
306 if ((code
& generate_jumps
))
307 lf_printf(file
, "goto ");
308 if ((code
& generate_calls
))
309 lf_printf(file
, "%s ", result
);
310 print_function_name(file
,
311 entry
->insns
->file_entry
->fields
[insn_name
],
312 entry
->expanded_bits
,
313 ((code
& generate_with_icache
)
314 ? function_name_prefix_icache
315 : function_name_prefix_semantics
));
316 if ((code
& generate_calls
))
317 lf_printf(file
, "(%s)", SEMANTIC_FUNCTION_ACTUAL
);
318 lf_printf(file
, ";\n");
320 else if (entry
->opcode_rule
->gen
== switch_gen
321 || entry
->opcode_rule
->gen
== padded_switch_gen
) {
322 /* switch calling switch */
323 print_idecode_switch(file
, entry
, result
);
326 /* switch looking up a table */
327 lf_printf(file
, "{\n");
329 print_idecode_table(file
, entry
, result
);
331 lf_printf(file
, "}\n");
333 lf_printf(file
, "break;\n");
340 print_idecode_switch_illegal(lf
*file
,
344 print_idecode_illegal(file
, result
);
345 /*lf_printf(file, "break;\n");*/
350 idecode_switch_end(insn_table
*table
,
355 const char *result
= data
;
357 ASSERT(table
->opcode_rule
->gen
== switch_gen
358 || table
->opcode_rule
->gen
== padded_switch_gen
359 || table
->opcode_rule
->gen
== goto_gen
);
360 ASSERT(table
->opcode
);
362 if (!table
->opcode
->is_boolean
) {
363 lf_printf(file
, "default:\n");
364 switch (table
->opcode_rule
->gen
) {
366 print_idecode_switch_illegal(file
, result
);
368 case padded_switch_gen
:
369 lf_printf(file
, " error(\"Internal error - bad switch generated\\n\");\n");
370 lf_printf(file
, " break;\n");
373 error("idecode_switch_end - unknown switch type\n");
376 lf_printf(file
, "}\n");
380 idecode_switch_padding(insn_table
*table
,
386 const char *result
= data
;
388 ASSERT(table
->opcode_rule
->gen
== switch_gen
389 || table
->opcode_rule
->gen
== padded_switch_gen
);
391 if (table
->opcode_rule
->gen
== padded_switch_gen
) {
392 lf_printf(file
, "case %d:\n", opcode_nr
);
393 print_idecode_switch_illegal(file
, result
);
395 else if (table
->opcode_rule
->gen
== goto_gen
) {
396 lf_printf(file
, "goto_%d:\n", opcode_nr
);
397 print_idecode_switch_illegal(file
, result
);
403 print_idecode_switch(lf
*file
,
407 insn_table_traverse_tree(table
,
410 idecode_switch_start
,
413 idecode_switch_padding
);
418 print_idecode_switch_function_header(lf
*file
,
420 int is_function_definition
)
422 lf_printf(file
, "\n");
423 if ((code
& generate_calls
)) {
424 lf_printf(file
, "static ");
425 if ((code
& generate_with_icache
))
426 lf_printf(file
, "idecode_semantic *");
428 lf_printf(file
, "unsigned_word");
429 if (is_function_definition
)
430 lf_printf(file
, "\n");
432 lf_printf(file
, " ");
433 lf_print_table_name(file
, table
);
434 lf_printf(file
, "\n(%s)", ICACHE_FUNCTION_FORMAL
);
435 if (!is_function_definition
)
436 lf_printf(file
, ";");
437 lf_printf(file
, "\n");
439 if ((code
& generate_jumps
) && is_function_definition
) {
441 lf_print_table_name(file
, table
);
442 lf_printf(file
, ":\n");
449 idecode_declare_if_switch(insn_table
*table
,
454 if ((table
->opcode_rule
->gen
== switch_gen
455 || table
->opcode_rule
->gen
== padded_switch_gen
)
456 && table
->parent
!= NULL
/* don't declare the top one yet */
457 && table
->parent
->opcode_rule
->gen
== array_gen
) {
458 print_idecode_switch_function_header(file
,
460 0/*isnt function definition*/);
466 idecode_expand_if_switch(insn_table
*table
,
471 if ((table
->opcode_rule
->gen
== switch_gen
472 || table
->opcode_rule
->gen
== padded_switch_gen
)
473 && table
->parent
!= NULL
/* don't expand the top one yet */
474 && table
->parent
->opcode_rule
->gen
== array_gen
) {
475 print_idecode_switch_function_header(file
,
477 1/*is function definition*/);
478 if ((code
& generate_calls
)) {
479 lf_printf(file
, "{\n");
482 print_idecode_switch(file
, table
, "return");
483 if ((code
& generate_calls
)) {
485 lf_printf(file
, "}\n");
491 /****************************************************************/
495 print_idecode_lookups(lf
*file
,
497 cache_table
*cache_rules
)
501 /* output switch function declarations where needed by tables */
502 insn_table_traverse_tree(table
,
505 idecode_declare_if_switch
, /* START */
508 /* output tables where needed */
509 for (depth
= insn_table_depth(table
);
512 insn_table_traverse_tree(table
,
515 print_idecode_table_start
,
516 print_idecode_table_leaf
,
517 print_idecode_table_end
,
518 print_idecode_table_padding
);
521 /* output switch functions where needed */
522 insn_table_traverse_tree(table
,
525 idecode_expand_if_switch
, /* START */
531 print_idecode_body(lf
*file
,
536 lf_indent(file
, +strlen(indent
));
537 lf_putstr(file
, "{\n");
539 if (table
->opcode_rule
->gen
== switch_gen
540 || table
->opcode_rule
->gen
== padded_switch_gen
)
541 print_idecode_switch(file
, table
, result
);
543 print_idecode_table(file
, table
, result
);
545 lf_putstr(file
, "}\n");
546 lf_indent(file
, -strlen(indent
));
550 /****************************************************************/
554 print_run_until_stop_body(lf
*file
,
558 /* Output the function to execute real code:
560 Unfortunatly, there are multiple cases to consider vis:
562 <icache> X <smp> X <events> X <keep-running-flag> X ...
564 Consequently this function is written in multiple different ways */
566 lf_putstr(file
, "{\n");
569 lf_putstr(file
, "int *keep_running = NULL;\n");
570 lf_putstr(file
, "jmp_buf halt;\n");
571 lf_putstr(file
, "jmp_buf restart;\n");
572 lf_putstr(file
, "cpu *processor = NULL;\n");
573 lf_putstr(file
, "unsigned_word cia = -1;\n");
574 lf_putstr(file
, "instruction_word instruction = 0;\n");
576 lf_putstr(file
, "int current_cpu = -1;\n");
578 if ((code
& generate_with_icache
)) {
579 lf_putstr(file
, "idecode_cache *cache_entry = NULL;\n");
582 if ((code
& generate_with_icache
)) {
583 lf_putstr(file
, "\n");
584 lf_putstr(file
, "{\n");
585 lf_putstr(file
, " int cpu_nr;\n");
586 lf_putstr(file
, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
587 lf_putstr(file
, " cpu_flush_icache(processors[cpu_nr]);\n");
588 lf_putstr(file
, "}\n");
591 lf_putstr(file
, "\n");
592 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
594 lf_putstr(file
, "\n");
595 lf_putstr(file
, "if (setjmp(halt))\n");
596 lf_putstr(file
, " return;\n");
598 lf_putstr(file
, "\n");
599 lf_putstr(file
, "setjmp(restart);\n");
604 /* CASE 1: NO SMP (with or with out instruction cache).
606 In this case, we can take advantage of the fact that the current
607 instruction address does not need to be returned to the cpu object
608 after every execution of an instruction. Instead it only needs to
609 be saved when either A. the main loop exits or B. A cpu-halt or
610 cpu-restart call forces the loop to be re-enered. The later
611 functions always save the current cpu instruction address.
613 Two subcases also exist that with and that without an instruction
616 lf_putstr(file
, "\n\n");
618 lf_putstr(file
, "processor = processors[0];\n");
619 lf_putstr(file
, "cia = cpu_get_program_counter(processor);\n");
620 lf_putstr(file
, "while (1) {\n");
622 lf_putstr(file
, "if (WITH_EVENTS) {\n");
623 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
624 lf_putstr(file
, " cpu_set_program_counter(processor, cia);\n");
625 lf_putstr(file
, " event_queue_process(events);\n");
626 lf_putstr(file
, " cia = cpu_get_program_counter(processor);\n");
627 lf_putstr(file
, " }\n");
628 lf_putstr(file
, "}\n");
630 if (!(code
& generate_with_icache
)) {
631 lf_putstr(file
, "instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
632 print_idecode_body(file
, table
, "cia =", "");
635 if ((code
& generate_with_icache
)) {
636 lf_putstr(file
, "cache_entry = cpu_icache_entry(processor, cia);\n");
637 lf_putstr(file
, "if (cache_entry->address == cia) {\n");
638 lf_putstr(file
, " /* cache hit */\n");
639 lf_putstr(file
, " idecode_semantic *const semantic = cache_entry->semantic;\n");
640 lf_putstr(file
, " cia = semantic(processor, cache_entry, cia);\n");
641 lf_putstr(file
, "}\n");
642 lf_putstr(file
, "else {\n");
643 lf_putstr(file
, " /* cache miss */\n");
644 if (!(code
& generate_with_semantic_icache
)) {
646 lf_putstr(file
, "idecode_semantic *semantic;\n");
649 lf_putstr(file
, " instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
650 lf_putstr(file
, " if (WITH_MON != 0)\n");
651 lf_putstr(file
, " mon_event(mon_event_icache_miss, processor, cia);\n");
652 if ((code
& generate_with_semantic_icache
)) {
653 print_idecode_body(file
, table
, "cia =", " ");
656 print_idecode_body(file
, table
, "semantic =", " ");
657 lf_putstr(file
, " cia = semantic(processor, cache_entry, cia);\n");
659 lf_putstr(file
, "}\n");
662 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
663 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
665 lf_putstr(file
, "}\n");
671 /* CASE 2: SMP (With or without ICACHE)
673 The complexity here comes from needing to correctly restart the
674 system when it is aborted. In particular if cpu0 requests a
675 restart, the next cpu is still cpu1. Cpu0 being restarted after
676 all the other CPU's and the event queue have been processed */");
678 lf_putstr(file
, "\n\n");
680 lf_putstr(file
, "current_cpu = psim_last_cpu(system);\n");
681 lf_putstr(file
, "while (1) {\n");
683 lf_putstr(file
, "if (WITH_EVENTS) {\n");
684 lf_putstr(file
, " current_cpu += 1;\n");
685 lf_putstr(file
, " if (current_cpu == nr_cpus) {\n");
686 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
687 lf_putstr(file
, " event_queue_process(events);\n");
688 lf_putstr(file
, " }\n");
689 lf_putstr(file
, " current_cpu = 0;\n");
690 lf_putstr(file
, " }\n");
691 lf_putstr(file
, "}\n");
692 lf_putstr(file
, "else {\n");
693 lf_putstr(file
, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
694 lf_putstr(file
, "}\n");
695 lf_putstr(file
, "processor = processors[current_cpu];\n");
696 lf_putstr(file
, "cia = cpu_get_program_counter(processor);\n");
698 if (!(code
& generate_with_icache
)) {
699 lf_putstr(file
, "instruction = vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
700 print_idecode_body(file
, table
, "cia =", "");
703 if ((code
& generate_with_icache
)) {
704 lf_putstr(file
, "cache_entry = cpu_icache_entry(processor, cia);\n");
705 lf_putstr(file
, "if (cache_entry->address == cia) {\n");
706 lf_putstr(file
, " /* cache hit */\n");
707 lf_putstr(file
, " idecode_semantic *semantic = cache_entry->semantic;\n");
708 lf_putstr(file
, " cia = semantic(processor, cache_entry, cia);\n");
709 lf_putstr(file
, "}\n");
710 lf_putstr(file
, "else {\n");
711 lf_putstr(file
, " /* cache miss */\n");
712 if (!(code
& generate_with_semantic_icache
)) {
714 lf_putstr(file
, " idecode_semantic *semantic;\n");
717 lf_putstr(file
, " instruction =\n");
718 lf_putstr(file
, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
719 lf_putstr(file
, " if (WITH_MON != 0)\n");
720 lf_putstr(file
, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
721 if ((code
& generate_with_semantic_icache
)) {
722 print_idecode_body(file
, table
, "cia =", " ");
725 print_idecode_body(file
, table
, "semantic = ", " ");
727 lf_putstr(file
, "cia = semantic(processor, cache_entry, cia));\n");
730 lf_putstr(file
, "}\n");
733 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
734 lf_putstr(file
, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
735 lf_putstr(file
, "cpu_set_program_counter(processor, cia);\n");
737 lf_putstr(file
, "}\n");
742 lf_putstr(file
, "}\n");
746 /****************************************************************/
753 lf_putstr(file
, "if (keep_running != NULL && !*keep_running)\n");
754 lf_putstr(file
, " cpu_halt(processor, nia, was_continuing, 0/*na*/);\n");
758 lf_putstr(file
, "if (WITH_EVENTS) {\n");
759 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
760 lf_putstr(file
, " cpu_set_program_counter(processor, nia);\n");
761 lf_putstr(file
, " event_queue_process(events);\n");
762 lf_putstr(file
, " nia = cpu_get_program_counter(processor);\n");
763 lf_putstr(file
, " }\n");
764 lf_putstr(file
, "}\n");
768 lf_putstr(file
, "cpu_set_program_counter(processor, nia);\n");
769 lf_putstr(file
, "if (WITH_EVENTS) {\n");
770 lf_putstr(file
, " current_cpu += 1;\n");
771 lf_putstr(file
, " if (current_cpu == nr_cpus) {\n");
772 lf_putstr(file
, " if (event_queue_tick(events)) {\n");
773 lf_putstr(file
, " event_queue_process(events);\n");
774 lf_putstr(file
, " }\n");
775 lf_putstr(file
, " current_cpu = 0;\n");
776 lf_putstr(file
, " }\n");
777 lf_putstr(file
, "}\n");
778 lf_putstr(file
, "else {\n");
779 lf_putstr(file
, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
780 lf_putstr(file
, "}\n");
781 lf_putstr(file
, "processor = processors[current_cpu];\n");
782 lf_putstr(file
, "nia = cpu_get_program_counter(processor);\n");
785 if ((code
& generate_with_icache
)) {
786 lf_putstr(file
, "cache_entry = cpu_icache_entry(processor, nia);\n");
787 lf_putstr(file
, "if (cache_entry->address == nia) {\n");
788 lf_putstr(file
, " /* cache hit */\n");
789 lf_putstr(file
, " goto *cache_entry->semantic;\n");
790 lf_putstr(file
, "}\n");
792 lf_putstr(file
, "goto cache_miss;\n");
796 if (!(code
& generate_with_icache
)) {
797 lf_printf(file
, "goto idecode;\n");
807 print_jump_insn(lf
*file
,
809 insn_bits
*expanded_bits
,
810 opcode_field
*opcodes
,
811 cache_table
*cache_rules
)
814 /* what we are for the moment */
815 lf_printf(file
, "\n");
816 print_define_my_index(file
, instruction
->file_entry
);
818 /* output the icache entry */
819 if ((code
& generate_with_icache
)) {
820 lf_printf(file
, "\n");
822 print_function_name(file
,
823 instruction
->file_entry
->fields
[insn_name
],
825 function_name_prefix_icache
);
826 lf_printf(file
, ":\n");
828 lf_printf(file
, "{\n");
830 lf_putstr(file
, "const unsigned_word cia = nia;\n");
831 print_itrace(file
, instruction
->file_entry
, 1/*putting-value-in-cache*/);
832 print_idecode_validate(file
, instruction
, opcodes
);
833 lf_printf(file
, "\n");
834 lf_printf(file
, "{\n");
836 print_icache_body(file
,
841 0/*get_value_from_cache*/,
842 1/*put_value_in_cache*/);
843 lf_printf(file
, "cache_entry->address = nia;\n");
844 lf_printf(file
, "cache_entry->semantic = &&");
845 print_function_name(file
,
846 instruction
->file_entry
->fields
[insn_name
],
848 function_name_prefix_semantics
);
849 lf_printf(file
, ";\n");
850 if ((code
& generate_with_semantic_icache
)) {
851 print_semantic_body(file
,
855 print_jump(file
, 1/*is-tail*/);
858 lf_printf(file
, "/* goto ");
859 print_function_name(file
,
860 instruction
->file_entry
->fields
[insn_name
],
862 function_name_prefix_semantics
);
863 lf_printf(file
, "; */\n");
866 lf_putstr(file
, "}\n");
868 lf_printf(file
, "}\n");
871 /* print the semantics */
872 lf_printf(file
, "\n");
874 print_function_name(file
,
875 instruction
->file_entry
->fields
[insn_name
],
877 function_name_prefix_semantics
);
878 lf_printf(file
, ":\n");
880 lf_printf(file
, "{\n");
882 lf_putstr(file
, "const unsigned_word cia = nia;\n");
883 print_icache_body(file
,
887 (code
& generate_with_direct_access_icache
),
888 (code
& generate_with_icache
)/*get_value_from_cache*/,
889 0/*put_value_in_cache*/);
890 print_semantic_body(file
,
894 print_jump(file
, 1/*is tail*/);
896 lf_printf(file
, "}\n");
900 print_jump_definition(insn_table
*entry
,
906 cache_table
*cache_rules
= (cache_table
*)data
;
907 if (generate_expanded_instructions
) {
908 ASSERT(entry
->nr_insn
== 1
909 && entry
->opcode
== NULL
910 && entry
->parent
!= NULL
911 && entry
->parent
->opcode
!= NULL
);
912 ASSERT(entry
->nr_insn
== 1
913 && entry
->opcode
== NULL
914 && entry
->parent
!= NULL
915 && entry
->parent
->opcode
!= NULL
916 && entry
->parent
->opcode_rule
!= NULL
);
917 print_jump_insn(file
,
919 entry
->expanded_bits
,
924 print_jump_insn(file
,
934 print_jump_internal_function(insn_table
*table
,
937 table_entry
*function
)
939 if (it_is("internal", function
->fields
[insn_flags
])) {
940 lf_printf(file
, "\n");
941 table_entry_print_cpp_line_nr(file
, function
);
943 print_function_name(file
,
944 function
->fields
[insn_name
],
946 ((code
& generate_with_icache
)
947 ? function_name_prefix_icache
948 : function_name_prefix_semantics
));
949 lf_printf(file
, ":\n");
951 lf_printf(file
, "{\n");
953 lf_printf(file
, "const unsigned_word cia = nia;\n");
954 lf_print__c_code(file
, function
->annex
);
955 lf_print__internal_reference(file
);
956 lf_printf(file
, "error(\"Internal function must longjump\\n\");\n");
958 lf_printf(file
, "}\n");
963 print_jump_until_stop_body(lf
*file
,
965 cache_table
*cache_rules
,
968 lf_printf(file
, "{\n");
971 lf_printf(file
, "int *keep_running = NULL;\n");
972 lf_putstr(file
, "jmp_buf halt;\n");
973 lf_putstr(file
, "jmp_buf restart;\n");
974 lf_putstr(file
, "cpu *processor = NULL;\n");
975 lf_putstr(file
, "unsigned_word nia = -1;\n");
976 lf_putstr(file
, "instruction_word instruction = 0;\n");
977 if ((code
& generate_with_icache
)) {
978 lf_putstr(file
, "idecode_cache *cache_entry = NULL;\n");
981 lf_putstr(file
, "int current_cpu = -1;\n");
984 /* all the switches and tables - they know about jumping */
985 print_idecode_lookups(file
, table
, cache_rules
);
987 /* start the simulation up */
988 if ((code
& generate_with_icache
)) {
989 lf_putstr(file
, "\n");
990 lf_putstr(file
, "{\n");
991 lf_putstr(file
, " int cpu_nr;\n");
992 lf_putstr(file
, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
993 lf_putstr(file
, " cpu_flush_icache(processors[cpu_nr]);\n");
994 lf_putstr(file
, "}\n");
997 lf_putstr(file
, "\n");
998 lf_putstr(file
, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1000 lf_putstr(file
, "\n");
1001 lf_putstr(file
, "if (setjmp(halt))\n");
1002 lf_putstr(file
, " return;\n");
1004 lf_putstr(file
, "\n");
1005 lf_putstr(file
, "setjmp(restart);\n");
1007 lf_putstr(file
, "\n");
1008 if (!generate_smp
) {
1009 lf_putstr(file
, "processor = processors[0];\n");
1010 lf_putstr(file
, "nia = cpu_get_program_counter(processor);\n");
1013 lf_putstr(file
, "current_cpu = psim_last_cpu(system);\n");
1016 if (!(code
& generate_with_icache
)) {
1017 lf_printf(file
, "\n");
1018 lf_indent(file
, -1);
1019 lf_printf(file
, "idecode:\n");
1020 lf_indent(file
, +1);
1023 print_jump(file
, 0/*is_tail*/);
1025 if ((code
& generate_with_icache
)) {
1026 lf_indent(file
, -1);
1027 lf_printf(file
, "cache_miss:\n");
1028 lf_indent(file
, +1);
1031 lf_putstr(file
, "instruction\n");
1032 lf_putstr(file
, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
1033 lf_putstr(file
, " processor, nia);\n");
1034 print_idecode_body(file
, table
, "/*IGORE*/", "");
1036 /* print out a table of all the internals functions */
1037 insn_table_traverse_function(table
,
1039 print_jump_internal_function
);
1041 /* print out a table of all the instructions */
1042 if (generate_expanded_instructions
)
1043 insn_table_traverse_tree(table
,
1047 print_jump_definition
, /* leaf */
1049 NULL
); /* padding */
1051 insn_table_traverse_insn(table
,
1053 print_jump_definition
);
1054 lf_indent(file
, -2);
1055 lf_printf(file
, "}\n");
1059 /****************************************************************/
1064 print_idecode_floating_point_unavailable(lf
*file
)
1066 if ((code
& generate_jumps
))
1067 lf_printf(file
, "goto %s_floating_point_unavailable;\n", (code
& generate_with_icache
) ? "icache" : "semantic");
1068 else if ((code
& generate_with_icache
))
1069 lf_printf(file
, "return icache_floating_point_unavailable(%s);\n",
1070 ICACHE_FUNCTION_ACTUAL
);
1072 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
1073 SEMANTIC_FUNCTION_ACTUAL
);
1077 /* Output code to do any final checks on the decoded instruction.
1078 This includes things like verifying any on decoded fields have the
1079 correct value and checking that (for floating point) floating point
1080 hardware isn't disabled */
1083 print_idecode_validate(lf
*file
,
1085 opcode_field
*opcodes
)
1087 /* Validate: unchecked instruction fields
1089 If any constant fields in the instruction were not checked by the
1090 idecode tables, output code to check that they have the correct
1093 unsigned check_mask
= 0;
1094 unsigned check_val
= 0;
1096 opcode_field
*opcode
;
1098 /* form check_mask/check_val containing what needs to be checked
1099 in the instruction */
1100 for (field
= instruction
->fields
->first
;
1101 field
->first
< insn_bit_size
;
1102 field
= field
->next
) {
1104 check_mask
<<= field
->width
;
1105 check_val
<<= field
->width
;
1107 /* is it a constant that could need validating? */
1108 if (!field
->is_int
&& !field
->is_slash
)
1111 /* has it been checked by a table? */
1112 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1113 if (field
->first
>= opcode
->first
1114 && field
->last
<= opcode
->last
)
1120 check_mask
|= (1 << field
->width
)-1;
1121 check_val
|= field
->val_int
;
1124 /* if any bits not checked by opcode tables, output code to check them */
1126 lf_printf(file
, "\n");
1127 lf_printf(file
, "/* validate: %s */\n",
1128 instruction
->file_entry
->fields
[insn_format
]);
1129 lf_printf(file
, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
1130 check_mask
, check_val
);
1131 lf_indent(file
, +2);
1132 print_idecode_illegal(file
, "return");
1133 lf_indent(file
, -2);
1137 /* Validate floating point hardware
1139 If the simulator is being built with out floating point hardware
1140 (different to it being disabled in the MSR) then floating point
1141 instructions are invalid */
1143 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1144 lf_printf(file
, "\n");
1145 lf_printf(file
, "/* Validate: FP hardware exists */\n");
1146 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1147 lf_indent(file
, +2);
1148 print_idecode_illegal(file
, "return");
1149 lf_indent(file
, -2);
1153 /* Validate: Floating Point available
1155 If floating point is not available, we enter a floating point
1156 unavailable interrupt into the cache instead of the instruction
1159 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1160 ever a CSI occures we flush the instruction cache. */
1163 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1164 lf_printf(file
, "\n");
1165 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
1166 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
1167 lf_indent(file
, +2);
1168 print_idecode_floating_point_unavailable(file
);
1169 lf_indent(file
, -2);
1175 /****************************************************************/
1179 print_idecode_run_function_header(lf
*file
,
1184 lf_printf(file
, "\n");
1185 lf_print_function_type(file
, "void", "INLINE_IDECODE", (is_definition
? " " : "\n"));
1186 indent
= lf_putstr(file
, (can_stop
? "idecode_run_until_stop" : "idecode_run"));
1188 lf_putstr(file
, "\n");
1190 lf_indent(file
, +indent
);
1191 lf_putstr(file
, "(psim *system,\n");
1193 lf_putstr(file
, " volatile int *keep_running,\n");
1194 lf_printf(file
, " event_queue *events,\n");
1195 lf_putstr(file
, " cpu *const processors[],\n");
1196 lf_putstr(file
, " const int nr_cpus)");
1198 lf_putstr(file
, ";");
1200 lf_indent(file
, -indent
);
1201 lf_putstr(file
, "\n");
1206 gen_idecode_h(lf
*file
,
1208 cache_table
*cache_rules
)
1210 lf_printf(file
, "/* The idecode_*.h functions shall move to support */\n");
1211 lf_printf(file
, "#include \"idecode_expression.h\"\n");
1212 lf_printf(file
, "#include \"idecode_fields.h\"\n");
1213 lf_printf(file
, "#include \"idecode_branch.h\"\n");
1214 lf_printf(file
, "\n");
1215 print_icache_struct(table
, cache_rules
, file
);
1216 lf_printf(file
, "\n");
1217 lf_printf(file
, "#define WITH_IDECODE_SMP %d\n", generate_smp
);
1218 lf_printf(file
, "\n");
1219 print_idecode_run_function_header(file
, 0/*can stop*/, 1/*is definition*/);
1220 print_idecode_run_function_header(file
, 1/*can stop*/, 1/*is definition*/);
1225 gen_idecode_c(lf
*file
,
1227 cache_table
*cache_rules
)
1230 lf_printf(file
, "#include \"inline.c\"\n");
1231 lf_printf(file
, "\n");
1232 lf_printf(file
, "#include \"cpu.h\"\n");
1233 lf_printf(file
, "#include \"idecode.h\"\n");
1234 lf_printf(file
, "#include \"semantics.h\"\n");
1235 lf_printf(file
, "#include \"icache.h\"\n");
1236 lf_printf(file
, "#include \"support.h\"\n");
1237 lf_printf(file
, "\n");
1238 lf_printf(file
, "#include <setjmp.h>\n");
1239 lf_printf(file
, "\n");
1240 lf_printf(file
, "/* encodings for a negative shift field */\n");
1241 lf_printf(file
, "enum {\n");
1242 lf_printf(file
, " table_boolean_entry = -2,\n");
1243 lf_printf(file
, " table_function_entry = -1,\n");
1244 lf_printf(file
, "};\n");
1245 lf_printf(file
, "\n");
1246 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
1247 lf_printf(file
, " signed short shift; /* shift >= 0: t[(i & mask) >> shift] */\n");
1248 lf_printf(file
, " unsigned char left; /* shift == -2: */\n");
1249 lf_printf(file
, " unsigned char right; /* t[((i << left) >> right) != mask] */\n");
1250 lf_printf(file
, " unsigned mask; /* else (shift == -1): function() */\n");
1251 lf_printf(file
, " void *function_or_table;\n");
1252 lf_printf(file
, "} idecode_table_entry;\n");
1253 lf_printf(file
, "\n");
1254 lf_printf(file
, "\n");
1256 if ((code
& generate_calls
)) {
1258 print_idecode_lookups(file
, table
, cache_rules
);
1260 /* output the main idecode routine */
1261 print_idecode_run_function_header(file
, 0/*can stop*/, 0/*is definition*/);
1262 print_run_until_stop_body(file
, table
, 0/* have stop argument */);
1264 print_idecode_run_function_header(file
, 1/*can stop*/, 0/*is definition*/);
1265 print_run_until_stop_body(file
, table
, 1/* no stop argument */);
1268 else if ((code
& generate_jumps
)) {
1270 print_idecode_run_function_header(file
, 0/*can stop*/, 0/*is definition*/);
1271 print_jump_until_stop_body(file
, table
, cache_rules
, 0 /* have stop argument */);
1273 print_idecode_run_function_header(file
, 1/*can stop*/, 0/*is definition*/);
1274 print_jump_until_stop_body(file
, table
, cache_rules
, 1/* have stop argument */);
1278 error("Something is wrong!\n");