/* The IGEN simulator generator for GDB, the GNU Debugger.

   Copyright 2002-2023 Free Software Foundation, Inc.

   Contributed by Andrew Cagney.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */


/* load the opcode stat structure */

#include "misc.h"
#include "lf.h"
#include "table.h"
#include "filter.h"

#include "igen.h"

#include "ld-decode.h"


static const name_map decode_type_map[] = {
  {"normal", normal_decode_rule},
  {"boolean", boolean_rule},
  {NULL, normal_decode_rule},
};

static const name_map decode_gen_map[] = {
  {"array", array_gen},
  {"switch", switch_gen},
  {"padded-switch", padded_switch_gen},
  {"goto-switch", goto_switch_gen},
  {NULL, -1},
};

static const name_map decode_reserved_map[] = {
  {"zero-reserved", 1},
  {NULL, 0},
};

static const name_map decode_duplicates_map[] = {
  {"duplicate", 1},
  {NULL, 0},
};

static const name_map decode_combine_map[] = {
  {"combine", 1},
  {NULL, 0},
};

static const name_map decode_search_map[] = {
  {"constants", decode_find_constants},
  {"mixed", decode_find_mixed},
  {"strings", decode_find_strings},
  {NULL, decode_find_mixed},
};


static void
set_bits (int bit[max_insn_bit_size], uint64_t value)
{
  int bit_nr;
  for (bit_nr = 0; bit_nr < max_insn_bit_size; bit_nr++)
    {
      if (bit_nr < options.insn_bit_size)
	bit[bit_nr] = (value >> (options.insn_bit_size - bit_nr - 1)) & 1;
      else
	bit[bit_nr] = 0;
    }
}

