Update objcopy's --section-alignment option so that it sets the alignment flag on...
[binutils-gdb.git] / sim / ppc / gen-idecode.c
blobbbb1cc980bc5fdea66b06d49943734f98fbbc757
1 /* This file is part of the program psim.
3 Copyright 1994, 1995, 1996, 1997, 2003 Andrew Cagney
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "misc.h"
21 #include "lf.h"
22 #include "lf-ppc.h"
23 #include "table.h"
25 #include "filter.h"
26 #include "filter-ppc.h"
28 #include "ld-decode.h"
29 #include "ld-cache.h"
30 #include "ld-insn.h"
32 #include "igen.h"
34 #include "gen-idecode.h"
35 #include "gen-icache.h"
36 #include "gen-semantics.h"
40 static void
41 lf_print_opcodes(lf *file,
42 insn_table *table)
44 if (table != NULL) {
45 while (1) {
46 ASSERT(table->opcode != NULL);
47 lf_printf(file, "_%d_%d",
48 table->opcode->first,
49 table->opcode->last);
50 if (table->parent == NULL) break;
51 lf_printf(file, "__%d", table->opcode_nr);
52 table = table->parent;
57 /****************************************************************/
60 static void
61 lf_print_table_name(lf *file,
62 insn_table *table)
64 lf_printf(file, "idecode_table");
65 lf_print_opcodes(file, table);
70 static void
71 print_idecode_table(lf *file,
72 insn_table *entry,
73 const char *result)
75 lf_printf(file, "/* prime the search */\n");
76 lf_printf(file, "idecode_table_entry *table = ");
77 lf_print_table_name(file, entry);
78 lf_printf(file, ";\n");
79 lf_printf(file, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
80 i2target(hi_bit_nr, entry->opcode->first),
81 i2target(hi_bit_nr, entry->opcode->last));
82 lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
84 lf_printf(file, "\n");
85 lf_printf(file, "/* iterate until a leaf */\n");
86 lf_printf(file, "while (1) {\n");
87 lf_printf(file, " signed shift = table_entry->shift;\n");
88 lf_printf(file, "if (shift == function_entry) break;\n");
89 lf_printf(file, " if (shift >= 0) {\n");
90 lf_printf(file, " table = ((idecode_table_entry*)\n");
91 lf_printf(file, " table_entry->function_or_table);\n");
92 lf_printf(file, " opcode = ((instruction & table_entry->mask)\n");
93 lf_printf(file, " >> shift);\n");
94 lf_printf(file, " table_entry = table + opcode;\n");
95 lf_printf(file, " }\n");
96 lf_printf(file, " else {\n");
97 lf_printf(file, " /* must be a boolean */\n");
98 lf_printf(file, " ASSERT(table_entry->shift == boolean_entry);\n");
99 lf_printf(file, " opcode = ((instruction & table_entry->mask)\n");
100 lf_printf(file, " != table_entry->value);\n");
101 lf_printf(file, " table = ((idecode_table_entry*)\n");
102 lf_printf(file, " table_entry->function_or_table);\n");
103 lf_printf(file, " table_entry = table + opcode;\n");
104 lf_printf(file, " }\n");
105 lf_printf(file, "}\n");
107 lf_printf(file, "\n");
108 lf_printf(file, "/* call the leaf code */\n");
109 if ((code & generate_jumps)) {
110 lf_printf(file, "goto *table_entry->function_or_table;\n");
112 else {
113 lf_printf(file, "%s ", result);
114 if ((code & generate_with_icache)) {
115 lf_printf(file, "(((idecode_icache*)table_entry->function_or_table)\n");
116 lf_printf(file, " (%s));\n", ICACHE_FUNCTION_ACTUAL);
118 else {
119 lf_printf(file, "((idecode_semantic*)table_entry->function_or_table)\n");
120 lf_printf(file, " (%s);\n", SEMANTIC_FUNCTION_ACTUAL);
126 static void
127 print_idecode_table_start(insn_table *table,
128 lf *file,
129 void *data,
130 int depth)
132 ASSERT(depth == 0);
133 /* start of the table */
134 if (table->opcode_rule->gen == array_gen) {
135 lf_printf(file, "\n");
136 lf_printf(file, "static idecode_table_entry ");
137 lf_print_table_name(file, table);
138 lf_printf(file, "[] = {\n");
142 static void
143 print_idecode_table_leaf(insn_table *entry,
144 lf *file,
145 void *data,
146 insn *instruction,
147 int depth)
149 ASSERT(entry->parent != NULL);
150 ASSERT(depth == 0);
152 /* add an entry to the table */
153 if (entry->parent->opcode_rule->gen == array_gen) {
154 lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
155 if (entry->opcode == NULL) {
156 /* table leaf entry */
157 lf_printf(file, "function_entry, 0, 0, ");
158 if ((code & generate_jumps))
159 lf_printf(file, "&&");
160 print_function_name(file,
161 entry->insns->file_entry->fields[insn_name],
162 entry->expanded_bits,
163 ((code & generate_with_icache)
164 ? function_name_prefix_icache
165 : function_name_prefix_semantics));
167 else if (entry->opcode_rule->gen == switch_gen
168 || entry->opcode_rule->gen == goto_switch_gen
169 || entry->opcode_rule->gen == padded_switch_gen) {
170 /* table calling switch statement */
171 lf_printf(file, "function_entry, 0, 0, ");
172 if ((code & generate_jumps))
173 lf_printf(file, "&&");
174 lf_print_table_name(file, entry);
176 else if (entry->opcode->is_boolean) {
177 /* table `calling' boolean table */
178 lf_printf(file, "boolean_entry, ");
179 lf_printf(file, "MASK32(%d, %d), ",
180 i2target(hi_bit_nr, entry->opcode->first),
181 i2target(hi_bit_nr, entry->opcode->last));
182 lf_printf(file, "INSERTED32(%d, %d, %d), ",
183 entry->opcode->boolean_constant,
184 i2target(hi_bit_nr, entry->opcode->first),
185 i2target(hi_bit_nr, entry->opcode->last));
186 lf_print_table_name(file, entry);
188 else {
189 /* table `calling' another table */
190 lf_printf(file, "%d, ", insn_bit_size - entry->opcode->last - 1);
191 lf_printf(file, "MASK32(%d,%d), ",
192 i2target(hi_bit_nr, entry->opcode->first),
193 i2target(hi_bit_nr, entry->opcode->last));
194 lf_printf(file, "0, ");
195 lf_print_table_name(file, entry);
197 lf_printf(file, " },\n");
201 static void
202 print_idecode_table_end(insn_table *table,
203 lf *file,
204 void *data,
205 int depth)
207 ASSERT(depth == 0);
208 if (table->opcode_rule->gen == array_gen) {
209 lf_printf(file, "};\n");
213 static void
214 print_idecode_table_padding(insn_table *table,
215 lf *file,
216 void *data,
217 int depth,
218 int opcode_nr)
220 ASSERT(depth == 0);
221 if (table->opcode_rule->gen == array_gen) {
222 lf_printf(file, " /*%d*/ { function_entry, 0, 0, ", opcode_nr);
223 if ((code & generate_jumps))
224 lf_printf(file, "&&");
225 lf_printf(file, "%s_illegal },\n",
226 ((code & generate_with_icache) ? "icache" : "semantic"));
231 /****************************************************************/
234 static void
235 print_goto_switch_name(lf *file,
236 insn_table *entry)
238 lf_printf(file, "case_");
239 if (entry->opcode == NULL)
240 print_function_name(file,
241 entry->insns->file_entry->fields[insn_name],
242 entry->expanded_bits,
243 ((code & generate_with_icache)
244 ? function_name_prefix_icache
245 : function_name_prefix_semantics));
246 else
247 lf_print_table_name(file, entry);
250 static void
251 print_goto_switch_table_leaf(insn_table *entry,
252 lf *file,
253 void *data,
254 insn *instruction,
255 int depth)
257 ASSERT(entry->parent != NULL);
258 ASSERT(depth == 0);
259 ASSERT(entry->parent->opcode_rule->gen == goto_switch_gen);
260 ASSERT(entry->parent->opcode);
262 lf_printf(file, "&&");
263 print_goto_switch_name(file, entry);
264 lf_printf(file, ",\n");
267 static void
268 print_goto_switch_table_padding(insn_table *table,
269 lf *file,
270 void *data,
271 int depth,
272 int opcode_nr)
274 ASSERT(depth == 0);
275 ASSERT(table->opcode_rule->gen == goto_switch_gen);
277 lf_printf(file, "&&illegal_");
278 lf_print_table_name(file, table);
279 lf_printf(file, ",\n");
282 static void
283 print_goto_switch_break(lf *file,
284 insn_table *entry)
286 lf_printf(file, "goto break_");
287 lf_print_table_name(file, entry->parent);
288 lf_printf(file, ";\n");
292 static void
293 print_goto_switch_table(lf *file,
294 insn_table *table)
296 lf_printf(file, "const static void *");
297 lf_print_table_name(file, table);
298 lf_printf(file, "[] = {\n");
299 lf_indent(file, +2);
300 insn_table_traverse_tree(table,
301 file, NULL/*data*/,
303 NULL/*start*/,
304 print_goto_switch_table_leaf,
305 NULL/*end*/,
306 print_goto_switch_table_padding);
307 lf_indent(file, -2);
308 lf_printf(file, "};\n");
312 void print_idecode_switch
313 (lf *file,
314 insn_table *table,
315 const char *result);
317 static void
318 idecode_switch_start(insn_table *table,
319 lf *file,
320 void *data,
321 int depth)
323 /* const char *result = data; */
324 ASSERT(depth == 0);
325 ASSERT(table->opcode_rule->gen == switch_gen
326 || table->opcode_rule->gen == goto_switch_gen
327 || table->opcode_rule->gen == padded_switch_gen);
329 if (table->opcode->is_boolean
330 || table->opcode_rule->gen == switch_gen
331 || table->opcode_rule->gen == padded_switch_gen) {
332 lf_printf(file, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
333 i2target(hi_bit_nr, table->opcode->first),
334 i2target(hi_bit_nr, table->opcode->last));
336 else if (table->opcode_rule->gen == goto_switch_gen) {
337 if (table->parent != NULL
338 && (table->parent->opcode_rule->gen == switch_gen
339 || table->parent->opcode_rule->gen == goto_switch_gen
340 || table->parent->opcode_rule->gen == padded_switch_gen)) {
341 lf_printf(file, "{\n");
342 lf_indent(file, +2);
344 print_goto_switch_table(file, table);
345 lf_printf(file, "ASSERT(EXTRACTED32(instruction, %d, %d)\n",
346 i2target(hi_bit_nr, table->opcode->first),
347 i2target(hi_bit_nr, table->opcode->last));
348 lf_printf(file, " < (sizeof(");
349 lf_print_table_name(file, table);
350 lf_printf(file, ") / sizeof(void*)));\n");
351 lf_printf(file, "goto *");
352 lf_print_table_name(file, table);
353 lf_printf(file, "[EXTRACTED32(instruction, %d, %d)];\n",
354 i2target(hi_bit_nr, table->opcode->first),
355 i2target(hi_bit_nr, table->opcode->last));
357 else {
358 ASSERT("bad switch" == NULL);
363 static void
364 idecode_switch_leaf(insn_table *entry,
365 lf *file,
366 void *data,
367 insn *instruction,
368 int depth)
370 const char *result = data;
371 ASSERT(entry->parent != NULL);
372 ASSERT(depth == 0);
373 ASSERT(entry->parent->opcode_rule->gen == switch_gen
374 || entry->parent->opcode_rule->gen == goto_switch_gen
375 || entry->parent->opcode_rule->gen == padded_switch_gen);
376 ASSERT(entry->parent->opcode);
378 if (entry->parent->opcode->is_boolean
379 && entry->opcode_nr == 0) {
380 /* boolean false target */
381 lf_printf(file, "case %d:\n", entry->parent->opcode->boolean_constant);
383 else if (entry->parent->opcode->is_boolean
384 && entry->opcode_nr != 0) {
385 /* boolean true case */
386 lf_printf(file, "default:\n");
388 else if (entry->parent->opcode_rule->gen == switch_gen
389 || entry->parent->opcode_rule->gen == padded_switch_gen) {
390 /* normal goto */
391 lf_printf(file, "case %d:\n", entry->opcode_nr);
393 else if (entry->parent->opcode_rule->gen == goto_switch_gen) {
394 /* lf_indent(file, -1); */
395 print_goto_switch_name(file, entry);
396 lf_printf(file, ":\n");
397 /* lf_indent(file, +1); */
399 else {
400 ASSERT("bad switch" == NULL);
402 lf_indent(file, +2);
404 if (entry->opcode == NULL) {
405 /* switch calling leaf */
406 if ((code & generate_jumps))
407 lf_printf(file, "goto ");
408 if ((code & generate_calls))
409 lf_printf(file, "%s ", result);
410 print_function_name(file,
411 entry->insns->file_entry->fields[insn_name],
412 entry->expanded_bits,
413 ((code & generate_with_icache)
414 ? function_name_prefix_icache
415 : function_name_prefix_semantics));
416 if ((code & generate_calls))
417 lf_printf(file, "(%s)", SEMANTIC_FUNCTION_ACTUAL);
418 lf_printf(file, ";\n");
420 else if (entry->opcode_rule->gen == switch_gen
421 || entry->opcode_rule->gen == goto_switch_gen
422 || entry->opcode_rule->gen == padded_switch_gen) {
423 /* switch calling switch */
424 print_idecode_switch(file, entry, result);
426 else {
427 /* switch looking up a table */
428 lf_printf(file, "{\n");
429 lf_indent(file, -2);
430 print_idecode_table(file, entry, result);
431 lf_indent(file, -2);
432 lf_printf(file, "}\n");
434 if (entry->parent->opcode->is_boolean
435 || entry->parent->opcode_rule->gen == switch_gen
436 || entry->parent->opcode_rule->gen == padded_switch_gen) {
437 lf_printf(file, "break;\n");
439 else if (entry->parent->opcode_rule->gen == goto_switch_gen) {
440 print_goto_switch_break(file, entry);
442 else {
443 ASSERT("bad switch" == NULL);
446 lf_indent(file, -2);
450 static void
451 print_idecode_switch_illegal(lf *file,
452 const char *result)
454 lf_indent(file, +2);
455 print_idecode_illegal(file, result);
456 lf_printf(file, "break;\n");
457 lf_indent(file, -2);
460 static void
461 idecode_switch_end(insn_table *table,
462 lf *file,
463 void *data,
464 int depth)
466 const char *result = data;
467 ASSERT(depth == 0);
468 ASSERT(table->opcode_rule->gen == switch_gen
469 || table->opcode_rule->gen == goto_switch_gen
470 || table->opcode_rule->gen == padded_switch_gen);
471 ASSERT(table->opcode);
473 if (table->opcode->is_boolean) {
474 lf_printf(file, "}\n");
476 else if (table->opcode_rule->gen == switch_gen
477 || table->opcode_rule->gen == padded_switch_gen) {
478 lf_printf(file, "default:\n");
479 switch (table->opcode_rule->gen) {
480 case switch_gen:
481 print_idecode_switch_illegal(file, result);
482 break;
483 case padded_switch_gen:
484 lf_printf(file, " error(\"Internal error - bad switch generated\\n\");\n");
485 lf_printf(file, " break;\n");
486 break;
487 default:
488 ASSERT("bad switch" == NULL);
490 lf_printf(file, "}\n");
492 else if (table->opcode_rule->gen == goto_switch_gen) {
493 lf_printf(file, "illegal_");
494 lf_print_table_name(file, table);
495 lf_printf(file, ":\n");
496 print_idecode_illegal(file, result);
497 lf_printf(file, "break_");
498 lf_print_table_name(file, table);
499 lf_printf(file, ":;\n");
500 if (table->parent != NULL
501 && (table->parent->opcode_rule->gen == switch_gen
502 || table->parent->opcode_rule->gen == goto_switch_gen
503 || table->parent->opcode_rule->gen == padded_switch_gen)) {
504 lf_indent(file, -2);
505 lf_printf(file, "}\n");
508 else {
509 ASSERT("bad switch" == NULL);
513 static void
514 idecode_switch_padding(insn_table *table,
515 lf *file,
516 void *data,
517 int depth,
518 int opcode_nr)
520 const char *result = data;
521 ASSERT(depth == 0);
522 ASSERT(table->opcode_rule->gen == switch_gen
523 || table->opcode_rule->gen == goto_switch_gen
524 || table->opcode_rule->gen == padded_switch_gen);
526 switch (table->opcode_rule->gen) {
527 case switch_gen:
528 break;
529 case padded_switch_gen:
530 lf_printf(file, "case %d:\n", opcode_nr);
531 print_idecode_switch_illegal(file, result);
532 break;
533 case goto_switch_gen:
534 /* no padding needed */
535 break;
536 default:
537 ASSERT("bad switch" != NULL);
542 void
543 print_idecode_switch(lf *file,
544 insn_table *table,
545 const char *result)
547 insn_table_traverse_tree(table,
548 file, (void*)result,
550 idecode_switch_start,
551 idecode_switch_leaf,
552 idecode_switch_end,
553 idecode_switch_padding);
557 static void
558 print_idecode_switch_function_header(lf *file,
559 insn_table *table,
560 int is_function_definition)
562 lf_printf(file, "\n");
563 if ((code & generate_calls)) {
564 lf_printf(file, "static ");
565 if ((code & generate_with_icache))
566 lf_printf(file, "idecode_semantic *");
567 else
568 lf_printf(file, "unsigned_word");
569 if (is_function_definition)
570 lf_printf(file, "\n");
571 else
572 lf_printf(file, " ");
573 lf_print_table_name(file, table);
574 lf_printf(file, "\n(%s)", ICACHE_FUNCTION_FORMAL);
575 if (!is_function_definition)
576 lf_printf(file, ";");
577 lf_printf(file, "\n");
579 if ((code & generate_jumps) && is_function_definition) {
580 lf_indent(file, -1);
581 lf_print_table_name(file, table);
582 lf_printf(file, ":\n");
583 lf_indent(file, +1);
588 static void
589 idecode_declare_if_switch(insn_table *table,
590 lf *file,
591 void *data,
592 int depth)
594 if ((table->opcode_rule->gen == switch_gen
595 || table->opcode_rule->gen == goto_switch_gen
596 || table->opcode_rule->gen == padded_switch_gen)
597 && table->parent != NULL /* don't declare the top one yet */
598 && table->parent->opcode_rule->gen == array_gen) {
599 print_idecode_switch_function_header(file,
600 table,
601 0/*isnt function definition*/);
606 static void
607 idecode_expand_if_switch(insn_table *table,
608 lf *file,
609 void *data,
610 int depth)
612 if ((table->opcode_rule->gen == switch_gen
613 || table->opcode_rule->gen == goto_switch_gen
614 || table->opcode_rule->gen == padded_switch_gen)
615 && table->parent != NULL /* don't expand the top one yet */
616 && table->parent->opcode_rule->gen == array_gen) {
617 print_idecode_switch_function_header(file,
618 table,
619 1/*is function definition*/);
620 if ((code & generate_calls)) {
621 lf_printf(file, "{\n");
622 lf_indent(file, +2);
624 print_idecode_switch(file, table, "return");
625 if ((code & generate_calls)) {
626 lf_indent(file, -2);
627 lf_printf(file, "}\n");
633 /****************************************************************/
636 static void
637 print_idecode_lookups(lf *file,
638 insn_table *table,
639 cache_table *cache_rules)
641 int depth;
643 /* output switch function declarations where needed by tables */
644 insn_table_traverse_tree(table,
645 file, NULL,
647 idecode_declare_if_switch, /* START */
648 NULL, NULL, NULL);
650 /* output tables where needed */
651 for (depth = insn_table_depth(table);
652 depth > 0;
653 depth--) {
654 insn_table_traverse_tree(table,
655 file, NULL,
656 1-depth,
657 print_idecode_table_start,
658 print_idecode_table_leaf,
659 print_idecode_table_end,
660 print_idecode_table_padding);
663 /* output switch functions where needed */
664 insn_table_traverse_tree(table,
665 file, NULL,
667 idecode_expand_if_switch, /* START */
668 NULL, NULL, NULL);
672 static void
673 print_idecode_body(lf *file,
674 insn_table *table,
675 const char *result)
677 if (table->opcode_rule->gen == switch_gen
678 || table->opcode_rule->gen == goto_switch_gen
679 || table->opcode_rule->gen == padded_switch_gen)
680 print_idecode_switch(file, table, result);
681 else
682 print_idecode_table(file, table, result);
686 /****************************************************************/
689 static void
690 print_run_until_stop_body(lf *file,
691 insn_table *table,
692 int can_stop)
694 /* Output the function to execute real code:
696 Unfortunatly, there are multiple cases to consider vis:
698 <icache> X <smp> X <events> X <keep-running-flag> X ...
700 Consequently this function is written in multiple different ways */
702 lf_putstr(file, "{\n");
703 lf_indent(file, +2);
704 lf_putstr(file, "jmp_buf halt;\n");
705 lf_putstr(file, "jmp_buf restart;\n");
706 if (!generate_smp) {
707 lf_putstr(file, "cpu *processor = NULL;\n");
708 lf_putstr(file, "unsigned_word cia = -1;\n");
710 lf_putstr(file, "int last_cpu;\n");
711 if (generate_smp) {
712 lf_putstr(file, "int current_cpu;\n");
715 if ((code & generate_with_icache)) {
716 lf_putstr(file, "int cpu_nr;\n");
717 lf_putstr(file, "\n");
718 lf_putstr(file, "/* flush the icache of a possible break insn */\n");
719 lf_putstr(file, "for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
720 lf_putstr(file, " cpu_flush_icache(processors[cpu_nr]);\n");
723 lf_putstr(file, "\n");
724 lf_putstr(file, "/* set the halt target initially */\n");
725 lf_putstr(file, "psim_set_halt_and_restart(system, &halt, NULL);\n");
726 lf_putstr(file, "if (setjmp(halt))\n");
727 lf_putstr(file, " return;\n");
729 lf_putstr(file, "\n");
730 lf_putstr(file, "/* where were we before the halt? */\n");
731 lf_putstr(file, "last_cpu = psim_last_cpu(system);\n");
733 lf_putstr(file, "\n");
734 lf_putstr(file, "/* check for need to force event processing first */\n");
735 lf_putstr(file, "if (WITH_EVENTS) {\n");
736 lf_putstr(file, " if (last_cpu == nr_cpus) {\n");
737 lf_putstr(file, " /* halted during event processing */\n");
738 lf_putstr(file, " event_queue_process(events);\n");
739 lf_putstr(file, " last_cpu = -1;\n");
740 lf_putstr(file, " }\n");
741 lf_putstr(file, " else if (last_cpu == nr_cpus - 1) {\n");
742 lf_putstr(file, " /* last cpu did halt */\n");
743 lf_putstr(file, " if (event_queue_tick(events)) {\n");
744 lf_putstr(file, " event_queue_process(events);\n");
745 lf_putstr(file, " }\n");
746 lf_putstr(file, " last_cpu = -1;\n");
747 lf_putstr(file, " }\n");
748 lf_putstr(file, "}\n");
749 lf_putstr(file, "else {\n");
750 lf_putstr(file, " if (last_cpu == nr_cpus - 1)\n");
751 lf_putstr(file, " /* cpu zero is next */\n");
752 lf_putstr(file, " last_cpu = -1;\n");
753 lf_putstr(file, "}\n");
755 lf_putstr(file, "\n");
756 lf_putstr(file, "/* have ensured that the event queue can not be first */\n");
757 lf_putstr(file, "ASSERT(last_cpu >= -1 && last_cpu < nr_cpus - 1);\n");
759 if (!generate_smp) {
761 lf_putstr(file, "\n\
762 /* CASE 1: NO SMP (with or with out instruction cache).\n\
764 In this case, we can take advantage of the fact that the current\n\
765 instruction address does not need to be returned to the cpu object\n\
766 after every execution of an instruction. Instead it only needs to\n\
767 be saved when either A. the main loop exits or B. A cpu-halt or\n\
768 cpu-restart call forces the loop to be re-enered. The later\n\
769 functions always save the current cpu instruction address.\n\
771 Two subcases also exist that with and that without an instruction\n\
772 cache.\n\
774 An additional complexity is the need to ensure that a 1:1 ratio\n\
775 is maintained between the execution of an instruction and the\n\
776 incrementing of the simulation clock */");
778 lf_putstr(file, "\n");
780 lf_putstr(file, "\n");
781 lf_putstr(file, "/* now add restart target as ready to run */\n");
782 lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
783 lf_putstr(file, "if (setjmp(restart)) {\n");
784 lf_putstr(file, " if (WITH_EVENTS) {\n");
785 lf_putstr(file, " /* when restart, cpu must have been last, clock next */\n");
786 lf_putstr(file, " if (event_queue_tick(events)) {\n");
787 lf_putstr(file, " event_queue_process(events);\n");
788 lf_putstr(file, " }\n");
789 lf_putstr(file, " }\n");
790 lf_putstr(file, "}\n");
792 lf_putstr(file, "\n");
793 lf_putstr(file, "/* prime the main loop */\n");
794 lf_putstr(file, "processor = processors[0];\n");
795 lf_putstr(file, "cia = cpu_get_program_counter(processor);\n");
797 lf_putstr(file, "\n");
798 lf_putstr(file, "while (1) {\n");
799 lf_indent(file, +2);
801 if (!(code & generate_with_icache)) {
802 lf_putstr(file, "instruction_word instruction =\n");
803 lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
804 lf_putstr(file, "\n");
805 print_idecode_body(file, table, "cia =");;
808 if ((code & generate_with_icache)) {
809 lf_putstr(file, "idecode_cache *cache_entry =\n");
810 lf_putstr(file, " cpu_icache_entry(processor, cia);\n");
811 lf_putstr(file, "if (cache_entry->address == cia) {\n");
812 lf_putstr(file, " /* cache hit */\n");
813 lf_putstr(file, " idecode_semantic *const semantic = cache_entry->semantic;\n");
814 lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n");
815 /* tail */
816 if (can_stop) {
817 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
818 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
820 lf_putstr(file, "}\n");
821 lf_putstr(file, "else {\n");
822 lf_putstr(file, " /* cache miss */\n");
823 if (!(code & generate_with_semantic_icache)) {
824 lf_indent(file, +2);
825 lf_putstr(file, "idecode_semantic *semantic;\n");
826 lf_indent(file, -2);
828 lf_putstr(file, " instruction_word instruction =\n");
829 lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
830 lf_putstr(file, " if (WITH_MON != 0)\n");
831 lf_putstr(file, " mon_event(mon_event_icache_miss, processor, cia);\n");
832 if ((code & generate_with_semantic_icache)) {
833 lf_putstr(file, "{\n");
834 lf_indent(file, +2);
835 print_idecode_body(file, table, "cia =");
836 lf_indent(file, -2);
837 lf_putstr(file, "}\n");
839 else {
840 print_idecode_body(file, table, "semantic =");
841 lf_putstr(file, " cia = semantic(processor, cache_entry, cia);\n");
843 lf_putstr(file, "}\n");
846 /* events */
847 lf_putstr(file, "\n");
848 lf_putstr(file, "/* process any events */\n");
849 lf_putstr(file, "if (WITH_EVENTS) {\n");
850 lf_putstr(file, " if (event_queue_tick(events)) {\n");
851 lf_putstr(file, " cpu_set_program_counter(processor, cia);\n");
852 lf_putstr(file, " event_queue_process(events);\n");
853 lf_putstr(file, " cia = cpu_get_program_counter(processor);\n");
854 lf_putstr(file, " }\n");
855 lf_putstr(file, "}\n");
857 /* tail */
858 if (can_stop) {
859 lf_putstr(file, "\n");
860 lf_putstr(file, "/* abort if necessary */\n");
861 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
862 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*not important*/);\n");
865 lf_indent(file, -2);
866 lf_putstr(file, "}\n");
869 if (generate_smp) {
871 lf_putstr(file, "\n\
872 /* CASE 2: SMP (With or without ICACHE)\n\
874 The complexity here comes from needing to correctly restart the\n\
875 system when it is aborted. In particular if cpu0 requests a\n\
876 restart, the next cpu is still cpu1. Cpu0 being restarted after\n\
877 all the other CPU's and the event queue have been processed */");
879 lf_putstr(file, "\n");
881 lf_putstr(file, "\n");
882 lf_putstr(file, "/* now establish the restart target */\n");
883 lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
884 lf_putstr(file, "if (setjmp(restart)) {\n");
885 lf_putstr(file, " current_cpu = psim_last_cpu(system);\n");
886 lf_putstr(file, " ASSERT(current_cpu >= 0 && current_cpu < nr_cpus);\n");
887 lf_putstr(file, "}\n");
888 lf_putstr(file, "else {\n");
889 lf_putstr(file, " current_cpu = last_cpu;\n");
890 lf_putstr(file, " ASSERT(current_cpu >= -1 && current_cpu < nr_cpus);\n");
891 lf_putstr(file, "}\n");
894 lf_putstr(file, "\n");
895 lf_putstr(file, "while (1) {\n");
896 lf_indent(file, +2);
898 lf_putstr(file, "\n");
899 lf_putstr(file, "if (WITH_EVENTS) {\n");
900 lf_putstr(file, " current_cpu += 1;\n");
901 lf_putstr(file, " if (current_cpu == nr_cpus) {\n");
902 lf_putstr(file, " if (event_queue_tick(events)) {\n");
903 lf_putstr(file, " event_queue_process(events);\n");
904 lf_putstr(file, " }\n");
905 lf_putstr(file, " current_cpu = 0;\n");
906 lf_putstr(file, " }\n");
907 lf_putstr(file, "}\n");
908 lf_putstr(file, "else {\n");
909 lf_putstr(file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
910 lf_putstr(file, "}\n");
912 lf_putstr(file, "\n");
913 lf_putstr(file, "{\n");
914 lf_indent(file, +2);
915 lf_putstr(file, "cpu *processor = processors[current_cpu];\n");
916 lf_putstr(file, "unsigned_word cia =\n");
917 lf_putstr(file, " cpu_get_program_counter(processor);\n");
919 if (!(code & generate_with_icache)) {
920 lf_putstr(file, "instruction_word instruction =\n");
921 lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
922 print_idecode_body(file, table, "cia =");
923 if (can_stop) {
924 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
925 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore*/);\n");
927 lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
930 if ((code & generate_with_icache)) {
931 lf_putstr(file, "idecode_cache *cache_entry =\n");
932 lf_putstr(file, " cpu_icache_entry(processor, cia);\n");
933 lf_putstr(file, "\n");
934 lf_putstr(file, "if (cache_entry->address == cia) {\n");
936 lf_indent(file, +2);
937 lf_putstr(file, "\n");
938 lf_putstr(file, "/* cache hit */\n");
939 lf_putstr(file, "idecode_semantic *semantic = cache_entry->semantic;\n");
940 lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n");
941 /* tail */
942 if (can_stop) {
943 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
944 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
946 lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
947 lf_putstr(file, "\n");
948 lf_indent(file, -2);
950 lf_putstr(file, "}\n");
951 lf_putstr(file, "else {\n");
953 lf_indent(file, +2);
954 lf_putstr(file, "\n");
955 lf_putstr(file, "/* cache miss */\n");
956 if (!(code & generate_with_semantic_icache)) {
957 lf_putstr(file, "idecode_semantic *semantic;\n");
959 lf_putstr(file, "instruction_word instruction =\n");
960 lf_putstr(file, " vm_instruction_map_read(cpu_instruction_map(processor), processor, cia);\n");
961 lf_putstr(file, "if (WITH_MON != 0)\n");
962 lf_putstr(file, " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n");
963 if ((code & generate_with_semantic_icache)) {
964 lf_putstr(file, "{\n");
965 lf_indent(file, +2);
966 print_idecode_body(file, table, "cia =");
967 lf_indent(file, -2);
968 lf_putstr(file, "}\n");
970 else {
971 print_idecode_body(file, table, "semantic = ");
972 lf_putstr(file, "cia = semantic(processor, cache_entry, cia);\n");
974 /* tail */
975 if (can_stop) {
976 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
977 lf_putstr(file, " cpu_halt(processor, cia, was_continuing, 0/*ignore-signal*/);\n");
979 lf_putstr(file, "cpu_set_program_counter(processor, cia);\n");
980 lf_putstr(file, "\n");
981 lf_indent(file, -2);
983 lf_putstr(file, "}\n");
986 /* close */
987 lf_indent(file, -2);
988 lf_putstr(file, "}\n");
990 /* tail */
991 lf_indent(file, -2);
992 lf_putstr(file, "}\n");
996 lf_indent(file, -2);
997 lf_putstr(file, "}\n");
1001 /****************************************************************/
1003 static void
1004 print_jump(lf *file,
1005 int is_tail)
1007 if (is_tail) {
1008 lf_putstr(file, "if (keep_running != NULL && !*keep_running)\n");
1009 lf_putstr(file, " cpu_halt(processor, nia, was_continuing, 0/*na*/);\n");
1012 if (!generate_smp) {
1013 lf_putstr(file, "if (WITH_EVENTS) {\n");
1014 lf_putstr(file, " if (event_queue_tick(events)) {\n");
1015 lf_putstr(file, " cpu_set_program_counter(processor, nia);\n");
1016 lf_putstr(file, " event_queue_process(events);\n");
1017 lf_putstr(file, " nia = cpu_get_program_counter(processor);\n");
1018 lf_putstr(file, " }\n");
1019 lf_putstr(file, "}\n");
1022 if (generate_smp) {
1023 if (is_tail)
1024 lf_putstr(file, "cpu_set_program_counter(processor, nia);\n");
1025 lf_putstr(file, "if (WITH_EVENTS) {\n");
1026 lf_putstr(file, " current_cpu += 1;\n");
1027 lf_putstr(file, " if (current_cpu >= nr_cpus) {\n");
1028 lf_putstr(file, " if (event_queue_tick(events)) {\n");
1029 lf_putstr(file, " event_queue_process(events);\n");
1030 lf_putstr(file, " }\n");
1031 lf_putstr(file, " current_cpu = 0;\n");
1032 lf_putstr(file, " }\n");
1033 lf_putstr(file, "}\n");
1034 lf_putstr(file, "else {\n");
1035 lf_putstr(file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
1036 lf_putstr(file, "}\n");
1037 lf_putstr(file, "processor = processors[current_cpu];\n");
1038 lf_putstr(file, "nia = cpu_get_program_counter(processor);\n");
1041 if ((code & generate_with_icache)) {
1042 lf_putstr(file, "cache_entry = cpu_icache_entry(processor, nia);\n");
1043 lf_putstr(file, "if (cache_entry->address == nia) {\n");
1044 lf_putstr(file, " /* cache hit */\n");
1045 lf_putstr(file, " goto *cache_entry->semantic;\n");
1046 lf_putstr(file, "}\n");
1047 if (is_tail) {
1048 lf_putstr(file, "goto cache_miss;\n");
1052 if (!(code & generate_with_icache) && is_tail) {
1053 lf_printf(file, "goto idecode;\n");
1062 static void
1063 print_jump_insn(lf *file,
1064 insn *instruction,
1065 insn_bits *expanded_bits,
1066 opcode_field *opcodes,
1067 cache_table *cache_rules)
1070 /* what we are for the moment */
1071 lf_printf(file, "\n");
1072 print_my_defines(file, expanded_bits, instruction->file_entry);
1074 /* output the icache entry */
1075 if ((code & generate_with_icache)) {
1076 lf_printf(file, "\n");
1077 lf_indent(file, -1);
1078 print_function_name(file,
1079 instruction->file_entry->fields[insn_name],
1080 expanded_bits,
1081 function_name_prefix_icache);
1082 lf_printf(file, ":\n");
1083 lf_indent(file, +1);
1084 lf_printf(file, "{\n");
1085 lf_indent(file, +2);
1086 lf_putstr(file, "const unsigned_word cia = nia;\n");
1087 print_itrace(file, instruction->file_entry, 1/*putting-value-in-cache*/);
1088 print_idecode_validate(file, instruction, opcodes);
1089 lf_printf(file, "\n");
1090 lf_printf(file, "{\n");
1091 lf_indent(file, +2);
1092 print_icache_body(file,
1093 instruction,
1094 expanded_bits,
1095 cache_rules,
1096 0, /*use_defines*/
1097 put_values_in_icache);
1098 lf_printf(file, "cache_entry->address = nia;\n");
1099 lf_printf(file, "cache_entry->semantic = &&");
1100 print_function_name(file,
1101 instruction->file_entry->fields[insn_name],
1102 expanded_bits,
1103 function_name_prefix_semantics);
1104 lf_printf(file, ";\n");
1105 if ((code & generate_with_semantic_icache)) {
1106 print_semantic_body(file,
1107 instruction,
1108 expanded_bits,
1109 opcodes);
1110 print_jump(file, 1/*is-tail*/);
1112 else {
1113 lf_printf(file, "/* goto ");
1114 print_function_name(file,
1115 instruction->file_entry->fields[insn_name],
1116 expanded_bits,
1117 function_name_prefix_semantics);
1118 lf_printf(file, "; */\n");
1120 lf_indent(file, -2);
1121 lf_putstr(file, "}\n");
1122 lf_indent(file, -2);
1123 lf_printf(file, "}\n");
1126 /* print the semantics */
1127 lf_printf(file, "\n");
1128 lf_indent(file, -1);
1129 print_function_name(file,
1130 instruction->file_entry->fields[insn_name],
1131 expanded_bits,
1132 function_name_prefix_semantics);
1133 lf_printf(file, ":\n");
1134 lf_indent(file, +1);
1135 lf_printf(file, "{\n");
1136 lf_indent(file, +2);
1137 lf_putstr(file, "const unsigned_word cia = nia;\n");
1138 print_icache_body(file,
1139 instruction,
1140 expanded_bits,
1141 cache_rules,
1142 ((code & generate_with_direct_access)
1143 ? define_variables
1144 : declare_variables),
1145 ((code & generate_with_icache)
1146 ? get_values_from_icache
1147 : do_not_use_icache));
1148 print_semantic_body(file,
1149 instruction,
1150 expanded_bits,
1151 opcodes);
1152 if (code & generate_with_direct_access)
1153 print_icache_body(file,
1154 instruction,
1155 expanded_bits,
1156 cache_rules,
1157 undef_variables,
1158 ((code & generate_with_icache)
1159 ? get_values_from_icache
1160 : do_not_use_icache));
1161 print_jump(file, 1/*is tail*/);
1162 lf_indent(file, -2);
1163 lf_printf(file, "}\n");
1166 static void
1167 print_jump_definition(insn_table *entry,
1168 lf *file,
1169 void *data,
1170 insn *instruction,
1171 int depth)
1173 cache_table *cache_rules = (cache_table*)data;
1174 if (generate_expanded_instructions) {
1175 ASSERT(entry->nr_insn == 1
1176 && entry->opcode == NULL
1177 && entry->parent != NULL
1178 && entry->parent->opcode != NULL);
1179 ASSERT(entry->nr_insn == 1
1180 && entry->opcode == NULL
1181 && entry->parent != NULL
1182 && entry->parent->opcode != NULL
1183 && entry->parent->opcode_rule != NULL);
1184 print_jump_insn(file,
1185 entry->insns,
1186 entry->expanded_bits,
1187 entry->opcode,
1188 cache_rules);
1190 else {
1191 print_jump_insn(file,
1192 instruction,
1193 NULL,
1194 NULL,
1195 cache_rules);
1200 static void
1201 print_jump_internal_function(insn_table *table,
1202 lf *file,
1203 void *data,
1204 table_entry *function)
1206 if (it_is("internal", function->fields[insn_flags])) {
1207 lf_printf(file, "\n");
1208 table_entry_print_cpp_line_nr(file, function);
1209 lf_indent(file, -1);
1210 print_function_name(file,
1211 function->fields[insn_name],
1212 NULL,
1213 ((code & generate_with_icache)
1214 ? function_name_prefix_icache
1215 : function_name_prefix_semantics));
1216 lf_printf(file, ":\n");
1217 lf_indent(file, +1);
1218 lf_printf(file, "{\n");
1219 lf_indent(file, +2);
1220 lf_printf(file, "const unsigned_word cia = nia;\n");
1221 lf_print__c_code(file, function->annex);
1222 lf_print__internal_ref(file);
1223 lf_printf(file, "error(\"Internal function must longjump\\n\");\n");
1224 lf_indent(file, -2);
1225 lf_printf(file, "}\n");
1229 static void
1230 print_jump_until_stop_body(lf *file,
1231 insn_table *table,
1232 cache_table *cache_rules,
1233 int can_stop)
1235 lf_printf(file, "{\n");
1236 lf_indent(file, +2);
1237 if (!can_stop)
1238 lf_printf(file, "int *keep_running = NULL;\n");
1239 lf_putstr(file, "jmp_buf halt;\n");
1240 lf_putstr(file, "jmp_buf restart;\n");
1241 lf_putstr(file, "cpu *processor = NULL;\n");
1242 lf_putstr(file, "unsigned_word nia = -1;\n");
1243 lf_putstr(file, "instruction_word instruction = 0;\n");
1244 if ((code & generate_with_icache)) {
1245 lf_putstr(file, "idecode_cache *cache_entry = NULL;\n");
1247 if (generate_smp) {
1248 lf_putstr(file, "int current_cpu = -1;\n");
1251 /* all the switches and tables - they know about jumping */
1252 print_idecode_lookups(file, table, cache_rules);
1254 /* start the simulation up */
1255 if ((code & generate_with_icache)) {
1256 lf_putstr(file, "\n");
1257 lf_putstr(file, "{\n");
1258 lf_putstr(file, " int cpu_nr;\n");
1259 lf_putstr(file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
1260 lf_putstr(file, " cpu_flush_icache(processors[cpu_nr]);\n");
1261 lf_putstr(file, "}\n");
1264 lf_putstr(file, "\n");
1265 lf_putstr(file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1267 lf_putstr(file, "\n");
1268 lf_putstr(file, "if (setjmp(halt))\n");
1269 lf_putstr(file, " return;\n");
1271 lf_putstr(file, "\n");
1272 lf_putstr(file, "setjmp(restart);\n");
1274 lf_putstr(file, "\n");
1275 if (!generate_smp) {
1276 lf_putstr(file, "processor = processors[0];\n");
1277 lf_putstr(file, "nia = cpu_get_program_counter(processor);\n");
1279 else {
1280 lf_putstr(file, "current_cpu = psim_last_cpu(system);\n");
1283 if (!(code & generate_with_icache)) {
1284 lf_printf(file, "\n");
1285 lf_indent(file, -1);
1286 lf_printf(file, "idecode:\n");
1287 lf_indent(file, +1);
1290 print_jump(file, 0/*is_tail*/);
1292 if ((code & generate_with_icache)) {
1293 lf_indent(file, -1);
1294 lf_printf(file, "cache_miss:\n");
1295 lf_indent(file, +1);
1298 lf_putstr(file, "instruction\n");
1299 lf_putstr(file, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
1300 lf_putstr(file, " processor, nia);\n");
1301 print_idecode_body(file, table, "/*IGORE*/");
1303 /* print out a table of all the internals functions */
1304 insn_table_traverse_function(table,
1305 file, NULL,
1306 print_jump_internal_function);
1308 /* print out a table of all the instructions */
1309 if (generate_expanded_instructions)
1310 insn_table_traverse_tree(table,
1311 file, cache_rules,
1313 NULL, /* start */
1314 print_jump_definition, /* leaf */
1315 NULL, /* end */
1316 NULL); /* padding */
1317 else
1318 insn_table_traverse_insn(table,
1319 file, cache_rules,
1320 print_jump_definition);
1321 lf_indent(file, -2);
1322 lf_printf(file, "}\n");
1326 /****************************************************************/
1330 static void
1331 print_idecode_floating_point_unavailable(lf *file)
1333 if ((code & generate_jumps))
1334 lf_printf(file, "goto %s_floating_point_unavailable;\n", (code & generate_with_icache) ? "icache" : "semantic");
1335 else if ((code & generate_with_icache))
1336 lf_printf(file, "return icache_floating_point_unavailable(%s);\n",
1337 ICACHE_FUNCTION_ACTUAL);
1338 else
1339 lf_printf(file, "return semantic_floating_point_unavailable(%s);\n",
1340 SEMANTIC_FUNCTION_ACTUAL);
1344 /* Output code to do any final checks on the decoded instruction.
1345 This includes things like verifying any on decoded fields have the
1346 correct value and checking that (for floating point) floating point
1347 hardware isn't disabled */
1349 void
1350 print_idecode_validate(lf *file,
1351 insn *instruction,
1352 opcode_field *opcodes)
1354 /* Validate: unchecked instruction fields
1356 If any constant fields in the instruction were not checked by the
1357 idecode tables, output code to check that they have the correct
1358 value here */
1360 unsigned check_mask = 0;
1361 unsigned check_val = 0;
1362 insn_field *field;
1363 opcode_field *opcode;
1365 /* form check_mask/check_val containing what needs to be checked
1366 in the instruction */
1367 for (field = instruction->fields->first;
1368 field->first < insn_bit_size;
1369 field = field->next) {
1371 check_mask <<= field->width;
1372 check_val <<= field->width;
1374 /* is it a constant that could need validating? */
1375 if (!field->is_int && !field->is_slash)
1376 continue;
1378 /* has it been checked by a table? */
1379 for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
1380 if (field->first >= opcode->first
1381 && field->last <= opcode->last)
1382 break;
1384 if (opcode != NULL)
1385 continue;
1387 check_mask |= (1 << field->width)-1;
1388 check_val |= field->val_int;
1391 /* if any bits not checked by opcode tables, output code to check them */
1392 if (check_mask) {
1393 lf_printf(file, "\n");
1394 lf_printf(file, "/* validate: %s */\n",
1395 instruction->file_entry->fields[insn_format]);
1396 lf_printf(file, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
1397 check_mask, check_val);
1398 lf_indent(file, +2);
1399 print_idecode_illegal(file, "return");
1400 lf_indent(file, -2);
1404 /* Validate floating point hardware
1406 If the simulator is being built with out floating point hardware
1407 (different to it being disabled in the MSR) then floating point
1408 instructions are invalid */
1410 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1411 lf_printf(file, "\n");
1412 lf_printf(file, "/* Validate: FP hardware exists */\n");
1413 lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1414 lf_indent(file, +2);
1415 print_idecode_illegal(file, "return");
1416 lf_indent(file, -2);
1420 /* Validate: Floating Point available
1422 If floating point is not available, we enter a floating point
1423 unavailable interrupt into the cache instead of the instruction
1424 proper.
1426 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1427 ever a CSI occures we flush the instruction cache. */
1430 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1431 lf_printf(file, "\n");
1432 lf_printf(file, "/* Validate: FP available according to MSR[FP] */\n");
1433 lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n");
1434 lf_indent(file, +2);
1435 print_idecode_floating_point_unavailable(file);
1436 lf_indent(file, -2);
1442 /****************************************************************/
1445 static void
1446 print_idecode_run_function_header(lf *file,
1447 int can_stop,
1448 int is_definition)
1450 int indent;
1451 lf_printf(file, "\n");
1452 lf_print__function_type(file, "void", "PSIM_INLINE_IDECODE", (is_definition ? " " : "\n"));
1453 indent = lf_putstr(file, (can_stop ? "idecode_run_until_stop" : "idecode_run"));
1454 if (is_definition)
1455 lf_putstr(file, "\n");
1456 else
1457 lf_indent(file, +indent);
1458 lf_putstr(file, "(psim *system,\n");
1459 if (can_stop)
1460 lf_putstr(file, " volatile int *keep_running,\n");
1461 lf_printf(file, " event_queue *events,\n");
1462 lf_putstr(file, " cpu *const processors[],\n");
1463 lf_putstr(file, " const int nr_cpus)");
1464 if (is_definition)
1465 lf_putstr(file, ";");
1466 else
1467 lf_indent(file, -indent);
1468 lf_putstr(file, "\n");
1472 void
1473 gen_idecode_h(lf *file,
1474 insn_table *table,
1475 cache_table *cache_rules)
1477 lf_printf(file, "/* The idecode_*.h functions shall move to support */\n");
1478 lf_printf(file, "#include \"idecode_expression.h\"\n");
1479 lf_printf(file, "#include \"idecode_fields.h\"\n");
1480 lf_printf(file, "#include \"idecode_branch.h\"\n");
1481 lf_printf(file, "\n");
1482 print_icache_struct(table, cache_rules, file);
1483 lf_printf(file, "\n");
1484 lf_printf(file, "#define WITH_IDECODE_SMP %d\n", generate_smp);
1485 lf_printf(file, "\n");
1486 print_idecode_run_function_header(file, 0/*can stop*/, 1/*is definition*/);
1487 print_idecode_run_function_header(file, 1/*can stop*/, 1/*is definition*/);
1491 void
1492 gen_idecode_c(lf *file,
1493 insn_table *table,
1494 cache_table *cache_rules)
1496 /* the intro */
1497 lf_printf(file, "#include \"inline.c\"\n");
1498 lf_printf(file, "\n");
1499 lf_printf(file, "#include \"cpu.h\"\n");
1500 lf_printf(file, "#include \"idecode.h\"\n");
1501 lf_printf(file, "#include \"semantics.h\"\n");
1502 lf_printf(file, "#include \"icache.h\"\n");
1503 lf_printf(file, "#ifdef HAVE_COMMON_FPU\n");
1504 lf_printf(file, "#include \"sim-inline.h\"\n");
1505 lf_printf(file, "#include \"sim-fpu.h\"\n");
1506 lf_printf(file, "#endif\n");
1507 lf_printf(file, "#include \"support.h\"\n");
1508 lf_printf(file, "\n");
1509 lf_printf(file, "#include <setjmp.h>\n");
1510 lf_printf(file, "\n");
1511 lf_printf(file, "enum {\n");
1512 lf_printf(file, " /* greater or equal to zero => table */\n");
1513 lf_printf(file, " function_entry = -1,\n");
1514 lf_printf(file, " boolean_entry = -2,\n");
1515 lf_printf(file, "};\n");
1516 lf_printf(file, "\n");
1517 lf_printf(file, "typedef struct _idecode_table_entry {\n");
1518 lf_printf(file, " int shift;\n");
1519 lf_printf(file, " instruction_word mask;\n");
1520 lf_printf(file, " instruction_word value;");
1521 lf_printf(file, " void *function_or_table;\n");
1522 lf_printf(file, "} idecode_table_entry;\n");
1523 lf_printf(file, "\n");
1524 lf_printf(file, "\n");
1526 if ((code & generate_calls)) {
1528 print_idecode_lookups(file, table, cache_rules);
1530 /* output the main idecode routine */
1531 print_idecode_run_function_header(file, 0/*can stop*/, 0/*is definition*/);
1532 print_run_until_stop_body(file, table, 0/* have stop argument */);
1534 print_idecode_run_function_header(file, 1/*can stop*/, 0/*is definition*/);
1535 print_run_until_stop_body(file, table, 1/* no stop argument */);
1538 else if ((code & generate_jumps)) {
1540 print_idecode_run_function_header(file, 0/*can stop*/, 0/*is definition*/);
1541 print_jump_until_stop_body(file, table, cache_rules, 0 /* have stop argument */);
1543 print_idecode_run_function_header(file, 1/*can stop*/, 0/*is definition*/);
1544 print_jump_until_stop_body(file, table, cache_rules, 1/* have stop argument */);
1547 else {
1548 ERROR("Something is wrong!\n");