Home | History | Annotate | Line # | Download | only in igen
      1 /* The IGEN simulator generator for GDB, the GNU Debugger.
      2 
      3    Copyright 2002-2024 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 /* load the opcode stat structure */
     24 
     25 #include "misc.h"
     26 #include "lf.h"
     27 #include "table.h"
     28 #include "filter.h"
     29 
     30 #include "igen.h"
     31 
     32 #include "ld-decode.h"
     33 
     34 
     35 static const name_map decode_type_map[] = {
     36   {"normal", normal_decode_rule},
     37   {"boolean", boolean_rule},
     38   {NULL, normal_decode_rule},
     39 };
     40 
     41 static const name_map decode_gen_map[] = {
     42   {"array", array_gen},
     43   {"switch", switch_gen},
     44   {"padded-switch", padded_switch_gen},
     45   {"goto-switch", goto_switch_gen},
     46   {NULL, -1},
     47 };
     48 
     49 static const name_map decode_reserved_map[] = {
     50   {"zero-reserved", 1},
     51   {NULL, 0},
     52 };
     53 
     54 static const name_map decode_duplicates_map[] = {
     55   {"duplicate", 1},
     56   {NULL, 0},
     57 };
     58 
     59 static const name_map decode_combine_map[] = {
     60   {"combine", 1},
     61   {NULL, 0},
     62 };
     63 
     64 #if 0
     65 static const name_map decode_search_map[] = {
     66   {"constants", decode_find_constants},
     67   {"mixed", decode_find_mixed},
     68   {"strings", decode_find_strings},
     69   {NULL, decode_find_mixed},
     70 };
     71 #endif
     72 
     73 
     74 static void
     75 set_bits (int bit[max_insn_bit_size], uint64_t value)
     76 {
     77   int bit_nr;
     78   for (bit_nr = 0; bit_nr < max_insn_bit_size; bit_nr++)
     79     {
     80       if (bit_nr < options.insn_bit_size)
     81 	bit[bit_nr] = (value >> (options.insn_bit_size - bit_nr - 1)) & 1;
     82       else
     83 	bit[bit_nr] = 0;
     84     }
     85 }
     86 
     87 decode_table *
     88 load_decode_table (const char *file_name)
     89 {
     90   table *file = table_open (file_name);
     91   table_entry *entry;
     92   decode_table *table = NULL;
     93   decode_table **curr_rule = &table;
     94   while ((entry = table_read (file)) != NULL)
     95     {
     96       char *decode_options = entry->field[decode_options_field];
     97       decode_table *new_rule = ZALLOC (decode_table);
     98       if (entry->nr_fields < min_nr_decode_fields)
     99 	error (entry->line, "Missing decode table fields\n");
    100       new_rule->line = entry->line;
    101 
    102       /* the options field */
    103       new_rule->type = name2i (decode_options, decode_type_map);
    104       if (options.decode.overriding_gen != NULL)
    105 	new_rule->gen =
    106 	  name2i (options.decode.overriding_gen, decode_gen_map);
    107       else
    108 	new_rule->gen = name2i (decode_options, decode_gen_map);
    109       if (new_rule->gen == padded_switch_gen && options.decode.switch_as_goto)
    110 	new_rule->gen = goto_switch_gen;
    111       if (options.decode.zero_reserved)
    112 	new_rule->with_zero_reserved = 1;
    113       else
    114 	new_rule->with_zero_reserved =
    115 	  name2i (decode_options, decode_reserved_map);
    116       if (options.decode.duplicate)
    117 	new_rule->with_duplicates = 1;
    118       else
    119 	new_rule->with_duplicates =
    120 	  name2i (decode_options, decode_duplicates_map);
    121       if (options.decode.combine)
    122 	new_rule->with_combine = 1;
    123       else
    124 	new_rule->with_combine = name2i (decode_options, decode_combine_map);
    125       if (new_rule->type == boolean_rule)
    126 	{
    127 	  char *chp = decode_options;
    128 	  while (*chp != '\0')
    129 	    {
    130 	      if (isdigit (*chp))
    131 		{
    132 		  new_rule->constant = a2i (chp);
    133 		  break;
    134 		}
    135 	      chp = skip_to_separator (chp, ",");
    136 	      if (*chp == ',')
    137 		++chp;
    138 	      chp = skip_spaces (chp);
    139 	    }
    140 	}
    141 
    142       /* First and last */
    143       if (entry->nr_fields > decode_first_field
    144 	  && strlen (entry->field[decode_first_field]) > 0)
    145 	{
    146 	  new_rule->first = target_a2i (options.hi_bit_nr,
    147 					entry->field[decode_first_field]);
    148 	  if (new_rule->first < 0 || new_rule->first >= options.insn_bit_size)
    149 	    error (new_rule->line, "First field out of range\n");
    150 	}
    151       else
    152 	new_rule->first = 0;
    153       if (entry->nr_fields > decode_last_field
    154 	  && strlen (entry->field[decode_last_field]) > 0)
    155 	{
    156 	  new_rule->last = target_a2i (options.hi_bit_nr,
    157 				       entry->field[decode_last_field]);
    158 	  if (new_rule->last < 0 || new_rule->last >= options.insn_bit_size)
    159 	    error (new_rule->line, "Last field out of range\n");
    160 	}
    161       else
    162 	new_rule->last = options.insn_bit_size - 1;
    163       if (new_rule->first > new_rule->last)
    164 	error (new_rule->line, "First must preceed last\n");
    165 
    166       /* force first/last, with default values based on first/last */
    167       if (entry->nr_fields > decode_force_first_field
    168 	  && strlen (entry->field[decode_force_first_field]) > 0)
    169 	{
    170 	  new_rule->force_first = target_a2i (options.hi_bit_nr,
    171 					      entry->
    172 					      field
    173 					      [decode_force_first_field]);
    174 	  if (new_rule->force_first < new_rule->first
    175 	      || new_rule->force_first > new_rule->last + 1)
    176 	    error (new_rule->line, "Force first out of range\n");
    177 	}
    178       else
    179 	new_rule->force_first = new_rule->last + 1;
    180       if (entry->nr_fields > decode_force_last_field
    181 	  && strlen (entry->field[decode_force_last_field]) > 0)
    182 	{
    183 	  new_rule->force_last = target_a2i (options.hi_bit_nr,
    184 					     entry->
    185 					     field[decode_force_last_field]);
    186 	  if (new_rule->force_last > new_rule->last
    187 	      || new_rule->force_last < new_rule->first - 1)
    188 	    error (new_rule->line, "Force-last out of range\n");
    189 	}
    190       else
    191 	new_rule->force_last = new_rule->first - 1;
    192 
    193       /* fields to be treated as constant */
    194       if (entry->nr_fields > decode_constant_field_names_field)
    195 	filter_parse (&new_rule->constant_field_names,
    196 		      entry->field[decode_constant_field_names_field]);
    197 
    198       /* applicable word nr */
    199       if (entry->nr_fields > decode_word_nr_field)
    200 	new_rule->word_nr = a2i (entry->field[decode_word_nr_field]);
    201 
    202       /* required instruction format names */
    203       if (entry->nr_fields > decode_format_names_field)
    204 	filter_parse (&new_rule->format_names,
    205 		      entry->field[decode_format_names_field]);
    206 
    207       /* required processor models */
    208       if (entry->nr_fields > decode_model_names_field)
    209 	filter_parse (&new_rule->model_names,
    210 		      entry->field[decode_model_names_field]);
    211 
    212       /* required paths */
    213       if (entry->nr_fields > decode_paths_field
    214 	  && strlen (entry->field[decode_paths_field]) > 0)
    215 	{
    216 	  decode_path_list **last = &new_rule->paths;
    217 	  char *chp = entry->field[decode_paths_field];
    218 	  do
    219 	    {
    220 	      (*last) = ZALLOC (decode_path_list);
    221 	      /* extra root/zero entry */
    222 	      (*last)->path = ZALLOC (decode_path);
    223 	      do
    224 		{
    225 		  decode_path *entry = ZALLOC (decode_path);
    226 		  entry->opcode_nr = a2i (chp);
    227 		  entry->parent = (*last)->path;
    228 		  (*last)->path = entry;
    229 		  chp = skip_digits (chp);
    230 		  chp = skip_spaces (chp);
    231 		}
    232 	      while (*chp == '.');
    233 	      last = &(*last)->next;
    234 	    }
    235 	  while (*chp == ',');
    236 	  if (*chp != '\0')
    237 	    error (entry->line, "Invalid path field\n");
    238 	}
    239 
    240       /* collect up the list of optional special conditions applicable
    241          to the rule */
    242       {
    243 	int field_nr = nr_decode_fields;
    244 	while (entry->nr_fields > field_nr)
    245 	  {
    246 	    decode_cond *cond = ZALLOC (decode_cond);
    247 	    decode_cond **last;
    248 	    if (entry->nr_fields > field_nr + decode_cond_mask_field)
    249 	      set_bits (cond->mask,
    250 			a2i (entry->
    251 			     field[field_nr + decode_cond_mask_field]));
    252 	    if (entry->nr_fields > field_nr + decode_cond_value_field)
    253 	      {
    254 		if (entry->field[field_nr + decode_cond_value_field][0] ==
    255 		    '!')
    256 		  {
    257 		    cond->is_equal = 0;
    258 		    set_bits (cond->value,
    259 			      a2i (entry->
    260 				   field[field_nr + decode_cond_value_field] +
    261 				   1));
    262 		  }
    263 		else
    264 		  {
    265 		    cond->is_equal = 1;
    266 		    set_bits (cond->value,
    267 			      a2i (entry->
    268 				   field[field_nr +
    269 					 decode_cond_value_field]));
    270 		  }
    271 	      }
    272 	    if (entry->nr_fields > field_nr + decode_cond_word_nr_field)
    273 	      cond->word_nr =
    274 		a2i (entry->field[field_nr + decode_cond_word_nr_field]);
    275 	    field_nr += nr_decode_cond_fields;
    276 	    /* insert it */
    277 	    last = &new_rule->conditions;
    278 	    while (*last != NULL)
    279 	      last = &(*last)->next;
    280 	    *last = cond;
    281 	  }
    282       }
    283       *curr_rule = new_rule;
    284       curr_rule = &new_rule->next;
    285     }
    286   return table;
    287 }
    288 
    289 
    290 int
    291 decode_table_max_word_nr (const decode_table *entry)
    292 {
    293   int max_word_nr = 0;
    294   while (entry != NULL)
    295     {
    296       decode_cond *cond;
    297       if (entry->word_nr > max_word_nr)
    298 	max_word_nr = entry->word_nr;
    299       for (cond = entry->conditions; cond != NULL; cond = cond->next)
    300 	{
    301 	  if (cond->word_nr > max_word_nr)
    302 	    max_word_nr = cond->word_nr;
    303 	}
    304       entry = entry->next;
    305     }
    306   return max_word_nr;
    307 }
    308 
    309 
    310 static void
    311 dump_decode_cond (lf *file, const char *prefix, const decode_cond *cond,
    312 		  const char *suffix)
    313 {
    314   lf_printf (file, "%s(decode_cond *) %p", prefix, cond);
    315   if (cond != NULL)
    316     {
    317       lf_indent (file, +1);
    318       lf_printf (file, "\n(word_nr %d)", cond->word_nr);
    319       lf_printf (file, "\n(mask %p)", cond->mask);
    320       lf_printf (file, "\n(value %p)", cond->value);
    321       lf_printf (file, "\n(is_equal %d)", cond->is_equal);
    322       lf_printf (file, "\n(next (decode_cond *) %p)", cond->next);
    323       lf_indent (file, -1);
    324     }
    325   lf_printf (file, "%s", suffix);
    326 }
    327 
    328 
    329 static void
    330 dump_decode_conds (lf *file, const char *prefix, const decode_cond *cond,
    331 		   const char *suffix)
    332 {
    333   lf_printf (file, "%s(decode_cond *) %p", prefix, cond);
    334   while (cond != NULL)
    335     {
    336       dump_decode_cond (file, "\n(", cond, ")");
    337       cond = cond->next;
    338     }
    339   lf_printf (file, "%s", suffix);
    340 }
    341 
    342 
    343 void
    344 dump_decode_rule (lf *file, const char *prefix, const decode_table *rule,
    345 		  const char *suffix)
    346 {
    347   lf_printf (file, "%s(decode_table *) %p", prefix, rule);
    348   if (rule != NULL)
    349     {
    350       lf_indent (file, +1);
    351       dump_line_ref (file, "\n(line ", rule->line, ")");
    352       lf_printf (file, "\n(type %s)", i2name (rule->type, decode_type_map));
    353       lf_printf (file, "\n(gen %s)", i2name (rule->gen, decode_gen_map));
    354       lf_printf (file, "\n(first %d)", rule->first);
    355       lf_printf (file, "\n(last %d)", rule->last);
    356       lf_printf (file, "\n(force_first %d)", rule->force_first);
    357       lf_printf (file, "\n(force_last %d)", rule->force_last);
    358       dump_filter (file, "\n(constant_field_names \"",
    359 		   rule->constant_field_names, "\")");
    360       lf_printf (file, "\n(constant 0x%x)", rule->constant);
    361       lf_printf (file, "\n(word_nr %d)", rule->word_nr);
    362       lf_printf (file, "\n(with_zero_reserved %d)", rule->with_zero_reserved);
    363       lf_printf (file, "\n(with_duplicates %d)", rule->with_duplicates);
    364       lf_printf (file, "\n(with_combine %d)", rule->with_combine);
    365       dump_filter (file, "\n(format_names \"", rule->format_names, "\")");
    366       dump_filter (file, "\n(model_names \"", rule->model_names, "\")");
    367       dump_decode_conds (file, "\n(conditions ", rule->conditions, ")");
    368       lf_printf (file, "\n(next %p)", rule->next);
    369       lf_indent (file, -1);
    370     }
    371   lf_printf (file, "%s", suffix);
    372 }
    373 
    374 
    375 #ifdef MAIN
    376 
    377 static void
    378 dump_decode_rules (lf *file,
    379 		   const char *prefix,
    380 		   const decode_table *rule,
    381 		   const char *suffix)
    382 {
    383   lf_printf (file, "%s", prefix);
    384   while (rule != NULL)
    385     {
    386       lf_indent (file, +1);
    387       dump_decode_rule (file, "\n(", rule, ")");
    388       lf_indent (file, -1);
    389       rule = rule->next;
    390     }
    391   lf_printf (file, "%s", suffix);
    392 }
    393 
    394 igen_options options;
    395 
    396 int
    397 main (int argc, char **argv)
    398 {
    399   lf *l;
    400   decode_table *rules;
    401 
    402   INIT_OPTIONS ();
    403 
    404   if (argc != 3)
    405     error (NULL, "Usage: decode <decode-file> <hi-bit-nr>\n");
    406 
    407   options.hi_bit_nr = a2i (argv[2]);
    408   rules = load_decode_table (argv[1]);
    409   l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
    410   dump_decode_rules (l, "(rules ", rules, ")\n");
    411 
    412   return 0;
    413 }
    414 #endif
    415