decode_table *
load_decode_table (const char *file_name)
{
  table *file = table_open (file_name);
  table_entry *entry;
  decode_table *table = NULL;
  decode_table **curr_rule = &table;
  while ((entry = table_read (file)) != NULL)
    {
      char *decode_options = entry->field[decode_options_field];
      decode_table *new_rule = ZALLOC (decode_table);
      if (entry->nr_fields < min_nr_decode_fields)
	error (entry->line, "Missing decode table fields\n");
      new_rule->line = entry->line;

      /* the options field */
      new_rule->type = name2i (decode_options, decode_type_map);
      if (options.decode.overriding_gen != NULL)
	new_rule->gen =
	  name2i (options.decode.overriding_gen, decode_gen_map);
      else
	new_rule->gen = name2i (decode_options, decode_gen_map);
      if (new_rule->gen == padded_switch_gen && options.decode.switch_as_goto)
	new_rule->gen = goto_switch_gen;
      if (options.decode.zero_reserved)
	new_rule->with_zero_reserved = 1;
      else
	new_rule->with_zero_reserved =
	  name2i (decode_options, decode_reserved_map);
      if (options.decode.duplicate)
	new_rule->with_duplicates = 1;
      else
	new_rule->with_duplicates =
	  name2i (decode_options, decode_duplicates_map);
      if (options.decode.combine)
	new_rule->with_combine = 1;
      else
	new_rule->with_combine = name2i (decode_options, decode_combine_map);
      if (new_rule->type == boolean_rule)
	{
	  char *chp = decode_options;
	  while (*chp != '\0')
	    {
	      if (isdigit (*chp))
		{
		  new_rule->constant = a2i (chp);
		  break;
		}
	      chp = skip_to_separator (chp, ",");
	      if (*chp == ',')
		++chp;
	      chp = skip_spaces (chp);
	    }
	}

      /* First and last */
      if (entry->nr_fields > decode_first_field
	  && strlen (entry->field[decode_first_field]) > 0)
	{
	  new_rule->first = target_a2i (options.hi_bit_nr,
					entry->field[decode_first_field]);
	  if (new_rule->first < 0 || new_rule->first >= options.insn_bit_size)
	    error (new_rule->line, "First field out of range\n");
	}
      else
	new_rule->first = 0;
      if (entry->nr_fields > decode_last_field
	  && strlen (entry->field[decode_last_field]) > 0)
	{
	  new_rule->last = target_a2i (options.hi_bit_nr,
				       entry->field[decode_last_field]);
	  if (new_rule->last < 0 || new_rule->last >= options.insn_bit_size)
	    error (new_rule->line, "Last field out of range\n");
	}
      else
	new_rule->last = options.insn_bit_size - 1;
      if (new_rule->first > new_rule->last)
	error (new_rule->line, "First must preceed last\n");

      /* force first/last, with default values based on first/last */
      if (entry->nr_fields > decode_force_first_field
	  && strlen (entry->field[decode_force_first_field]) > 0)
	{
	  new_rule->force_first = target_a2i (options.hi_bit_nr,
					      entry->
					      field
					      [decode_force_first_field]);
	  if (new_rule->force_first < new_rule->first
	      || new_rule->force_first > new_rule->last + 1)
	    error (new_rule->line, "Force first out of range\n");
	}
      else
	new_rule->force_first = new_rule->last + 1;
      if (entry->nr_fields > decode_force_last_field
	  && strlen (entry->field[decode_force_last_field]) > 0)
	{
	  new_rule->force_last = target_a2i (options.hi_bit_nr,
					     entry->
					     field[decode_force_last_field]);
	  if (new_rule->force_last > new_rule->last
	      || new_rule->force_last < new_rule->first - 1)
	    error (new_rule->line, "Force-last out of range\n");
	}
      else
	new_rule->force_last = new_rule->first - 1;

      /* fields to be treated as constant */
      if (entry->nr_fields > decode_constant_field_names_field)
	filter_parse (&new_rule->constant_field_names,
		      entry->field[decode_constant_field_names_field]);

      /* applicable word nr */
      if (entry->nr_fields > decode_word_nr_field)
	new_rule->word_nr = a2i (entry->field[decode_word_nr_field]);

      /* required instruction format names */
      if (entry->nr_fields > decode_format_names_field)
	filter_parse (&new_rule->format_names,
		      entry->field[decode_format_names_field]);

      /* required processor models */
      if (entry->nr_fields > decode_model_names_field)
	filter_parse (&new_rule->model_names,
		      entry->field[decode_model_names_field]);

      /* required paths */
      if (entry->nr_fields > decode_paths_field
	  && strlen (entry->field[decode_paths_field]) > 0)
	{
	  decode_path_list **last = &new_rule->paths;
	  char *chp = entry->field[decode_paths_field];
	  do
	    {
	      (*last) = ZALLOC (decode_path_list);
	      /* extra root/zero entry */
	      (*last)->path = ZALLOC (decode_path);
	      do
		{
		  decode_path *entry = ZALLOC (decode_path);
		  entry->opcode_nr = a2i (chp);
		  entry->parent = (*last)->path;
		  (*last)->path = entry;
		  chp = skip_digits (chp);
		  chp = skip_spaces (chp);
		}
	      while (*chp == '.');
	      last = &(*last)->next;
	    }
	  while (*chp == ',');
	  if (*chp != '\0')
	    error (entry->line, "Invalid path field\n");
	}

      /* collect up the list of optional special conditions applicable
         to the rule */
      {
	int field_nr = nr_decode_fields;
	while (entry->nr_fields > field_nr)
	  {
	    decode_cond *cond = ZALLOC (decode_cond);
	    decode_cond **last;
	    if (entry->nr_fields > field_nr + decode_cond_mask_field)
	      set_bits (cond->mask,
			a2i (entry->
			     field[field_nr + decode_cond_mask_field]));
	    if (entry->nr_fields > field_nr + decode_cond_value_field)
	      {
		if (entry->field[field_nr + decode_cond_value_field][0] ==
		    '!')
		  {
		    cond->is_equal = 0;
		    set_bits (cond->value,
			      a2i (entry->
				   field[field_nr + decode_cond_value_field] +
				   1));
		  }
		else
		  {
		    cond->is_equal = 1;
		    set_bits (cond->value,
			      a2i (entry->
				   field[field_nr +
					 decode_cond_value_field]));
		  }
	      }
	    if (entry->nr_fields > field_nr + decode_cond_word_nr_field)
	      cond->word_nr =
		a2i (entry->field[field_nr + decode_cond_word_nr_field]);
	    field_nr += nr_decode_cond_fields;
	    /* insert it */
	    last = &new_rule->conditions;
	    while (*last != NULL)
	      last = &(*last)->next;
	    *last = cond;
	  }
      }
      *curr_rule = new_rule;
      curr_rule = &new_rule->next;
    }
  return table;
}


