1 /* The IGEN simulator generator for GDB, the GNU Debugger.
3 Copyright 2002-2024 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney.
7 This file is part of GDB.
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.
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.
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/>. */
30 #include "ld-decode.h"
34 #include "gen-idecode.h"
35 #include "gen-icache.h"
36 #include "gen-semantics.h"
41 lf_print_opcodes (lf
*file
, const gen_entry
*table
)
47 ASSERT (table
->opcode
!= NULL
);
48 lf_printf (file
, "_%d_%d",
49 table
->opcode
->first
, table
->opcode
->last
);
50 if (table
->parent
== NULL
)
52 lf_printf (file
, "__%d", table
->opcode_nr
);
53 table
= table
->parent
;
62 print_idecode_ifetch (lf
*file
,
63 int previous_nr_prefetched_words
,
64 int current_nr_prefetched_words
)
67 for (word_nr
= previous_nr_prefetched_words
;
68 word_nr
< current_nr_prefetched_words
; word_nr
++)
71 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
72 word_nr
, options
.insn_bit_size
, word_nr
);
79 /****************************************************************/
83 lf_print_table_name (lf
*file
, const gen_entry
*table
)
85 lf_printf (file
, "idecode_table");
86 lf_print_opcodes (file
, table
);
92 print_idecode_table (lf
*file
, const gen_entry
*entry
, const char *result
)
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");
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");
127 lf_printf (file
, "\n");
128 lf_printf (file
, "/* call the leaf code */\n");
129 if (options
.gen
.code
== generate_jumps
)
131 lf_printf (file
, "goto *table_entry->function_or_table;\n");
135 lf_printf (file
, "%s ", result
);
136 if (options
.gen
.icache
)
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");
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");
157 print_idecode_table_start (lf
*file
,
158 const gen_entry
*table
, int depth
, void *data
)
161 /* start of the table */
162 if (table
->opcode_rule
->gen
== array_gen
)
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");
172 print_idecode_table_leaf (lf
*file
,
173 const gen_entry
*entry
, int depth
, void *data
)
175 const gen_entry
*master_entry
;
176 ASSERT (entry
->parent
!= NULL
);
178 if (entry
->combined_parent
== NULL
)
179 master_entry
= entry
;
181 master_entry
= entry
->combined_parent
;
183 /* add an entry to the table */
184 if (entry
->parent
->opcode_rule
->gen
== array_gen
)
186 lf_printf (file
, " /*%d*/ { ", entry
->opcode_nr
);
187 if (entry
->opcode
== NULL
)
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
)
194 lf_printf (file
, "&&");
196 print_function_name (file
,
197 entry
->insns
->insn
->name
,
198 entry
->insns
->insn
->format_name
,
200 master_entry
->expanded_bits
,
202 ? function_name_prefix_icache
203 : function_name_prefix_semantics
));
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
)
209 /* table calling switch statement */
210 lf_printf (file
, "function_entry, 0, 0, ");
211 if (options
.gen
.code
== generate_jumps
)
213 lf_printf (file
, "&&");
215 lf_print_table_name (file
, entry
);
217 else if (entry
->opcode
->is_boolean
)
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
);
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
);
241 lf_printf (file
, " },\n");
246 print_idecode_table_end (lf
*file
,
247 const gen_entry
*table
, int depth
, void *data
)
250 if (table
->opcode_rule
->gen
== array_gen
)
252 lf_printf (file
, "};\n");
256 /****************************************************************/
260 print_goto_switch_name (lf
*file
, const gen_entry
*entry
)
262 lf_printf (file
, "case_");
263 if (entry
->opcode
== NULL
)
265 print_function_name (file
,
266 entry
->insns
->insn
->name
,
267 entry
->insns
->insn
->format_name
,
269 entry
->expanded_bits
,
271 ? function_name_prefix_icache
272 : function_name_prefix_semantics
));
276 lf_print_table_name (file
, entry
);
281 print_goto_switch_table_leaf (lf
*file
,
282 const gen_entry
*entry
, int depth
, void *data
)
284 ASSERT (entry
->parent
!= NULL
);
286 ASSERT (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
);
287 ASSERT (entry
->parent
->opcode
);
289 lf_printf (file
, "/* %d */ &&", entry
->opcode_nr
);
290 if (entry
->combined_parent
!= NULL
)
291 print_goto_switch_name (file
, entry
->combined_parent
);
293 print_goto_switch_name (file
, entry
);
294 lf_printf (file
, ",\n");
298 print_goto_switch_break (lf
*file
, const gen_entry
*entry
)
300 lf_printf (file
, "goto break_");
301 lf_print_table_name (file
, entry
->parent
);
302 lf_printf (file
, ";\n");
307 print_goto_switch_table (lf
*file
, const gen_entry
*table
)
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 */ ,
316 lf_indent (file
, -2);
317 lf_printf (file
, "};\n");
321 void print_idecode_switch
322 (lf
*file
, const gen_entry
*table
, const char *result
);
325 print_idecode_switch_start (lf
*file
,
326 const gen_entry
*table
, int depth
, void *data
)
328 /* const char *result = data; */
330 ASSERT (table
->opcode_rule
->gen
== switch_gen
331 || table
->opcode_rule
->gen
== goto_switch_gen
332 || table
->opcode_rule
->gen
== padded_switch_gen
);
334 if (table
->opcode
->is_boolean
335 || table
->opcode_rule
->gen
== switch_gen
336 || table
->opcode_rule
->gen
== padded_switch_gen
)
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");
346 else if (table
->opcode_rule
->gen
== goto_switch_gen
)
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
))
353 lf_printf (file
, "{\n");
354 lf_indent (file
, +2);
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
));
375 ASSERT ("bad switch" == NULL
);
381 print_idecode_switch_leaf (lf
*file
,
382 const gen_entry
*entry
, int depth
, void *data
)
384 const char *result
= data
;
385 ASSERT (entry
->parent
!= NULL
);
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
);
392 /* skip over any instructions combined into another entry */
393 if (entry
->combined_parent
!= NULL
)
396 if (entry
->parent
->opcode
->is_boolean
&& entry
->opcode_nr
== 0)
398 /* case: boolean false target */
399 lf_printf (file
, "case %d:\n", entry
->parent
->opcode
->boolean_constant
);
401 else if (entry
->parent
->opcode
->is_boolean
&& entry
->opcode_nr
!= 0)
403 /* case: boolean true case */
404 lf_printf (file
, "default:\n");
406 else if (entry
->parent
->opcode_rule
->gen
== switch_gen
407 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
)
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
);
414 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
)
416 /* case: <opcode-nr> - goto-switch */
417 print_goto_switch_name (file
, entry
);
418 lf_printf (file
, ":\n");
422 ERROR ("bad switch");
424 lf_printf (file
, " {\n");
425 lf_indent (file
, +4);
427 if (entry
->opcode
== NULL
)
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
)
436 lf_printf (file
, "goto ");
439 lf_printf (file
, "%s", result
);
442 print_function_name (file
,
443 entry
->insns
->insn
->name
,
444 entry
->insns
->insn
->format_name
,
446 entry
->expanded_bits
,
448 ? function_name_prefix_icache
449 : function_name_prefix_semantics
));
450 if (options
.gen
.code
== generate_calls
)
452 lf_printf (file
, " (");
453 print_semantic_function_actual (file
,
454 entry
->insns
->semantic
->
455 nr_prefetched_words
);
456 lf_printf (file
, ")");
458 lf_printf (file
, ";\n");
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
)
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");
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");
484 if (entry
->parent
->opcode
->is_boolean
485 || entry
->parent
->opcode_rule
->gen
== switch_gen
486 || entry
->parent
->opcode_rule
->gen
== padded_switch_gen
)
488 lf_printf (file
, "break;\n");
490 else if (entry
->parent
->opcode_rule
->gen
== goto_switch_gen
)
492 print_goto_switch_break (file
, entry
);
496 ERROR ("bad switch");
499 lf_indent (file
, -4);
500 lf_printf (file
, " }\n");
505 print_idecode_switch_illegal (lf
*file
, const char *result
)
507 lf_indent (file
, +2);
508 print_idecode_invalid (file
, result
, invalid_illegal
);
509 lf_printf (file
, "break;\n");
510 lf_indent (file
, -2);
514 print_idecode_switch_end (lf
*file
,
515 const gen_entry
*table
, int depth
, void *data
)
517 const char *result
= data
;
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
);
524 if (table
->opcode
->is_boolean
)
526 lf_printf (file
, "}\n");
527 lf_indent (file
, -2);
529 else if (table
->opcode_rule
->gen
== switch_gen
530 || table
->opcode_rule
->gen
== padded_switch_gen
)
532 lf_printf (file
, "default:\n");
533 lf_indent (file
, +2);
534 if (table
->nr_entries
== table
->opcode
->nr_opcodes
)
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");
543 print_idecode_switch_illegal (file
, result
);
545 lf_indent (file
, -2);
546 lf_printf (file
, "}\n");
547 lf_indent (file
, -2);
549 else if (table
->opcode_rule
->gen
== goto_switch_gen
)
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
))
563 lf_indent (file
, -2);
564 lf_printf (file
, "}\n");
569 ERROR ("bad switch");
575 print_idecode_switch (lf
*file
, const gen_entry
*table
, const char *result
)
577 gen_entry_traverse_tree (file
, table
,
579 print_idecode_switch_start
,
580 print_idecode_switch_leaf
,
581 print_idecode_switch_end
, (void *) result
);
586 print_idecode_switch_function_header (lf
*file
,
587 const gen_entry
*table
,
588 int is_function_definition
,
589 int nr_prefetched_words
)
591 lf_printf (file
, "\n");
592 if (options
.gen
.code
== generate_calls
)
594 lf_printf (file
, "static ");
595 if (options
.gen
.icache
)
597 lf_printf (file
, "idecode_semantic *");
601 lf_printf (file
, "unsigned_word");
603 if (is_function_definition
)
605 lf_printf (file
, "\n");
609 lf_printf (file
, " ");
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
)
617 lf_printf (file
, ";");
619 lf_printf (file
, "\n");
621 if (options
.gen
.code
== generate_jumps
&& is_function_definition
)
623 lf_indent (file
, -1);
624 lf_print_table_name (file
, table
);
625 lf_printf (file
, ":\n");
626 lf_indent (file
, +1);
632 idecode_declare_if_switch (lf
*file
,
633 const gen_entry
*table
, int depth
, void *data
)
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
)
638 print_idecode_switch_function_header (file
,
640 0 /*isnt function definition */ ,
647 idecode_expand_if_switch (lf
*file
,
648 const gen_entry
*table
, int depth
, void *data
)
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
)
653 print_idecode_switch_function_header (file
,
655 1 /*is function definition */ ,
657 if (options
.gen
.code
== generate_calls
)
659 lf_printf (file
, "{\n");
660 lf_indent (file
, +2);
662 print_idecode_switch (file
, table
, "return");
663 if (options
.gen
.code
== generate_calls
)
665 lf_indent (file
, -2);
666 lf_printf (file
, "}\n");
672 /****************************************************************/
676 print_idecode_lookups (lf
*file
,
677 const gen_entry
*table
,
678 cache_entry
*cache_rules
)
682 /* output switch function declarations where needed by tables */
683 gen_entry_traverse_tree (file
, table
, 1, idecode_declare_if_switch
, /* START */
686 /* output tables where needed */
687 for (depth
= gen_entry_depth (table
); depth
> 0; depth
--)
689 gen_entry_traverse_tree (file
, table
,
691 print_idecode_table_start
,
692 print_idecode_table_leaf
,
693 print_idecode_table_end
, NULL
);
696 /* output switch functions where needed */
697 gen_entry_traverse_tree (file
, table
, 1, idecode_expand_if_switch
, /* START */
703 print_idecode_body (lf
*file
, const gen_entry
*table
, const char *result
)
705 if (table
->opcode_rule
->gen
== switch_gen
706 || table
->opcode_rule
->gen
== goto_switch_gen
707 || table
->opcode_rule
->gen
== padded_switch_gen
)
709 print_idecode_switch (file
, table
, result
);
713 print_idecode_table (file
, table
, result
);
718 /****************************************************************/
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 */
726 print_idecode_validate (lf
*file
,
727 const insn_entry
*instruction
,
728 const insn_opcodes
*opcode_paths
)
730 /* Validate: unchecked instruction fields
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
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
++)
746 insn_uint check_mask
= 0;
747 insn_uint check_val
= 0;
748 insn_word_entry
*word
= instruction
->word
[word_nr
];
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
++)
755 insn_bit_entry
*bit
= word
->bit
[bit_nr
];
756 insn_field_entry
*field
= bit
->field
;
758 /* Make space for the next bit */
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
))
774 /* Look through the list of opcode paths that lead to this
775 instruction. See if any have failed to check the
777 if (opcode_paths
!= NULL
)
779 const insn_opcodes
*entry
;
780 for (entry
= opcode_paths
; entry
!= NULL
; entry
= entry
->next
)
782 opcode_field
*opcode
;
783 for (opcode
= entry
->opcode
;
784 opcode
!= NULL
; opcode
= opcode
->parent
)
786 if (opcode
->word_nr
== word_nr
787 && opcode
->first
<= bit_nr
788 && opcode
->last
>= bit_nr
)
789 /* we've decoded on this bit */
793 /* the bit wasn't decoded on */
797 /* all the opcode paths decoded on BIT_NR, no need
803 check_val
|= bit
->value
;
806 /* if any bits not checked by opcode tables, output code to check them */
811 lf_printf (file
, "if (WITH_RESERVED_BITS)\n");
812 lf_printf (file
, " {\n");
813 lf_indent (file
, +4);
816 if (options
.insn_bit_size
> 32)
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
));
829 "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
830 word_nr
, (unsigned long) (check_mask
),
831 (unsigned long) (check_val
));
833 lf_indent (file
, +2);
834 print_idecode_invalid (file
, "return", invalid_illegal
);
835 lf_indent (file
, -2);
840 lf_indent (file
, -4);
841 lf_printf (file
, " }\n");
843 lf_indent_suppress (file
);
844 lf_printf (file
, "#endif\n");
847 /* Validate: Floating Point hardware
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 */
853 if (filter_is_member (instruction
->flags
, "f"))
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");
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");
870 /* Validate: Floating Point available
872 If floating point is not available, we enter a floating point
873 unavailable interrupt into the cache instead of the instruction
876 The PowerPC spec requires a CSI after MSR[FP] is changed and when
877 ever a CSI occures we flush the instruction cache. */
880 if (filter_is_member (instruction
->flags
, "f"))
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");
896 /* Validate: Validate Instruction in correct slot
898 Some architectures place restrictions on the slot that an
899 instruction can be issued in */
902 if (filter_is_member (instruction
->options
, "s")
903 || options
.gen
.slot_verification
)
905 lf_printf (file
, "\n");
906 lf_indent_suppress (file
);
907 lf_printf (file
, "#if defined(IS_WRONG_SLOT)\n");
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");
923 /****************************************************************/
927 print_idecode_issue_function_header (lf
*file
,
928 const char *processor
,
929 function_decl_type decl_type
,
930 int nr_prefetched_words
)
933 lf_printf (file
, "\n");
936 case is_function_declaration
:
937 lf_print__function_type_function (file
, print_semantic_function_type
,
938 "INLINE_IDECODE", " ");
940 case is_function_definition
:
941 lf_print__function_type_function (file
, print_semantic_function_type
,
942 "INLINE_IDECODE", "\n");
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
, " (*");
951 indent
= print_function_name (file
,
955 NULL
, function_name_prefix_idecode
);
958 case is_function_definition
:
959 indent
+= lf_printf (file
, " (");
961 case is_function_declaration
:
962 lf_putstr (file
, "\n(");
965 case is_function_variable
:
966 lf_putstr (file
, ")\n(");
970 lf_indent (file
, +indent
);
971 print_semantic_function_formal (file
, nr_prefetched_words
);
972 lf_putstr (file
, ")");
973 lf_indent (file
, -indent
);
976 case is_function_definition
:
977 lf_printf (file
, "\n");
979 case is_function_declaration
:
980 case is_function_variable
:
981 lf_putstr (file
, ";\n");
989 print_idecode_globals (lf
*file
)
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");