]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/igen/gen-idecode.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / sim / igen / gen-idecode.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3 Copyright 2002-2023 Free Software Foundation, Inc.
4
5 Contributed by Andrew Cagney.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22
23 #include "misc.h"
24 #include "lf.h"
25 #include "table.h"
26 #include "filter.h"
27 #include "igen.h"
28
29 #include "ld-insn.h"
30 #include "ld-decode.h"
31
32 #include "gen.h"
33
34 #include "gen-idecode.h"
35 #include "gen-icache.h"
36 #include "gen-semantics.h"
37
38
39
40 static void
41 lf_print_opcodes (lf *file, const gen_entry *table)
42 {
43 if (table !=NULL)
44 {
45 while (1)
46 {
47 ASSERT (table->opcode != NULL);
48 lf_printf (file, "_%d_%d",
49 table->opcode->first, table->opcode->last);
50 if (table->parent == NULL)
51 break;
52 lf_printf (file, "__%d", table->opcode_nr);
53 table = table->parent;
54 }
55 }
56 }
57
58
59
60
61 static void
62 print_idecode_ifetch (lf *file,
63 int previous_nr_prefetched_words,
64 int current_nr_prefetched_words)
65 {
66 int word_nr;
67 for (word_nr = previous_nr_prefetched_words;
68 word_nr < current_nr_prefetched_words; word_nr++)
69 {
70 lf_printf (file,
71 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
72 word_nr, options.insn_bit_size, word_nr);
73
74 }
75 }
76
77
78
79 /****************************************************************/
80
81
82 static void
83 lf_print_table_name (lf *file, const 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, const gen_entry *entry, const char *result)
93 {
94 lf_printf (file, "/* prime the search */\n");
95 lf_printf (file, "idecode_table_entry *table = ");
96 lf_print_table_name (file, entry);
97 lf_printf (file, ";\n");
98 lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n",
99 options.insn_bit_size,
100 i2target (options.hi_bit_nr, entry->opcode->first),
101 i2target (options.hi_bit_nr, entry->opcode->last));
102 lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");
103
104 lf_printf (file, "\n");
105 lf_printf (file, "/* iterate until a leaf */\n");
106 lf_printf (file, "while (1) {\n");
107 lf_printf (file, " signed shift = table_entry->shift;\n");
108 lf_printf (file, "if (shift == function_entry) break;\n");
109 lf_printf (file, " if (shift >= 0) {\n");
110 lf_printf (file, " table = ((idecode_table_entry*)\n");
111 lf_printf (file, " table_entry->function_or_table);\n");
112 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
113 lf_printf (file, " >> shift);\n");
114 lf_printf (file, " table_entry = table + opcode;\n");
115 lf_printf (file, " }\n");
116 lf_printf (file, " else {\n");
117 lf_printf (file, " /* must be a boolean */\n");
118 lf_printf (file, " ASSERT(table_entry->shift == boolean_entry);\n");
119 lf_printf (file, " opcode = ((instruction & table_entry->mask)\n");
120 lf_printf (file, " != table_entry->value);\n");
121 lf_printf (file, " table = ((idecode_table_entry*)\n");
122 lf_printf (file, " table_entry->function_or_table);\n");
123 lf_printf (file, " table_entry = table + opcode;\n");
124 lf_printf (file, " }\n");
125 lf_printf (file, "}\n");
126
127 lf_printf (file, "\n");
128 lf_printf (file, "/* call the leaf code */\n");
129 if (options.gen.code == generate_jumps)
130 {
131 lf_printf (file, "goto *table_entry->function_or_table;\n");
132 }
133 else
134 {
135 lf_printf (file, "%s ", result);
136 if (options.gen.icache)
137 {
138 lf_printf (file,
139 "(((idecode_icache*)table_entry->function_or_table)\n");
140 lf_printf (file, " (");
141 print_icache_function_actual (file, 1);
142 lf_printf (file, "));\n");
143 }
144 else
145 {
146 lf_printf (file,
147 "((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 const gen_entry *table, int depth, void *data)
159 {
160 ASSERT (depth == 0);
161 /* start of the table */
162 if (table->opcode_rule->gen == array_gen)
163 {
164 lf_printf (file, "\n");
165 lf_printf (file, "static idecode_table_entry ");
166 lf_print_table_name (file, table);
167 lf_printf (file, "[] = {\n");
168 }
169 }
170
171 static void
172 print_idecode_table_leaf (lf *file,
173 const gen_entry *entry, int depth, void *data)
174 {
175 const gen_entry *master_entry;
176 ASSERT (entry->parent != NULL);
177 ASSERT (depth == 0);
178 if (entry->combined_parent == NULL)
179 master_entry = entry;
180 else
181 master_entry = entry->combined_parent;
182
183 /* add an entry to the table */
184 if (entry->parent->opcode_rule->gen == array_gen)
185 {
186 lf_printf (file, " /*%d*/ { ", entry->opcode_nr);
187 if (entry->opcode == NULL)
188 {
189 ASSERT (entry->nr_insns == 1);
190 /* table leaf entry */
191 lf_printf (file, "function_entry, 0, 0, ");
192 if (options.gen.code == generate_jumps)
193 {
194 lf_printf (file, "&&");
195 }
196 print_function_name (file,
197 entry->insns->insn->name,
198 entry->insns->insn->format_name,
199 NULL,
200 master_entry->expanded_bits,
201 (options.gen.icache
202 ? function_name_prefix_icache
203 : function_name_prefix_semantics));
204 }
205 else if (entry->opcode_rule->gen == switch_gen
206 || entry->opcode_rule->gen == goto_switch_gen
207 || entry->opcode_rule->gen == padded_switch_gen)
208 {
209 /* table calling switch statement */
210 lf_printf (file, "function_entry, 0, 0, ");
211 if (options.gen.code == generate_jumps)
212 {
213 lf_printf (file, "&&");
214 }
215 lf_print_table_name (file, entry);
216 }
217 else if (entry->opcode->is_boolean)
218 {
219 /* table `calling' boolean table */
220 lf_printf (file, "boolean_entry, ");
221 lf_printf (file, "MASK32(%d, %d), ",
222 i2target (options.hi_bit_nr, entry->opcode->first),
223 i2target (options.hi_bit_nr, entry->opcode->last));
224 lf_printf (file, "INSERTED32(%d, %d, %d), ",
225 entry->opcode->boolean_constant,
226 i2target (options.hi_bit_nr, entry->opcode->first),
227 i2target (options.hi_bit_nr, entry->opcode->last));
228 lf_print_table_name (file, entry);
229 }
230 else
231 {
232 /* table `calling' another table */
233 lf_printf (file, "%d, ",
234 options.insn_bit_size - entry->opcode->last - 1);
235 lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size,
236 i2target (options.hi_bit_nr, entry->opcode->first),
237 i2target (options.hi_bit_nr, entry->opcode->last));
238 lf_printf (file, "0, ");
239 lf_print_table_name (file, entry);
240 }
241 lf_printf (file, " },\n");
242 }
243 }
244
245 static void
246 print_idecode_table_end (lf *file,
247 const gen_entry *table, int depth, void *data)
248 {
249 ASSERT (depth == 0);
250 if (table->opcode_rule->gen == array_gen)
251 {
252 lf_printf (file, "};\n");
253 }
254 }
255
256 /****************************************************************/
257
258
259 static void
260 print_goto_switch_name (lf *file, const gen_entry *entry)
261 {
262 lf_printf (file, "case_");
263 if (entry->opcode == NULL)
264 {
265 print_function_name (file,
266 entry->insns->insn->name,
267 entry->insns->insn->format_name,
268 NULL,
269 entry->expanded_bits,
270 (options.gen.icache
271 ? function_name_prefix_icache
272 : function_name_prefix_semantics));
273 }
274 else
275 {
276 lf_print_table_name (file, entry);
277 }
278 }
279
280 static void
281 print_goto_switch_table_leaf (lf *file,
282 const gen_entry *entry, int depth, void *data)
283 {
284 ASSERT (entry->parent != NULL);
285 ASSERT (depth == 0);
286 ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);
287 ASSERT (entry->parent->opcode);
288
289 lf_printf (file, "/* %d */ &&", entry->opcode_nr);
290 if (entry->combined_parent != NULL)
291 print_goto_switch_name (file, entry->combined_parent);
292 else
293 print_goto_switch_name (file, entry);
294 lf_printf (file, ",\n");
295 }
296
297 static void
298 print_goto_switch_break (lf *file, const gen_entry *entry)
299 {
300 lf_printf (file, "goto break_");
301 lf_print_table_name (file, entry->parent);
302 lf_printf (file, ";\n");
303 }
304
305
306 static void
307 print_goto_switch_table (lf *file, const gen_entry *table)
308 {
309 lf_printf (file, "const static void *");
310 lf_print_table_name (file, table);
311 lf_printf (file, "[] = {\n");
312 lf_indent (file, +2);
313 gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,
314 print_goto_switch_table_leaf, NULL /*end */ ,
315 NULL /*data */ );
316 lf_indent (file, -2);
317 lf_printf (file, "};\n");
318 }
319
320
321 void print_idecode_switch
322 (lf *file, const gen_entry *table, const char *result);
323
324 static void
325 print_idecode_switch_start (lf *file,
326 const gen_entry *table, int depth, void *data)
327 {
328 /* const char *result = data; */
329 ASSERT (depth == 0);
330 ASSERT (table->opcode_rule->gen == switch_gen
331 || table->opcode_rule->gen == goto_switch_gen
332 || table->opcode_rule->gen == padded_switch_gen);
333
334 if (table->opcode->is_boolean
335 || table->opcode_rule->gen == switch_gen
336 || table->opcode_rule->gen == padded_switch_gen)
337 {
338 lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n",
339 options.insn_bit_size,
340 table->opcode_rule->word_nr,
341 i2target (options.hi_bit_nr, table->opcode->first),
342 i2target (options.hi_bit_nr, table->opcode->last));
343 lf_indent (file, +2);
344 lf_printf (file, "{\n");
345 }
346 else if (table->opcode_rule->gen == goto_switch_gen)
347 {
348 if (table->parent != NULL
349 && (table->parent->opcode_rule->gen == switch_gen
350 || table->parent->opcode_rule->gen == goto_switch_gen
351 || table->parent->opcode_rule->gen == padded_switch_gen))
352 {
353 lf_printf (file, "{\n");
354 lf_indent (file, +2);
355 }
356 print_goto_switch_table (file, table);
357 lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n",
358 options.insn_bit_size,
359 table->opcode->word_nr,
360 i2target (options.hi_bit_nr, table->opcode->first),
361 i2target (options.hi_bit_nr, table->opcode->last));
362 lf_printf (file, " < (sizeof (");
363 lf_print_table_name (file, table);
364 lf_printf (file, ") / sizeof(void*)));\n");
365 lf_printf (file, "goto *");
366 lf_print_table_name (file, table);
367 lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n",
368 options.insn_bit_size,
369 table->opcode->word_nr,
370 i2target (options.hi_bit_nr, table->opcode->first),
371 i2target (options.hi_bit_nr, table->opcode->last));
372 }
373 else
374 {
375 ASSERT ("bad switch" == NULL);
376 }
377 }
378
379
380 static void
381 print_idecode_switch_leaf (lf *file,
382 const gen_entry *entry, int depth, void *data)
383 {
384 const char *result = data;
385 ASSERT (entry->parent != NULL);
386 ASSERT (depth == 0);
387 ASSERT (entry->parent->opcode_rule->gen == switch_gen
388 || entry->parent->opcode_rule->gen == goto_switch_gen
389 || entry->parent->opcode_rule->gen == padded_switch_gen);
390 ASSERT (entry->parent->opcode);
391
392 /* skip over any instructions combined into another entry */
393 if (entry->combined_parent != NULL)
394 return;
395
396 if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)
397 {
398 /* case: boolean false target */
399 lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
400 }
401 else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)
402 {
403 /* case: boolean true case */
404 lf_printf (file, "default:\n");
405 }
406 else if (entry->parent->opcode_rule->gen == switch_gen
407 || entry->parent->opcode_rule->gen == padded_switch_gen)
408 {
409 /* case: <opcode-nr> - switch */
410 const gen_entry *cob;
411 for (cob = entry; cob != NULL; cob = cob->combined_next)
412 lf_printf (file, "case %d:\n", cob->opcode_nr);
413 }
414 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
415 {
416 /* case: <opcode-nr> - goto-switch */
417 print_goto_switch_name (file, entry);
418 lf_printf (file, ":\n");
419 }
420 else
421 {
422 ERROR ("bad switch");
423 }
424 lf_printf (file, " {\n");
425 lf_indent (file, +4);
426 {
427 if (entry->opcode == NULL)
428 {
429 /* switch calling leaf */
430 ASSERT (entry->nr_insns == 1);
431 print_idecode_ifetch (file, entry->nr_prefetched_words,
432 entry->insns->semantic->nr_prefetched_words);
433 switch (options.gen.code)
434 {
435 case generate_jumps:
436 lf_printf (file, "goto ");
437 break;
438 case generate_calls:
439 lf_printf (file, "%s", result);
440 break;
441 }
442 print_function_name (file,
443 entry->insns->insn->name,
444 entry->insns->insn->format_name,
445 NULL,
446 entry->expanded_bits,
447 (options.gen.icache
448 ? function_name_prefix_icache
449 : function_name_prefix_semantics));
450 if (options.gen.code == generate_calls)
451 {
452 lf_printf (file, " (");
453 print_semantic_function_actual (file,
454 entry->insns->semantic->
455 nr_prefetched_words);
456 lf_printf (file, ")");
457 }
458 lf_printf (file, ";\n");
459 }
460 else if (entry->opcode_rule->gen == switch_gen
461 || entry->opcode_rule->gen == goto_switch_gen
462 || entry->opcode_rule->gen == padded_switch_gen)
463 {
464 /* switch calling switch */
465 lf_printf (file, "{\n");
466 lf_indent (file, +2);
467 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
468 entry->nr_prefetched_words);
469 print_idecode_switch (file, entry, result);
470 lf_indent (file, -2);
471 lf_printf (file, "}\n");
472 }
473 else
474 {
475 /* switch looking up a table */
476 lf_printf (file, "{\n");
477 lf_indent (file, +2);
478 print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
479 entry->nr_prefetched_words);
480 print_idecode_table (file, entry, result);
481 lf_indent (file, -2);
482 lf_printf (file, "}\n");
483 }
484 if (entry->parent->opcode->is_boolean
485 || entry->parent->opcode_rule->gen == switch_gen
486 || entry->parent->opcode_rule->gen == padded_switch_gen)
487 {
488 lf_printf (file, "break;\n");
489 }
490 else if (entry->parent->opcode_rule->gen == goto_switch_gen)
491 {
492 print_goto_switch_break (file, entry);
493 }
494 else
495 {
496 ERROR ("bad switch");
497 }
498 }
499 lf_indent (file, -4);
500 lf_printf (file, " }\n");
501 }
502
503
504 static void
505 print_idecode_switch_illegal (lf *file, const char *result)
506 {
507 lf_indent (file, +2);
508 print_idecode_invalid (file, result, invalid_illegal);
509 lf_printf (file, "break;\n");
510 lf_indent (file, -2);
511 }
512
513 static void
514 print_idecode_switch_end (lf *file,
515 const gen_entry *table, int depth, void *data)
516 {
517 const char *result = data;
518 ASSERT (depth == 0);
519 ASSERT (table->opcode_rule->gen == switch_gen
520 || table->opcode_rule->gen == goto_switch_gen
521 || table->opcode_rule->gen == padded_switch_gen);
522 ASSERT (table->opcode);
523
524 if (table->opcode->is_boolean)
525 {
526 lf_printf (file, "}\n");
527 lf_indent (file, -2);
528 }
529 else if (table->opcode_rule->gen == switch_gen
530 || table->opcode_rule->gen == padded_switch_gen)
531 {
532 lf_printf (file, "default:\n");
533 lf_indent (file, +2);
534 if (table->nr_entries == table->opcode->nr_opcodes)
535 {
536 print_sim_engine_abort (file,
537 "Internal error - bad switch generated");
538 lf_printf (file, "%sNULL_CIA;\n", result);
539 lf_printf (file, "break;\n");
540 }
541 else
542 {
543 print_idecode_switch_illegal (file, result);
544 }
545 lf_indent (file, -2);
546 lf_printf (file, "}\n");
547 lf_indent (file, -2);
548 }
549 else if (table->opcode_rule->gen == goto_switch_gen)
550 {
551 lf_printf (file, "illegal_");
552 lf_print_table_name (file, table);
553 lf_printf (file, ":\n");
554 print_idecode_invalid (file, result, invalid_illegal);
555 lf_printf (file, "break_");
556 lf_print_table_name (file, table);
557 lf_printf (file, ":;\n");
558 if (table->parent != NULL
559 && (table->parent->opcode_rule->gen == switch_gen
560 || table->parent->opcode_rule->gen == goto_switch_gen
561 || table->parent->opcode_rule->gen == padded_switch_gen))
562 {
563 lf_indent (file, -2);
564 lf_printf (file, "}\n");
565 }
566 }
567 else
568 {
569 ERROR ("bad switch");
570 }
571 }
572
573
574 void
575 print_idecode_switch (lf *file, const gen_entry *table, const char *result)
576 {
577 gen_entry_traverse_tree (file, table,
578 0,
579 print_idecode_switch_start,
580 print_idecode_switch_leaf,
581 print_idecode_switch_end, (void *) result);
582 }
583
584
585 static void
586 print_idecode_switch_function_header (lf *file,
587 const gen_entry *table,
588 int is_function_definition,
589 int nr_prefetched_words)
590 {
591 lf_printf (file, "\n");
592 if (options.gen.code == generate_calls)
593 {
594 lf_printf (file, "static ");
595 if (options.gen.icache)
596 {
597 lf_printf (file, "idecode_semantic *");
598 }
599 else
600 {
601 lf_printf (file, "unsigned_word");
602 }
603 if (is_function_definition)
604 {
605 lf_printf (file, "\n");
606 }
607 else
608 {
609 lf_printf (file, " ");
610 }
611 lf_print_table_name (file, table);
612 lf_printf (file, "\n(");
613 print_icache_function_formal (file, nr_prefetched_words);
614 lf_printf (file, ")");
615 if (!is_function_definition)
616 {
617 lf_printf (file, ";");
618 }
619 lf_printf (file, "\n");
620 }
621 if (options.gen.code == generate_jumps && is_function_definition)
622 {
623 lf_indent (file, -1);
624 lf_print_table_name (file, table);
625 lf_printf (file, ":\n");
626 lf_indent (file, +1);
627 }
628 }
629
630
631 static void
632 idecode_declare_if_switch (lf *file,
633 const gen_entry *table, int depth, void *data)
634 {
635 if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't declare the top one yet */
636 && table->parent->opcode_rule->gen == array_gen)
637 {
638 print_idecode_switch_function_header (file,
639 table,
640 0 /*isnt function definition */ ,
641 0);
642 }
643 }
644
645
646 static void
647 idecode_expand_if_switch (lf *file,
648 const gen_entry *table, int depth, void *data)
649 {
650 if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't expand the top one yet */
651 && table->parent->opcode_rule->gen == array_gen)
652 {
653 print_idecode_switch_function_header (file,
654 table,
655 1 /*is function definition */ ,
656 0);
657 if (options.gen.code == generate_calls)
658 {
659 lf_printf (file, "{\n");
660 lf_indent (file, +2);
661 }
662 print_idecode_switch (file, table, "return");
663 if (options.gen.code == generate_calls)
664 {
665 lf_indent (file, -2);
666 lf_printf (file, "}\n");
667 }
668 }
669 }
670
671
672 /****************************************************************/
673
674
675 void
676 print_idecode_lookups (lf *file,
677 const gen_entry *table,
678 cache_entry *cache_rules)
679 {
680 int depth;
681
682 /* output switch function declarations where needed by tables */
683 gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */
684 NULL, NULL, NULL);
685
686 /* output tables where needed */
687 for (depth = gen_entry_depth (table); depth > 0; depth--)
688 {
689 gen_entry_traverse_tree (file, table,
690 1 - depth,
691 print_idecode_table_start,
692 print_idecode_table_leaf,
693 print_idecode_table_end, NULL);
694 }
695
696 /* output switch functions where needed */
697 gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */
698 NULL, NULL, NULL);
699 }
700
701
702 void
703 print_idecode_body (lf *file, const gen_entry *table, const char *result)
704 {
705 if (table->opcode_rule->gen == switch_gen
706 || table->opcode_rule->gen == goto_switch_gen
707 || table->opcode_rule->gen == padded_switch_gen)
708 {
709 print_idecode_switch (file, table, result);
710 }
711 else
712 {
713 print_idecode_table (file, table, result);
714 }
715 }
716
717
718 /****************************************************************/
719
720 /* Output code to do any final checks on the decoded instruction.
721 This includes things like verifying any on decoded fields have the
722 correct value and checking that (for floating point) floating point
723 hardware isn't disabled */
724
725 void
726 print_idecode_validate (lf *file,
727 const insn_entry *instruction,
728 const insn_opcodes *opcode_paths)
729 {
730 /* Validate: unchecked instruction fields
731
732 If any constant fields in the instruction were not checked by the
733 idecode tables, output code to check that they have the correct
734 value here */
735 {
736 int nr_checks = 0;
737 int word_nr;
738 lf_printf (file, "\n");
739 lf_indent_suppress (file);
740 lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n");
741 lf_printf (file, "/* validate: ");
742 print_insn_words (file, instruction);
743 lf_printf (file, " */\n");
744 for (word_nr = 0; word_nr < instruction->nr_words; word_nr++)
745 {
746 insn_uint check_mask = 0;
747 insn_uint check_val = 0;
748 insn_word_entry *word = instruction->word[word_nr];
749 int bit_nr;
750
751 /* form check_mask/check_val containing what needs to be checked
752 in the instruction */
753 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
754 {
755 insn_bit_entry *bit = word->bit[bit_nr];
756 insn_field_entry *field = bit->field;
757
758 /* Make space for the next bit */
759 check_mask <<= 1;
760 check_val <<= 1;
761
762 /* Only need to validate constant (and reserved)
763 bits. Skip any others */
764 if (field->type != insn_field_int
765 && field->type != insn_field_reserved
766 /* Consider a named field equal to a value to be just as
767 constant as an integer field. */
768 && (field->type != insn_field_string
769 || field->conditions == NULL
770 || field->conditions->test != insn_field_cond_eq
771 || field->conditions->type != insn_field_cond_value))
772 continue;
773
774 /* Look through the list of opcode paths that lead to this
775 instruction. See if any have failed to check the
776 relevant bit */
777 if (opcode_paths != NULL)
778 {
779 const insn_opcodes *entry;
780 for (entry = opcode_paths; entry != NULL; entry = entry->next)
781 {
782 opcode_field *opcode;
783 for (opcode = entry->opcode;
784 opcode != NULL; opcode = opcode->parent)
785 {
786 if (opcode->word_nr == word_nr
787 && opcode->first <= bit_nr
788 && opcode->last >= bit_nr)
789 /* we've decoded on this bit */
790 break;
791 }
792 if (opcode == NULL)
793 /* the bit wasn't decoded on */
794 break;
795 }
796 if (entry == NULL)
797 /* all the opcode paths decoded on BIT_NR, no need
798 to check it */
799 continue;
800 }
801
802 check_mask |= 1;
803 check_val |= bit->value;
804 }
805
806 /* if any bits not checked by opcode tables, output code to check them */
807 if (check_mask)
808 {
809 if (nr_checks == 0)
810 {
811 lf_printf (file, "if (WITH_RESERVED_BITS)\n");
812 lf_printf (file, " {\n");
813 lf_indent (file, +4);
814 }
815 nr_checks++;
816 if (options.insn_bit_size > 32)
817 {
818 lf_printf (file, "if ((instruction_%d\n", word_nr);
819 lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n",
820 (unsigned long) (check_mask >> 32),
821 (unsigned long) (check_mask));
822 lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n",
823 (unsigned long) (check_val >> 32),
824 (unsigned long) (check_val));
825 }
826 else
827 {
828 lf_printf (file,
829 "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
830 word_nr, (unsigned long) (check_mask),
831 (unsigned long) (check_val));
832 }
833 lf_indent (file, +2);
834 print_idecode_invalid (file, "return", invalid_illegal);
835 lf_indent (file, -2);
836 }
837 }
838 if (nr_checks > 0)
839 {
840 lf_indent (file, -4);
841 lf_printf (file, " }\n");
842 }
843 lf_indent_suppress (file);
844 lf_printf (file, "#endif\n");
845 }
846
847 /* Validate: Floating Point hardware
848
849 If the simulator is being built with out floating point hardware
850 (different to it being disabled in the MSR) then floating point
851 instructions are invalid */
852 {
853 if (filter_is_member (instruction->flags, "f"))
854 {
855 lf_printf (file, "\n");
856 lf_indent_suppress (file);
857 lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");
858 lf_printf (file, "/* Validate: FP hardware exists */\n");
859 lf_printf (file,
860 "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
861 lf_indent (file, +2);
862 print_idecode_invalid (file, "return", invalid_illegal);
863 lf_indent (file, -2);
864 lf_printf (file, "}\n");
865 lf_indent_suppress (file);
866 lf_printf (file, "#endif\n");
867 }
868 }
869
870 /* Validate: Floating Point available
871
872 If floating point is not available, we enter a floating point
873 unavailable interrupt into the cache instead of the instruction
874 proper.
875
876 The PowerPC spec requires a CSI after MSR[FP] is changed and when
877 ever a CSI occures we flush the instruction cache. */
878
879 {
880 if (filter_is_member (instruction->flags, "f"))
881 {
882 lf_printf (file, "\n");
883 lf_indent_suppress (file);
884 lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n");
885 lf_printf (file, "/* Validate: FP available according to cpu */\n");
886 lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");
887 lf_indent (file, +2);
888 print_idecode_invalid (file, "return", invalid_fp_unavailable);
889 lf_indent (file, -2);
890 lf_printf (file, "}\n");
891 lf_indent_suppress (file);
892 lf_printf (file, "#endif\n");
893 }
894 }
895
896 /* Validate: Validate Instruction in correct slot
897
898 Some architectures place restrictions on the slot that an
899 instruction can be issued in */
900
901 {
902 if (filter_is_member (instruction->options, "s")
903 || options.gen.slot_verification)
904 {
905 lf_printf (file, "\n");
906 lf_indent_suppress (file);
907 lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");
908 lf_printf (file,
909 "/* Validate: Instruction issued in correct slot */\n");
910 lf_printf (file, "if (IS_WRONG_SLOT) {\n");
911 lf_indent (file, +2);
912 print_idecode_invalid (file, "return", invalid_wrong_slot);
913 lf_indent (file, -2);
914 lf_printf (file, "}\n");
915 lf_indent_suppress (file);
916 lf_printf (file, "#endif\n");
917 }
918 }
919
920 }
921
922
923 /****************************************************************/
924
925
926 void
927 print_idecode_issue_function_header (lf *file,
928 const char *processor,
929 function_decl_type decl_type,
930 int nr_prefetched_words)
931 {
932 int indent;
933 lf_printf (file, "\n");
934 switch (decl_type)
935 {
936 case is_function_declaration:
937 lf_print__function_type_function (file, print_semantic_function_type,
938 "INLINE_IDECODE", " ");
939 break;
940 case is_function_definition:
941 lf_print__function_type_function (file, print_semantic_function_type,
942 "INLINE_IDECODE", "\n");
943 break;
944 case is_function_variable:
945 if (lf_get_file_type (file) == lf_is_h)
946 lf_printf (file, "extern ");
947 print_semantic_function_type (file);
948 lf_printf (file, " (*");
949 break;
950 }
951 indent = print_function_name (file,
952 "issue",
953 NULL,
954 processor,
955 NULL, function_name_prefix_idecode);
956 switch (decl_type)
957 {
958 case is_function_definition:
959 indent += lf_printf (file, " (");
960 break;
961 case is_function_declaration:
962 lf_putstr (file, "\n(");
963 indent = 1;
964 break;
965 case is_function_variable:
966 lf_putstr (file, ")\n(");
967 indent = 1;
968 break;
969 }
970 lf_indent (file, +indent);
971 print_semantic_function_formal (file, nr_prefetched_words);
972 lf_putstr (file, ")");
973 lf_indent (file, -indent);
974 switch (decl_type)
975 {
976 case is_function_definition:
977 lf_printf (file, "\n");
978 break;
979 case is_function_declaration:
980 case is_function_variable:
981 lf_putstr (file, ";\n");
982 break;
983 }
984 }
985
986
987
988 void
989 print_idecode_globals (lf *file)
990 {
991 lf_printf (file, "enum {\n");
992 lf_printf (file, " /* greater or equal to zero => table */\n");
993 lf_printf (file, " function_entry = -1,\n");
994 lf_printf (file, " boolean_entry = -2,\n");
995 lf_printf (file, "};\n");
996 lf_printf (file, "\n");
997 lf_printf (file, "typedef struct _idecode_table_entry {\n");
998 lf_printf (file, " int shift;\n");
999 lf_printf (file, " uint%d_t mask;\n", options.insn_bit_size);
1000 lf_printf (file, " uint%d_t value;\n", options.insn_bit_size);
1001 lf_printf (file, " void *function_or_table;\n");
1002 lf_printf (file, "} idecode_table_entry;\n");
1003 }