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