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