OSDN Git Service

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