]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/igen/gen-idecode.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / igen / gen-idecode.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
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.
9
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.
14
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.
18
19 */
20
21 #include "misc.h"
22 #include "lf.h"
23 #include "table.h"
24 #include "filter.h"
25 #include "igen.h"
26
27 #include "ld-insn.h"
28 #include "ld-decode.h"
29
30 #include "gen.h"
31
32 #include "gen-idecode.h"
33 #include "gen-icache.h"
34 #include "gen-semantics.h"
35
36
37
38 static void
39 lf_print_opcodes (lf *file,
40 gen_entry *table)
41 {
42 if (table != NULL)
43 {
44 while (1)
45 {
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;
53 }
54 }
55 }
56
57
58
59
60 static void
61 print_idecode_ifetch (lf *file,
62 int previous_nr_prefetched_words,
63 int current_nr_prefetched_words)
64 {
65 int word_nr;
66 for (word_nr = previous_nr_prefetched_words;
67 word_nr < current_nr_prefetched_words;
68 word_nr ++)
69 {
70 lf_printf (file, "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
71 word_nr, options.insn_bit_size, word_nr);
72
73 }
74 }
75
76
77
78 /****************************************************************/
79
80
81 static void
82 lf_print_table_name (lf *file,
83 gen_entry *table)
84 {
85 lf_printf (file, "idecode_table");
86 lf_print_opcodes (file, table);
87 }
88
89
90
91 static void
92 print_idecode_table (lf *file,
93 gen_entry *entry,
94 const char *result)
95 {
96 lf_printf (file, "/* prime the search */\n");
97 lf_printf (file, "idecode_table_entry *table = ");
98 lf_print_table_name (file, entry);
99 lf_printf (file, ";\n");
100 lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n",
101 options.insn_bit_size,
102 i2target (options.hi_bit_nr, entry->opcode->first),
103 i2target (options.hi_bit_nr, entry->opcode->last));
104 lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");
105
106 lf_printf (file, "\n");
107 lf_printf (file, "/* iterate until a leaf */\n");
108 lf_printf (file, "while (1) {\n");
109 lf_printf (file, " signed shift = table_entry->shift;\n");
110 lf_printf (file, "if (shift == function_entry) break;\n");
111 lf_printf (file, " if (shift >= 0) {\n");
112 lf_printf (file, " table = ((idecode_table_entry*)\n");
113 lf_printf (file, " table_entry->function_or_table);\n");
114 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
115 lf_printf (file, " >> shift);\n");
116 lf_printf (file, " table_entry = table + opcode;\n");
117 lf_printf (file, " }\n");
118 lf_printf (file, " else {\n");
119 lf_printf (file, " /* must be a boolean */\n");
120 lf_printf (file, " ASSERT(table_entry->shift == boolean_entry);\n");
121 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
122 lf_printf (file, " != table_entry->value);\n");
123 lf_printf (file, " table = ((idecode_table_entry*)\n");
124 lf_printf (file, " table_entry->function_or_table);\n");
125 lf_printf (file, " table_entry = table + opcode;\n");
126 lf_printf (file, " }\n");
127 lf_printf (file, "}\n");
128
129 lf_printf (file, "\n");
130 lf_printf (file, "/* call the leaf code */\n");
131 if (options.gen.code == generate_jumps)
132 {
133 lf_printf (file, "goto *table_entry->function_or_table;\n");
134 }
135 else
136 {
137 lf_printf (file, "%s ", result);
138 if (options.gen.icache)
139 {
140 lf_printf (file, "(((idecode_icache*)table_entry->function_or_table)\n");
141 lf_printf (file, " (");
142 print_icache_function_actual (file, 1);
143 lf_printf (file, "));\n");
144 }
145 else
146 {
147 lf_printf (file, "((idecode_semantic*)table_entry->function_or_table)\n");
148 lf_printf (file, " (");
149 print_semantic_function_actual (file, 1);
150 lf_printf (file, ");\n");
151 }
152 }
153 }
154
155
156 static void
157 print_idecode_table_start (lf *file,
158 gen_entry *table,
159 int depth,
160 void *data)
161 {
162 ASSERT (depth == 0);
163 /* start of the table */
164 if (table->opcode_rule->gen == array_gen)
165 {
166 lf_printf (file, "\n");
167 lf_printf (file, "static idecode_table_entry ");
168 lf_print_table_name (file, table);
169 lf_printf (file, "[] = {\n");
170 }
171 }
172
173 static void
174 print_idecode_table_leaf (lf *file,
175 gen_entry *entry,
176 int depth,
177 void *data)
178 {
179 gen_entry *master_entry;
180 ASSERT (entry->parent != NULL);
181 ASSERT (depth == 0);
182 if (entry->combined_parent == NULL)
183 master_entry = entry;
184 else
185 master_entry = entry->combined_parent;
186
187 /* add an entry to the table */
188 if (entry->parent->opcode_rule->gen == array_gen)
189 {
190 lf_printf (file, " /*%d*/ { ", entry->opcode_nr);
191 if (entry->opcode == NULL)
192 {
193 ASSERT (entry->nr_insns == 1);
194 /* table leaf entry */
195 lf_printf (file, "function_entry, 0, 0, ");
196 if (options.gen.code == generate_jumps)
197 {
198 lf_printf (file, "&&");
199 }
200 print_function_name (file,
201 entry->insns->insn->name,
202 entry->insns->insn->format_name,
203 NULL,
204 master_entry->expanded_bits,
205 (options.gen.icache
206 ? function_name_prefix_icache
207 : function_name_prefix_semantics));
208 }
209 else if (entry->opcode_rule->gen == switch_gen
210 || entry->opcode_rule->gen == goto_switch_gen
211 || entry->opcode_rule->gen == padded_switch_gen)
212 {
213 /* table calling switch statement */
214 lf_printf (file, "function_entry, 0, 0, ");
215 if (options.gen.code == generate_jumps)
216 {
217 lf_printf (file, "&&");
218 }
219 lf_print_table_name (file, entry);
220 }
221 else if (entry->opcode->is_boolean)
222 {
223 /* table `calling' boolean table */
224 lf_printf (file, "boolean_entry, ");
225 lf_printf (file, "MASK32(%d, %d), ",
226 i2target (options.hi_bit_nr, entry->opcode->first),
227 i2target (options.hi_bit_nr, entry->opcode->last));
228 lf_printf (file, "INSERTED32(%d, %d, %d), ",
229 entry->opcode->boolean_constant,
230 i2target (options.hi_bit_nr, entry->opcode->first),
231 i2target (options.hi_bit_nr, entry->opcode->last));
232 lf_print_table_name (file, entry);
233 }
234 else
235 {
236 /* table `calling' another table */
237 lf_printf (file, "%d, ", options.insn_bit_size - entry->opcode->last - 1);
238 lf_printf (file, "MASK%d(%d,%d), ",
239 options.insn_bit_size,
240 i2target (options.hi_bit_nr, entry->opcode->first),
241 i2target (options.hi_bit_nr, entry->opcode->last));
242 lf_printf (file, "0, ");
243 lf_print_table_name (file, entry);
244 }
245 lf_printf (file, " },\n");
246 }
247 }
248
249 static void
250 print_idecode_table_end (lf *file,
251 gen_entry *table,
252 int depth,
253 void *data)
254 {
255 ASSERT (depth == 0);
256 if (table->opcode_rule->gen == array_gen) {
257 lf_printf (file, "};\n");
258 }
259 }
260
261 /****************************************************************/
262
263
264 static void
265 print_goto_switch_name (lf *file,
266 gen_entry *entry)
267 {
268 lf_printf (file, "case_");
269 if (entry->opcode == NULL)
270 {
271 print_function_name (file,
272 entry->insns->insn->name,
273 entry->insns->insn->format_name,
274 NULL,
275 entry->expanded_bits,
276 (options.gen.icache
277 ? function_name_prefix_icache
278 : function_name_prefix_semantics));
279 }
280 else
281 {
282 lf_print_table_name(file, entry);
283 }
284 }
285
286 static void
287 print_goto_switch_table_leaf (lf *file,
288 gen_entry *entry,
289 int depth,
290 void *data)
291 {
292 ASSERT (entry->parent != NULL);
293 ASSERT (depth == 0);
294 ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);
295 ASSERT (entry->parent->opcode);
296
297 lf_printf (file, "/* %d */ &&", entry->opcode_nr);
298 if (entry->combined_parent != NULL)
299 print_goto_switch_name (file, entry->combined_parent);
300 else
301 print_goto_switch_name (file, entry);
302 lf_printf (file, ",\n");
303 }
304
305 static void
306 print_goto_switch_break (lf *file,
307 gen_entry *entry)
308 {
309 lf_printf (file, "goto break_");
310 lf_print_table_name (file, entry->parent);
311 lf_printf (file, ";\n");
312 }
313
314
315 static void
316 print_goto_switch_table (lf *file,
317 gen_entry *table)
318 {
319 lf_printf (file, "const static void *");
320 lf_print_table_name (file, table);
321 lf_printf (file, "[] = {\n");
322 lf_indent (file, +2);
323 gen_entry_traverse_tree (file, table,
324 0,
325 NULL/*start*/,
326 print_goto_switch_table_leaf,
327 NULL/*end*/,
328 NULL/*data*/);
329 lf_indent (file, -2);
330 lf_printf (file, "};\n");
331 }
332
333
334 void print_idecode_switch
335 (lf *file,
336 gen_entry *table,
337 const char *result);
338
339 static void
340 print_idecode_switch_start (lf *file,
341 gen_entry *table,
342 int depth,
343 void *data)
344 {
345 /* const char *result = data; */
346 ASSERT (depth == 0);
347 ASSERT (table->opcode_rule->gen == switch_gen
348 || table->opcode_rule->gen == goto_switch_gen
349 || table->opcode_rule->gen == padded_switch_gen);
350
351 if (table->opcode->is_boolean
352 || table->opcode_rule->gen == switch_gen
353 || table->opcode_rule->gen == padded_switch_gen)
354 {
355 lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n",
356 options.insn_bit_size,
357 table->opcode_rule->word_nr,
358 i2target (options.hi_bit_nr, table->opcode->first),
359 i2target (options.hi_bit_nr, table->opcode->last));
360 lf_indent (file, +2);
361 lf_printf (file, "{\n");
362 }
363 else if (table->opcode_rule->gen == goto_switch_gen)
364 {
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 {
370 lf_printf (file, "{\n");
371 lf_indent (file, +2);
372 }
373 print_goto_switch_table (file, table);
374 lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n",
375 options.insn_bit_size,
376 table->opcode->word_nr,
377 i2target (options.hi_bit_nr, table->opcode->first),
378 i2target (options.hi_bit_nr, table->opcode->last));
379 lf_printf (file, " < (sizeof (");
380 lf_print_table_name (file, table);
381 lf_printf (file, ") / sizeof(void*)));\n");
382 lf_printf (file, "goto *");
383 lf_print_table_name (file, table);
384 lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n",
385 options.insn_bit_size,
386 table->opcode->word_nr,
387 i2target (options.hi_bit_nr, table->opcode->first),
388 i2target (options.hi_bit_nr, table->opcode->last));
389 }
390 else
391 {
392 ASSERT("bad switch" == NULL);
393 }
394 }
395
396
397 static void
398 print_idecode_switch_leaf (lf *file,
399 gen_entry *entry,
400 int depth,
401 void *data)
402 {
403 const char *result = data;
404 ASSERT (entry->parent != NULL);
405 ASSERT (depth == 0);
406 ASSERT (entry->parent->opcode_rule->gen == switch_gen
407 || entry->parent->opcode_rule->gen == goto_switch_gen
408 || entry->parent->opcode_rule->gen == padded_switch_gen);
409 ASSERT (entry->parent->opcode);
410
411 /* skip over any instructions combined into another entry */
412 if (entry->combined_parent != NULL)
413 return;
414
415 if (entry->parent->opcode->is_boolean
416 && entry->opcode_nr == 0)
417 {
418 /* case: boolean false target */
419 lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
420 }
421 else if (entry->parent->opcode->is_boolean
422 && entry->opcode_nr != 0)
423 {
424 /* case: boolean true case */
425 lf_printf (file, "default:\n");
426 }
427 else if (entry->parent->opcode_rule->gen == switch_gen
428 || entry->parent->opcode_rule->gen == padded_switch_gen)
429 {
430 /* case: <opcode-nr> - switch */
431 gen_entry *cob;
432 for (cob = entry; cob != NULL; cob = cob->combined_next)
433 lf_printf (file, "case %d:\n", cob->opcode_nr);
434 }
435 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
436 {
437 /* case: <opcode-nr> - goto-switch */
438 print_goto_switch_name (file, entry);
439 lf_printf (file, ":\n");
440 }
441 else
442 {
443 ERROR ("bad switch");
444 }
445 lf_printf (file, " {\n");
446 lf_indent (file, +4);
447 {
448 if (entry->opcode == NULL)
449 {
450 /* switch calling leaf */
451 ASSERT (entry->nr_insns == 1);
452 print_idecode_ifetch (file, entry->nr_prefetched_words,
453 entry->insns->semantic->nr_prefetched_words);
454 switch (options.gen.code)
455 {
456 case generate_jumps:
457 lf_printf (file, "goto ");
458 break;
459 case generate_calls:
460 lf_printf (file, "%s", result);
461 break;
462 }
463 print_function_name (file,
464 entry->insns->insn->name,
465 entry->insns->insn->format_name,
466 NULL,
467 entry->expanded_bits,
468 (options.gen.icache
469 ? function_name_prefix_icache
470 : function_name_prefix_semantics));
471 if (options.gen.code == generate_calls)
472 {
473 lf_printf (file, " (");
474 print_semantic_function_actual (file, entry->insns->semantic->nr_prefetched_words);
475 lf_printf (file, ")");
476 }
477 lf_printf (file, ";\n");
478 }
479 else if (entry->opcode_rule->gen == switch_gen
480 || entry->opcode_rule->gen == goto_switch_gen
481 || entry->opcode_rule->gen == padded_switch_gen)
482 {
483 /* switch calling switch */
484 lf_printf (file, "{\n");
485 lf_indent (file, +2);
486 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
487 entry->nr_prefetched_words);
488 print_idecode_switch (file, entry, result);
489 lf_indent (file, -2);
490 lf_printf (file, "}\n");
491 }
492 else
493 {
494 /* switch looking up a table */
495 lf_printf (file, "{\n");
496 lf_indent (file, +2);
497 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
498 entry->nr_prefetched_words);
499 print_idecode_table (file, entry, result);
500 lf_indent (file, -2);
501 lf_printf (file, "}\n");
502 }
503 if (entry->parent->opcode->is_boolean
504 || entry->parent->opcode_rule->gen == switch_gen
505 || entry->parent->opcode_rule->gen == padded_switch_gen)
506 {
507 lf_printf (file, "break;\n");
508 }
509 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
510 {
511 print_goto_switch_break(file, entry);
512 }
513 else
514 {
515 ERROR ("bad switch");
516 }
517 }
518 lf_indent (file, -4);
519 lf_printf (file, " }\n");
520 }
521
522
523 static void
524 print_idecode_switch_illegal (lf *file,
525 const char *result)
526 {
527 lf_indent (file, +2);
528 print_idecode_invalid (file, result, invalid_illegal);
529 lf_printf (file, "break;\n");
530 lf_indent (file, -2);
531 }
532
533 static void
534 print_idecode_switch_end (lf *file,
535 gen_entry *table,
536 int depth,
537 void *data)
538 {
539 const char *result = data;
540 ASSERT (depth == 0);
541 ASSERT (table->opcode_rule->gen == switch_gen
542 || table->opcode_rule->gen == goto_switch_gen
543 || table->opcode_rule->gen == padded_switch_gen);
544 ASSERT (table->opcode);
545
546 if (table->opcode->is_boolean)
547 {
548 lf_printf (file, "}\n");
549 lf_indent (file, -2);
550 }
551 else if (table->opcode_rule->gen == switch_gen
552 || table->opcode_rule->gen == padded_switch_gen)
553 {
554 lf_printf (file, "default:\n");
555 lf_indent (file, +2);
556 if (table->nr_entries == table->opcode->nr_opcodes)
557 {
558 print_sim_engine_abort (file, "Internal error - bad switch generated");
559 lf_printf (file, "%sNULL_CIA;\n", result);
560 lf_printf (file, "break;\n");
561 }
562 else
563 {
564 print_idecode_switch_illegal (file, result);
565 }
566 lf_indent (file, -2);
567 lf_printf (file, "}\n");
568 lf_indent (file, -2);
569 }
570 else if (table->opcode_rule->gen == goto_switch_gen)
571 {
572 lf_printf (file, "illegal_");
573 lf_print_table_name (file, table);
574 lf_printf (file, ":\n");
575 print_idecode_invalid (file, result, invalid_illegal);
576 lf_printf (file, "break_");
577 lf_print_table_name(file, table);
578 lf_printf (file, ":;\n");
579 if (table->parent != NULL
580 && (table->parent->opcode_rule->gen == switch_gen
581 || table->parent->opcode_rule->gen == goto_switch_gen
582 || table->parent->opcode_rule->gen == padded_switch_gen))
583 {
584 lf_indent (file, -2);
585 lf_printf (file, "}\n");
586 }
587 }
588 else
589 {
590 ERROR ("bad switch");
591 }
592 }
593
594
595 void
596 print_idecode_switch (lf *file,
597 gen_entry *table,
598 const char *result)
599 {
600 gen_entry_traverse_tree (file, table,
601 0,
602 print_idecode_switch_start,
603 print_idecode_switch_leaf,
604 print_idecode_switch_end,
605 (void*)result);
606 }
607
608
609 static void
610 print_idecode_switch_function_header (lf *file,
611 gen_entry *table,
612 int is_function_definition,
613 int nr_prefetched_words)
614 {
615 lf_printf (file, "\n");
616 if (options.gen.code == generate_calls)
617 {
618 lf_printf (file, "static ");
619 if (options.gen.icache)
620 {
621 lf_printf (file, "idecode_semantic *");
622 }
623 else
624 {
625 lf_printf (file, "unsigned_word");
626 }
627 if (is_function_definition)
628 {
629 lf_printf (file, "\n");
630 }
631 else
632 {
633 lf_printf (file, " ");
634 }
635 lf_print_table_name (file, table);
636 lf_printf (file, "\n(");
637 print_icache_function_formal (file, nr_prefetched_words);
638 lf_printf (file, ")");
639 if (!is_function_definition)
640 {
641 lf_printf (file, ";");
642 }
643 lf_printf (file, "\n");
644 }
645 if (options.gen.code == generate_jumps && is_function_definition)
646 {
647 lf_indent (file, -1);
648 lf_print_table_name (file, table);
649 lf_printf (file, ":\n");
650 lf_indent (file, +1);
651 }
652 }
653
654
655 static void
656 idecode_declare_if_switch (lf *file,
657 gen_entry *table,
658 int depth,
659 void *data)
660 {
661 if ((table->opcode_rule->gen == switch_gen
662 || table->opcode_rule->gen == goto_switch_gen
663 || table->opcode_rule->gen == padded_switch_gen)
664 && table->parent != NULL /* don't declare the top one yet */
665 && table->parent->opcode_rule->gen == array_gen)
666 {
667 print_idecode_switch_function_header (file,
668 table,
669 0/*isnt function definition*/,
670 0);
671 }
672 }
673
674
675 static void
676 idecode_expand_if_switch (lf *file,
677 gen_entry *table,
678 int depth,
679 void *data)
680 {
681 if ((table->opcode_rule->gen == switch_gen
682 || table->opcode_rule->gen == goto_switch_gen
683 || table->opcode_rule->gen == padded_switch_gen)
684 && table->parent != NULL /* don't expand the top one yet */
685 && table->parent->opcode_rule->gen == array_gen)
686 {
687 print_idecode_switch_function_header(file,
688 table,
689 1/*is function definition*/,
690 0);
691 if (options.gen.code == generate_calls)
692 {
693 lf_printf (file, "{\n");
694 lf_indent (file, +2);
695 }
696 print_idecode_switch(file, table, "return");
697 if (options.gen.code == generate_calls)
698 {
699 lf_indent (file, -2);
700 lf_printf (file, "}\n");
701 }
702 }
703 }
704
705
706 /****************************************************************/
707
708
709 void
710 print_idecode_lookups (lf *file,
711 gen_entry *table,
712 cache_entry *cache_rules)
713 {
714 int depth;
715
716 /* output switch function declarations where needed by tables */
717 gen_entry_traverse_tree (file, table,
718 1,
719 idecode_declare_if_switch, /* START */
720 NULL, NULL,
721 NULL);
722
723 /* output tables where needed */
724 for (depth = gen_entry_depth (table);
725 depth > 0;
726 depth--)
727 {
728 gen_entry_traverse_tree (file, table,
729 1-depth,
730 print_idecode_table_start,
731 print_idecode_table_leaf,
732 print_idecode_table_end,
733 NULL);
734 }
735
736 /* output switch functions where needed */
737 gen_entry_traverse_tree (file, table,
738 1,
739 idecode_expand_if_switch, /* START */
740 NULL, NULL,
741 NULL);
742 }
743
744
745 void
746 print_idecode_body (lf *file,
747 gen_entry *table,
748 const char *result)
749 {
750 if (table->opcode_rule->gen == switch_gen
751 || table->opcode_rule->gen == goto_switch_gen
752 || table->opcode_rule->gen == padded_switch_gen)
753 {
754 print_idecode_switch (file, table, result);
755 }
756 else
757 {
758 print_idecode_table (file, table, result);
759 }
760 }
761
762
763 /****************************************************************/
764
765 #if 0
766 static void
767 print_jump (lf *file,
768 int is_tail)
769 {
770 if (is_tail)
771 {
772 lf_putstr (file, "if (keep_running != NULL && !*keep_running)\n");
773 lf_putstr (file, " cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n");
774 }
775
776 if (!options.generate_smp)
777 {
778 lf_putstr (file, "if (WITH_EVENTS) {\n");
779 lf_putstr (file, " if (event_queue_tick(events)) {\n");
780 lf_putstr (file, " cpu_set_program_counter(cpu, nia);\n");
781 lf_putstr (file, " event_queue_process(events);\n");
782 lf_putstr (file, " nia = cpu_get_program_counter(cpu);\n");
783 lf_putstr (file, " }\n");
784 lf_putstr (file, "}\n");
785 }
786
787 if (options.generate_smp)
788 {
789 if (is_tail)
790 {
791 lf_putstr (file, "cpu_set_program_counter(cpu, nia);\n");
792 }
793 lf_putstr (file, "if (WITH_EVENTS) {\n");
794 lf_putstr (file, " current_cpu += 1;\n");
795 lf_putstr (file, " if (current_cpu >= nr_cpus) {\n");
796 lf_putstr (file, " if (event_queue_tick(events)) {\n");
797 lf_putstr (file, " event_queue_process(events);\n");
798 lf_putstr (file, " }\n");
799 lf_putstr (file, " current_cpu = 0;\n");
800 lf_putstr (file, " }\n");
801 lf_putstr (file, "}\n");
802 lf_putstr (file, "else {\n");
803 lf_putstr (file, " current_cpu = (current_cpu + 1) % nr_cpus;\n");
804 lf_putstr (file, "}\n");
805 lf_putstr (file, "cpu = cpus[current_cpu];\n");
806 lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
807 }
808
809 if (options.gen.icache)
810 {
811 lf_putstr (file, "cache_entry = cpu_icache_entry(cpu, nia);\n");
812 lf_putstr (file, "if (cache_entry->address == nia) {\n");
813 lf_putstr (file, " /* cache hit */\n");
814 lf_putstr (file, " goto *cache_entry->semantic;\n");
815 lf_putstr (file, "}\n");
816 if (is_tail)
817 {
818 lf_putstr (file, "goto cache_miss;\n");
819 }
820 }
821
822 if (!options.gen.icache && is_tail)
823 {
824 lf_printf (file, "goto idecode;\n");
825 }
826
827 }
828 #endif
829
830
831
832 #if 0
833 static void
834 print_jump_insn (lf *file,
835 insn_entry *instruction,
836 insn_bits *expanded_bits,
837 opcode_field *opcodes,
838 cache_entry *cache_rules)
839 {
840
841 /* what we are for the moment */
842 lf_printf (file, "\n");
843 print_my_defines (file, expanded_bits, instruction->name);
844
845 /* output the icache entry */
846 if (options.gen.icache)
847 {
848 lf_printf (file, "\n");
849 lf_indent (file, -1);
850 print_function_name (file,
851 instruction->name,
852 expanded_bits,
853 function_name_prefix_icache);
854 lf_printf (file, ":\n");
855 lf_indent (file, +1);
856 lf_printf (file, "{\n");
857 lf_indent (file, +2);
858 lf_putstr (file, "const unsigned_word cia = nia;\n");
859 print_itrace (file, instruction, 1/*putting-value-in-cache*/);
860 print_idecode_validate (file, instruction, opcodes);
861 lf_printf (file, "\n");
862 lf_printf (file, "{\n");
863 lf_indent (file, +2);
864 print_icache_body (file,
865 instruction,
866 expanded_bits,
867 cache_rules,
868 0, /*use_defines*/
869 put_values_in_icache);
870 lf_printf (file, "cache_entry->address = nia;\n");
871 lf_printf (file, "cache_entry->semantic = &&");
872 print_function_name (file,
873 instruction->name,
874 expanded_bits,
875 function_name_prefix_semantics);
876 lf_printf (file, ";\n");
877 if (options.gen.semantic_icache)
878 {
879 print_semantic_body (file,
880 instruction,
881 expanded_bits,
882 opcodes);
883 print_jump (file, 1/*is-tail*/);
884 }
885 else
886 {
887 lf_printf (file, "/* goto ");
888 print_function_name (file,
889 instruction->name,
890 expanded_bits,
891 function_name_prefix_semantics);
892 lf_printf (file, "; */\n");
893 }
894 lf_indent (file, -2);
895 lf_putstr (file, "}\n");
896 lf_indent (file, -2);
897 lf_printf (file, "}\n");
898 }
899
900 /* print the semantics */
901 lf_printf (file, "\n");
902 lf_indent (file, -1);
903 print_function_name (file,
904 instruction->name,
905 expanded_bits,
906 function_name_prefix_semantics);
907 lf_printf (file, ":\n");
908 lf_indent (file, +1);
909 lf_printf (file, "{\n");
910 lf_indent (file, +2);
911 lf_putstr (file, "const unsigned_word cia = nia;\n");
912 print_icache_body (file,
913 instruction,
914 expanded_bits,
915 cache_rules,
916 (options.gen.direct_access
917 ? define_variables
918 : declare_variables),
919 (options.gen.icache
920 ? get_values_from_icache
921 : do_not_use_icache));
922 print_semantic_body (file,
923 instruction,
924 expanded_bits,
925 opcodes);
926 if (options.gen.direct_access)
927 print_icache_body (file,
928 instruction,
929 expanded_bits,
930 cache_rules,
931 undef_variables,
932 (options.gen.icache
933 ? get_values_from_icache
934 : do_not_use_icache));
935 print_jump (file, 1/*is tail*/);
936 lf_indent (file, -2);
937 lf_printf (file, "}\n");
938 }
939 #endif
940
941
942 #if 0
943 static void
944 print_jump_definition (lf *file,
945 gen_entry *entry,
946 insn_entry *insn,
947 int depth,
948 void *data)
949 {
950 cache_entry *cache_rules = (cache_entry*)data;
951 if (options.generate_expanded_instructions)
952 {
953 ASSERT (entry->nr_insns == 1
954 && entry->opcode == NULL
955 && entry->parent != NULL
956 && entry->parent->opcode != NULL);
957 ASSERT (entry->nr_insns == 1
958 && entry->opcode == NULL
959 && entry->parent != NULL
960 && entry->parent->opcode != NULL
961 && entry->parent->opcode_rule != NULL);
962 print_jump_insn (file,
963 entry->insns->words[0]->insn,
964 entry->expanded_bits,
965 entry->opcode,
966 cache_rules);
967 }
968 else
969 {
970 print_jump_insn (file,
971 instruction->words[0]->insn,
972 NULL,
973 NULL,
974 cache_rules);
975 }
976 }
977 #endif
978
979 #if 0
980 static void
981 print_jump_internal_function (lf *file,
982 gen_entry *table,
983 function_entry *function,
984 void *data)
985 {
986 if (function->is_internal)
987 {
988 lf_printf (file, "\n");
989 lf_print__line_ref (file, function->line);
990 lf_indent (file, -1);
991 print_function_name (file,
992 function->name,
993 NULL,
994 (options.gen.icache
995 ? function_name_prefix_icache
996 : function_name_prefix_semantics));
997 lf_printf (file, ":\n");
998 lf_indent (file, +1);
999 lf_printf (file, "{\n");
1000 lf_indent (file, +2);
1001 lf_printf (file, "const unsigned_word cia = nia;\n");
1002 table_print_code (file, function->code);
1003 lf_print__internal_ref (file);
1004 print_sim_engine_abort (file, "Internal function must longjump");
1005 lf_indent (file, -2);
1006 lf_printf (file, "}\n");
1007 }
1008 }
1009 #endif
1010
1011
1012
1013 #if 0
1014 static void
1015 print_jump_until_stop_body(lf *file,
1016 insn_table *table,
1017 cache_table *cache_rules)
1018 {
1019 lf_printf (file, "{\n");
1020 lf_indent (file, +2);
1021 lf_putstr (file, "jmp_buf halt;\n");
1022 lf_putstr (file, "jmp_buf restart;\n");
1023 lf_putstr (file, "sim_cpu *cpu = NULL;\n");
1024 lf_putstr (file, "unsigned_word nia = -1;\n");
1025 lf_putstr (file, "instruction_word instruction = 0;\n");
1026 if ((code & generate_with_icache)) {
1027 lf_putstr (file, "idecode_cache *cache_entry = NULL;\n");
1028 }
1029 if (generate_smp) {
1030 lf_putstr (file, "int current_cpu = -1;\n");
1031 }
1032
1033 /* all the switches and tables - they know about jumping */
1034 print_idecode_lookups(file, table, cache_rules);
1035
1036 /* start the simulation up */
1037 if ((code & generate_with_icache)) {
1038 lf_putstr (file, "\n");
1039 lf_putstr (file, "{\n");
1040 lf_putstr (file, " int cpu_nr;\n");
1041 lf_putstr (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
1042 lf_putstr (file, " cpu_flush_icache(cpus[cpu_nr]);\n");
1043 lf_putstr (file, "}\n");
1044 }
1045
1046 lf_putstr (file, "\n");
1047 lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
1048
1049 lf_putstr (file, "\n");
1050 lf_putstr (file, "if (setjmp(halt))\n");
1051 lf_putstr (file, " return;\n");
1052
1053 lf_putstr (file, "\n");
1054 lf_putstr (file, "setjmp(restart);\n");
1055
1056 lf_putstr (file, "\n");
1057 if (!generate_smp) {
1058 lf_putstr (file, "cpu = cpus[0];\n");
1059 lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
1060 }
1061 else {
1062 lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
1063 }
1064
1065 if (!(code & generate_with_icache)) {
1066 lf_printf (file, "\n");
1067 lf_indent (file, -1);
1068 lf_printf (file, "idecode:\n");
1069 lf_indent (file, +1);
1070 }
1071
1072 print_jump(file, 0/*is_tail*/);
1073
1074 if ((code & generate_with_icache)) {
1075 lf_indent (file, -1);
1076 lf_printf (file, "cache_miss:\n");
1077 lf_indent (file, +1);
1078 }
1079
1080 lf_putstr (file, "instruction\n");
1081 lf_putstr (file, " = vm_instruction_map_read(cpu_instruction_map(cpu),\n");
1082 lf_putstr (file, " cpu, nia);\n");
1083 print_idecode_body(file, table, "/*IGORE*/");
1084
1085 /* print out a table of all the internals functions */
1086 insn_table_traverse_function(table,
1087 file, NULL,
1088 print_jump_internal_function);
1089
1090 /* print out a table of all the instructions */
1091 if (generate_expanded_instructions)
1092 insn_table_traverse_tree(table,
1093 file, cache_rules,
1094 1,
1095 NULL, /* start */
1096 print_jump_definition, /* leaf */
1097 NULL, /* end */
1098 NULL); /* padding */
1099 else
1100 insn_table_traverse_insn(table,
1101 file, cache_rules,
1102 print_jump_definition);
1103 lf_indent (file, -2);
1104 lf_printf (file, "}\n");
1105 }
1106 #endif
1107
1108 /****************************************************************/
1109
1110
1111
1112 /* Output code to do any final checks on the decoded instruction.
1113 This includes things like verifying any on decoded fields have the
1114 correct value and checking that (for floating point) floating point
1115 hardware isn't disabled */
1116
1117 void
1118 print_idecode_validate (lf *file,
1119 insn_entry *instruction,
1120 insn_opcodes *opcode_paths)
1121 {
1122 /* Validate: unchecked instruction fields
1123
1124 If any constant fields in the instruction were not checked by the
1125 idecode tables, output code to check that they have the correct
1126 value here */
1127 {
1128 int nr_checks = 0;
1129 int word_nr;
1130 lf_printf (file, "\n");
1131 lf_indent_suppress (file);
1132 lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n");
1133 lf_printf (file, "/* validate: ");
1134 print_insn_words (file, instruction);
1135 lf_printf (file, " */\n");
1136 for (word_nr = 0; word_nr < instruction->nr_words; word_nr++)
1137 {
1138 insn_uint check_mask = 0;
1139 insn_uint check_val = 0;
1140 insn_word_entry *word = instruction->word[word_nr];
1141 int bit_nr;
1142
1143 /* form check_mask/check_val containing what needs to be checked
1144 in the instruction */
1145 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1146 {
1147 insn_bit_entry *bit = word->bit[bit_nr];
1148 insn_field_entry *field = bit->field;
1149
1150 /* Make space for the next bit */
1151 check_mask <<= 1;
1152 check_val <<= 1;
1153
1154 /* Only need to validate constant (and reserved)
1155 bits. Skip any others */
1156 if (field->type != insn_field_int
1157 && field->type != insn_field_reserved)
1158 continue;
1159
1160 /* Look through the list of opcode paths that lead to this
1161 instruction. See if any have failed to check the
1162 relevant bit */
1163 if (opcode_paths != NULL)
1164 {
1165 insn_opcodes *entry;
1166 for (entry = opcode_paths;
1167 entry != NULL;
1168 entry = entry->next)
1169 {
1170 opcode_field *opcode;
1171 for (opcode = entry->opcode;
1172 opcode != NULL;
1173 opcode = opcode->parent)
1174 {
1175 if (opcode->word_nr == word_nr
1176 && opcode->first <= bit_nr
1177 && opcode->last >= bit_nr)
1178 /* we've decoded on this bit */
1179 break;
1180 }
1181 if (opcode == NULL)
1182 /* the bit wasn't decoded on */
1183 break;
1184 }
1185 if (entry == NULL)
1186 /* all the opcode paths decoded on BIT_NR, no need
1187 to check it */
1188 continue;
1189 }
1190
1191 check_mask |= 1;
1192 check_val |= bit->value;
1193 }
1194
1195 /* if any bits not checked by opcode tables, output code to check them */
1196 if (check_mask)
1197 {
1198 if (nr_checks == 0)
1199 {
1200 lf_printf (file, "if (WITH_RESERVED_BITS)\n");
1201 lf_printf (file, " {\n");
1202 lf_indent (file, +4);
1203 }
1204 nr_checks ++;
1205 if (options.insn_bit_size > 32)
1206 {
1207 lf_printf (file, "if ((instruction_%d\n", word_nr);
1208 lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n",
1209 (unsigned long)(check_mask >> 32),
1210 (unsigned long)(check_mask));
1211 lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n",
1212 (unsigned long)(check_val >> 32),
1213 (unsigned long)(check_val));
1214 }
1215 else
1216 {
1217 lf_printf (file, "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
1218 word_nr,
1219 (unsigned long)(check_mask),
1220 (unsigned long)(check_val));
1221 }
1222 lf_indent (file, +2);
1223 print_idecode_invalid (file, "return", invalid_illegal);
1224 lf_indent (file, -2);
1225 }
1226 }
1227 if (nr_checks > 0)
1228 {
1229 lf_indent (file, -4);
1230 lf_printf (file, " }\n");
1231 }
1232 lf_indent_suppress(file);
1233 lf_printf (file, "#endif\n");
1234 }
1235
1236 /* Validate: Floating Point hardware
1237
1238 If the simulator is being built with out floating point hardware
1239 (different to it being disabled in the MSR) then floating point
1240 instructions are invalid */
1241 {
1242 if (filter_is_member (instruction->flags, "f"))
1243 {
1244 lf_printf (file, "\n");
1245 lf_indent_suppress (file);
1246 lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");
1247 lf_printf (file, "/* Validate: FP hardware exists */\n");
1248 lf_printf (file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
1249 lf_indent (file, +2);
1250 print_idecode_invalid (file, "return", invalid_illegal);
1251 lf_indent (file, -2);
1252 lf_printf (file, "}\n");
1253 lf_indent_suppress (file);
1254 lf_printf (file, "#endif\n");
1255 }
1256 }
1257
1258 /* Validate: Floating Point available
1259
1260 If floating point is not available, we enter a floating point
1261 unavailable interrupt into the cache instead of the instruction
1262 proper.
1263
1264 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1265 ever a CSI occures we flush the instruction cache. */
1266
1267 {
1268 if (filter_is_member (instruction->flags, "f"))
1269 {
1270 lf_printf (file, "\n");
1271 lf_indent_suppress (file);
1272 lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n");
1273 lf_printf (file, "/* Validate: FP available according to cpu */\n");
1274 lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");
1275 lf_indent (file, +2);
1276 print_idecode_invalid (file, "return", invalid_fp_unavailable);
1277 lf_indent (file, -2);
1278 lf_printf (file, "}\n");
1279 lf_indent_suppress (file);
1280 lf_printf (file, "#endif\n");
1281 }
1282 }
1283
1284 /* Validate: Validate Instruction in correct slot
1285
1286 Some architectures place restrictions on the slot that an
1287 instruction can be issued in */
1288
1289 {
1290 if (filter_is_member (instruction->options, "s")
1291 || options.gen.slot_verification)
1292 {
1293 lf_printf (file, "\n");
1294 lf_indent_suppress (file);
1295 lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");
1296 lf_printf (file, "/* Validate: Instruction issued in correct slot */\n");
1297 lf_printf (file, "if (IS_WRONG_SLOT) {\n");
1298 lf_indent (file, +2);
1299 print_idecode_invalid (file, "return", invalid_wrong_slot);
1300 lf_indent (file, -2);
1301 lf_printf (file, "}\n");
1302 lf_indent_suppress (file);
1303 lf_printf (file, "#endif\n");
1304 }
1305 }
1306
1307 }
1308
1309
1310 /****************************************************************/
1311
1312
1313 void
1314 print_idecode_issue_function_header (lf *file,
1315 const char *processor,
1316 function_decl_type decl_type,
1317 int nr_prefetched_words)
1318 {
1319 int indent;
1320 lf_printf (file, "\n");
1321 switch (decl_type)
1322 {
1323 case is_function_declaration:
1324 lf_print__function_type_function (file, print_semantic_function_type,
1325 "INLINE_IDECODE",
1326 " ");
1327 break;
1328 case is_function_definition:
1329 lf_print__function_type_function (file, print_semantic_function_type,
1330 "INLINE_IDECODE",
1331 "\n");
1332 break;
1333 case is_function_variable:
1334 print_semantic_function_type (file);
1335 lf_printf (file, " (*");
1336 break;
1337 }
1338 indent = print_function_name (file,
1339 "issue",
1340 NULL,
1341 processor,
1342 NULL,
1343 function_name_prefix_idecode);
1344 switch (decl_type)
1345 {
1346 case is_function_definition:
1347 indent += lf_printf (file, " (");
1348 break;
1349 case is_function_declaration:
1350 lf_putstr (file, "\n(");
1351 indent = 1;
1352 break;
1353 case is_function_variable:
1354 lf_putstr (file, ")\n(");
1355 indent = 1;
1356 break;
1357 }
1358 lf_indent (file, +indent);
1359 print_semantic_function_formal (file, nr_prefetched_words);
1360 lf_putstr (file, ")");
1361 lf_indent (file, -indent);
1362 switch (decl_type)
1363 {
1364 case is_function_definition:
1365 lf_printf (file, "\n");
1366 break;
1367 case is_function_declaration:
1368 case is_function_variable:
1369 lf_putstr (file, ";\n");
1370 break;
1371 }
1372 }
1373
1374
1375
1376 void
1377 print_idecode_globals (lf *file)
1378 {
1379 lf_printf (file, "enum {\n");
1380 lf_printf (file, " /* greater or equal to zero => table */\n");
1381 lf_printf (file, " function_entry = -1,\n");
1382 lf_printf (file, " boolean_entry = -2,\n");
1383 lf_printf (file, "};\n");
1384 lf_printf (file, "\n");
1385 lf_printf (file, "typedef struct _idecode_table_entry {\n");
1386 lf_printf (file, " int shift;\n");
1387 lf_printf (file, " unsigned%d mask;\n", options.insn_bit_size);
1388 lf_printf (file, " unsigned%d value;\n", options.insn_bit_size);
1389 lf_printf (file, " void *function_or_table;\n");
1390 lf_printf (file, "} idecode_table_entry;\n");
1391 }