int
decode_table_max_word_nr (const decode_table *entry)
{
  int max_word_nr = 0;
  while (entry != NULL)
    {
      decode_cond *cond;
      if (entry->word_nr > max_word_nr)
	max_word_nr = entry->word_nr;
      for (cond = entry->conditions; cond != NULL; cond = cond->next)
	{
	  if (cond->word_nr > max_word_nr)
	    max_word_nr = cond->word_nr;
	}
      entry = entry->next;
    }
  return max_word_nr;
}


static void
dump_decode_cond (lf *file, const char *prefix, const decode_cond *cond,
		  const char *suffix)
{
  lf_printf (file, "%s(decode_cond *) %p", prefix, cond);
  if (cond != NULL)
    {
      lf_indent (file, +1);
      lf_printf (file, "\n(word_nr %d)", cond->word_nr);
      lf_printf (file, "\n(mask %p)", cond->mask);
      lf_printf (file, "\n(value %p)", cond->value);
      lf_printf (file, "\n(is_equal %d)", cond->is_equal);
      lf_printf (file, "\n(next (decode_cond *) %p)", cond->next);
      lf_indent (file, -1);
    }
  lf_printf (file, "%s", suffix);
}


static void
dump_decode_conds (lf *file, const char *prefix, const decode_cond *cond,
		   const char *suffix)
{
  lf_printf (file, "%s(decode_cond *) %p", prefix, cond);
  while (cond != NULL)
    {
      dump_decode_cond (file, "\n(", cond, ")");
      cond = cond->next;
    }
  lf_printf (file, "%s", suffix);
}


void
dump_decode_rule (lf *file, const char *prefix, const decode_table *rule,
		  const char *suffix)
{
  lf_printf (file, "%s(decode_table *) %p", prefix, rule);
  if (rule != NULL)
    {
      lf_indent (file, +1);
      dump_line_ref (file, "\n(line ", rule->line, ")");
      lf_printf (file, "\n(type %s)", i2name (rule->type, decode_type_map));
      lf_printf (file, "\n(gen %s)", i2name (rule->gen, decode_gen_map));
      lf_printf (file, "\n(first %d)", rule->first);
      lf_printf (file, "\n(last %d)", rule->last);
      lf_printf (file, "\n(force_first %d)", rule->force_first);
      lf_printf (file, "\n(force_last %d)", rule->force_last);
      dump_filter (file, "\n(constant_field_names \"",
		   rule->constant_field_names, "\")");
      lf_printf (file, "\n(constant 0x%x)", rule->constant);
      lf_printf (file, "\n(word_nr %d)", rule->word_nr);
      lf_printf (file, "\n(with_zero_reserved %d)", rule->with_zero_reserved);
      lf_printf (file, "\n(with_duplicates %d)", rule->with_duplicates);
      lf_printf (file, "\n(with_combine %d)", rule->with_combine);
      dump_filter (file, "\n(format_names \"", rule->format_names, "\")");
      dump_filter (file, "\n(model_names \"", rule->model_names, "\")");
      dump_decode_conds (file, "\n(conditions ", rule->conditions, ")");
      lf_printf (file, "\n(next %p)", rule->next);
      lf_indent (file, -1);
    }
  lf_printf (file, "%s", suffix);
}


#ifdef MAIN

static void
dump_decode_rules (lf *file,
		   const char *prefix,
		   const decode_table *rule,
		   const char *suffix)
{
  lf_printf (file, "%s", prefix);
  while (rule != NULL)
    {
      lf_indent (file, +1);
      dump_decode_rule (file, "\n(", rule, ")");
      lf_indent (file, -1);
      rule = rule->next;
    }
  lf_printf (file, "%s", suffix);
}

igen_options options;

int
main (int argc, char **argv)
{
  lf *l;
  decode_table *rules;

  INIT_OPTIONS ();

  if (argc != 3)
    error (NULL, "Usage: decode <decode-file> <hi-bit-nr>\n");

  options.hi_bit_nr = a2i (argv[2]);
  rules = load_decode_table (argv[1]);
  l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
  dump_decode_rules (l, "(rules ", rules, ")\n");

  return 0;
}
#endif
