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