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