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

   Copyright 2002-2025 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/>.  */


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

#include "igen.h"
#include "ld-insn.h"
#include "ld-decode.h"
#include "gen.h"

static insn_uint
sub_val (insn_uint val, int val_last_pos, int first_pos, int last_pos)
{
  return ((val >> (val_last_pos - last_pos))
	  & (((insn_uint) 1 << (last_pos - first_pos + 1)) - 1));
}

static void
update_depth (lf *file, const gen_entry *entry, int depth, void *data)
{
  int *max_depth = (int *) data;
  if (*max_depth < depth)
    *max_depth = depth;
}


int
gen_entry_depth (const gen_entry *table)
{
  int depth = 0;
  gen_entry_traverse_tree (NULL, table, 1, NULL,	/*start */
			   update_depth, NULL,	/*end */
			   &depth);	/* data */
  return depth;
}


static void
print_gen_entry_path (const line_ref *line,
		      const gen_entry *table,
		      error_func *print)
{
  if (table->parent == NULL)
    {
      if (table->top->model != NULL)
	print (line, "%s", table->top->model->name);
      else
	{
	  /* We don't want to output things, but we want the side-effects they
	     might have (e.g. checking line != NULL).  */
	  print (line, "%s", "");
	}
    }
  else
    {
      print_gen_entry_path (line, table->parent, print);
      print (NULL, ".%d", table->opcode_nr);
    }
}

static void
print_gen_entry_insns (const gen_entry *table,
		       error_func *print,
		       const char *first_message,
		       const char *next_message)
{
  insn_list *i;
  const char *message;
  message = first_message;
  for (i = table->insns; i != NULL; i = i->next)
    {
      insn_entry *insn = i->insn;
      print_gen_entry_path (insn->line, table, print);
      print (NULL, ": %s.%s %s\n", insn->format_name, insn->name, message);
      if (next_message != NULL)
	message = next_message;
    }
}

/* same as strcmp */
static int
insn_field_cmp (const insn_word_entry *l, const insn_word_entry *r)
{
  while (1)
    {
      int bit_nr;
      if (l == NULL && r == NULL)
	return 0;		/* all previous fields the same */
      if (l == NULL)
	return -1;		/* left shorter than right */
      if (r == NULL)
	return +1;		/* left longer than right */
      for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
	{
	  if (l->bit[bit_nr]->field->type != insn_field_string)
	    continue;
	  if (r->bit[bit_nr]->field->type != insn_field_string)
	    continue;
	  if (l->bit[bit_nr]->field->conditions == NULL)
	    continue;
	  if (r->bit[bit_nr]->field->conditions == NULL)
	    continue;
	  if (0)
	    printf ("%s%s%s VS %s%s%s\n",
		    l->bit[bit_nr]->field->val_string,
		    l->bit[bit_nr]->field->conditions->test ==
		    insn_field_cond_eq ? "=" : "!",
		    l->bit[bit_nr]->field->conditions->string,
		    r->bit[bit_nr]->field->val_string,
		    r->bit[bit_nr]->field->conditions->test ==
		    insn_field_cond_eq ? "=" : "!",
		    r->bit[bit_nr]->field->conditions->string);
	  if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq
	      && r->bit[bit_nr]->field->conditions->test ==
	      insn_field_cond_eq)
	    {
	      if (l->bit[bit_nr]->field->conditions->type ==
		  insn_field_cond_field
		  && r->bit[bit_nr]->field->conditions->type ==
		  insn_field_cond_field)
		/* somewhat arbitrary */
		{
		  int cmp = strcmp (l->bit[bit_nr]->field->conditions->string,
				    r->bit[bit_nr]->field->conditions->
				    string);
		  if (cmp != 0)
		    return cmp;
		  else
		    continue;
		}
	      if (l->bit[bit_nr]->field->conditions->type ==
		  insn_field_cond_field)
		return +1;
	      if (r->bit[bit_nr]->field->conditions->type ==
		  insn_field_cond_field)
		return -1;
	      /* The case of both fields having constant values should have
	         already have been handled because such fields are converted
	         into normal constant fields, but we must not make this
		 an assert, as we wouldn't gracefully handle an (invalid)
		 duplicate insn description.  */
	      continue;
	    }
	  if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
	    return +1;		/* left = only */
	  if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
	    return -1;		/* right = only */
	  /* FIXME: Need to some what arbitrarily order conditional lists */
	  continue;
	}
      l = l->next;
      r = r->next;
    }
}

/* same as strcmp */
static int
insn_word_cmp (const insn_word_entry *l, const insn_word_entry *r)
{
  while (1)
    {
      int bit_nr;
      if (l == NULL && r == NULL)
	return 0;		/* all previous fields the same */
      if (l == NULL)
	return -1;		/* left shorter than right */
      if (r == NULL)
	return +1;		/* left longer than right */
      for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
	{
	  if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask)
	    return -1;
	  if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask)
	    return 1;
	  if (l->bit[bit_nr]->value < r->bit[bit_nr]->value)
	    return -1;
	  if (l->bit[bit_nr]->value > r->bit[bit_nr]->value)
	    return 1;
	}
      l = l->next;
      r = r->next;
    }
}

/* same as strcmp */
static int
opcode_bit_cmp (const opcode_bits *l, const opcode_bits *r)
{
  if (l == NULL && r == NULL)
    return 0;			/* all previous bits the same */
  if (l == NULL)
    return -1;			/* left shorter than right */
  if (r == NULL)
    return +1;			/* left longer than right */
  /* most significant word */
  if (l->field->word_nr < r->field->word_nr)
    return +1;			/* left has more significant word */
  if (l->field->word_nr > r->field->word_nr)
    return -1;			/* right has more significant word */
  /* most significant bit? */
  if (l->first < r->first)
    return +1;			/* left as more significant bit */
  if (l->first > r->first)
    return -1;			/* right as more significant bit */
  /* nr bits? */
  if (l->last < r->last)
    return +1;			/* left as less bits */
  if (l->last > r->last)
    return -1;			/* right as less bits */
  /* value? */
  if (l->value < r->value)
    return -1;
  if (l->value > r->value)
    return 1;
  return 0;
}


/* same as strcmp */
static int
opcode_bits_cmp (const opcode_bits *l, const opcode_bits *r)
{
  while (1)
    {
      int cmp;
      if (l == NULL && r == NULL)
	return 0;		/* all previous bits the same */
      cmp = opcode_bit_cmp (l, r);
      if (cmp != 0)
	return cmp;
      l = l->next;
      r = r->next;
    }
}

/* same as strcmp */
static opcode_bits *
new_opcode_bits (opcode_bits *old_bits,
		 int value,
		 int first,
		 int last, insn_field_entry *field, opcode_field *opcode)
{
  opcode_bits *new_bits = ZALLOC (opcode_bits);
  new_bits->field = field;
  new_bits->value = value;
  new_bits->first = first;
  new_bits->last = last;
  new_bits->opcode = opcode;

  if (old_bits != NULL)
    {
      opcode_bits *new_list;
      opcode_bits **last = &new_list;
      new_list = new_opcode_bits (old_bits->next,
				  old_bits->value,
				  old_bits->first,
				  old_bits->last,
				  old_bits->field, old_bits->opcode);
      while (*last != NULL)
	{
	  int cmp = opcode_bit_cmp (new_bits, *last);
	  if (cmp < 0)		/* new < new_list */
	    {
	      break;
	    }
	  if (cmp == 0)
	    {
	      ERROR ("Duplicated insn bits in list");
	    }
	  last = &(*last)->next;
	}
      new_bits->next = *last;
      *last = new_bits;
      return new_list;
    }
  else
    {
      return new_bits;
    }
}

/* Same as strcmp().  */
static int
name_cmp (const char *l, const char *r)
{
  if (l == NULL && r == NULL)
    return 0;
  if (l != NULL && r == NULL)
    return -1;
  if (l == NULL && r != NULL)
    return +1;
  return strcmp (l, r);
}


typedef enum
{
  merge_duplicate_insns,
  report_duplicate_insns,
}
duplicate_insn_actions;

static insn_list *
insn_list_insert (insn_list **cur_insn_ptr,
		  int *nr_insns,
		  insn_entry * insn,
		  opcode_bits *expanded_bits,
		  opcode_field *opcodes,
		  int nr_prefetched_words,
		  duplicate_insn_actions duplicate_action)
{
  /* insert it according to the order of the fields & bits */
  for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next)
    {
      int cmp;

      /* key#1 sort according to the constant fields of each instruction */
      cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words);
      if (cmp < 0)
	break;
      else if (cmp > 0)
	continue;

      /* key#2 sort according to the expanded bits of each instruction */
      cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits);
      if (cmp < 0)
	break;
      else if (cmp > 0)
	continue;

      /* key#3 sort according to the non-constant fields of each instruction */
      cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words);
      if (cmp < 0)
	break;
      else if (cmp > 0)
	continue;

      if (duplicate_action == merge_duplicate_insns)
	{
	  /* key#4: If we're going to merge duplicates, also sort
	     according to the format_name.  Two instructions with
	     identical decode patterns, but different names, are
	     considered different when merging.  Duplicates are only
	     important when creating a decode table (implied by
	     report_duplicate_insns) as such a table only has the
	     instruction's bit code as a way of differentiating
	     between instructions.  */
	  int cmp = name_cmp (insn->format_name,
			      (*cur_insn_ptr)->insn->format_name);
	  if (cmp < 0)
	    break;
	  else if (cmp > 0)
	    continue;
	}

      if (duplicate_action == merge_duplicate_insns)
	{
	  /* key#5: If we're going to merge duplicates, also sort
	     according to the name.  See comment above for
	     format_name.  */
	  int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name);
	  if (cmp < 0)
	    break;
	  else if (cmp > 0)
	    continue;
	}

      /* duplicate keys, report problem */
      switch (duplicate_action)
	{
	case report_duplicate_insns:
	  /* It would appear that we have two instructions with the
	     same constant field values across all words and bits.
	     This error can also occure when insn_field_cmp() is
	     failing to differentiate between two instructions that
	     differ only in their conditional fields. */
	  warning (insn->line,
		   "Two instructions with identical constant fields\n");
	  error ((*cur_insn_ptr)->insn->line,
		 "Location of duplicate instruction\n");
	case merge_duplicate_insns:
	  /* Add the opcode path to the instructions list */
	  if (options.trace.insn_insertion)
	    {
	      notify ((*cur_insn_ptr)->insn->line,
		      "%s.%s: insert merge %s.%s\n",
		      (*cur_insn_ptr)->insn->format_name,
		      (*cur_insn_ptr)->insn->name,
		      insn->format_name,
		      insn->name);
	    }
	  if (opcodes != NULL)
	    {
	      insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
	      while (*last != NULL)
		{
		  last = &(*last)->next;
		}
	      (*last) = ZALLOC (insn_opcodes);
	      (*last)->opcode = opcodes;
	    }
	  /* Use the larger nr_prefetched_words */
	  if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
	    (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
	  return (*cur_insn_ptr);
	}

    }

  /* create a new list entry and insert it */
  {
    insn_list *new_insn = ZALLOC (insn_list);
    if (options.trace.insn_insertion)
      {
	notify (insn->line,
		"%s.%s: insert new\n",
		insn->format_name,
		insn->name);
      }
    new_insn->insn = insn;
    new_insn->expanded_bits = expanded_bits;
    new_insn->next = (*cur_insn_ptr);
    new_insn->nr_prefetched_words = nr_prefetched_words;
    if (opcodes != NULL)
      {
	new_insn->opcodes = ZALLOC (insn_opcodes);
	new_insn->opcodes->opcode = opcodes;
      }
    (*cur_insn_ptr) = new_insn;
  }

  *nr_insns += 1;

  return (*cur_insn_ptr);
}


extern void
gen_entry_traverse_tree (lf *file,
			 const gen_entry *table,
			 int depth,
			 gen_entry_handler * start,
			 gen_entry_handler * leaf,
			 gen_entry_handler * end, void *data)
{
  gen_entry *entry;

  ASSERT (table !=NULL);
  ASSERT (table->opcode != NULL);
  ASSERT (table->nr_entries > 0);
  ASSERT (table->entries != 0);

  /* prefix */
  if (start != NULL && depth >= 0)
    {
      start (file, table, depth, data);
    }
  /* infix leaves */
  for (entry = table->entries; entry != NULL; entry = entry->sibling)
    {
      if (entry->entries != NULL && depth != 0)
	{
	  gen_entry_traverse_tree (file, entry, depth + 1,
				   start, leaf, end, data);
	}
      else if (depth >= 0)
	{
	  if (leaf != NULL)
	    {
	      leaf (file, entry, depth, data);
	    }
	}
    }
  /* postfix */
  if (end != NULL && depth >= 0)
    {
      end (file, table, depth, data);
    }
}



/* create a list element containing a single gen_table entry */

static gen_list *
make_table (const insn_table *isa,
	    const decode_table *rules,
	    const model_entry *model)
{
  insn_entry *insn;
  gen_list *entry = ZALLOC (gen_list);
  entry->table = ZALLOC (gen_entry);
  entry->table->top = entry;
  entry->model = model;
  entry->isa = isa;
  for (insn = isa->insns; insn != NULL; insn = insn->next)
    {
      if (model == NULL
	  || insn->processors == NULL
	  || filter_is_member (insn->processors, model->name))
	{
	  insn_list_insert (&entry->table->insns, &entry->table->nr_insns, insn, NULL,	/* expanded_bits - none yet */
			    NULL,	/* opcodes - none yet */
			    0,	/* nr_prefetched_words - none yet */
			    report_duplicate_insns);
	}
    }
  entry->table->opcode_rule = rules;
  return entry;
}


gen_table *
make_gen_tables (const insn_table *isa, const decode_table *rules)
{
  gen_table *gen = ZALLOC (gen_table);
  gen->isa = isa;
  gen->rules = rules;
  if (options.gen.multi_sim)
    {
      gen_list **last = &gen->tables;
      model_entry *model;
      filter *processors;
      if (options.model_filter != NULL)
	processors = options.model_filter;
      else
	processors = isa->model->processors;
      for (model = isa->model->models; model != NULL; model = model->next)
	{
	  if (filter_is_member (processors, model->name))
	    {
	      *last = make_table (isa, rules, model);
	      last = &(*last)->next;
	    }
	}
    }
  else
    {
      gen->tables = make_table (isa, rules, NULL);
    }
  return gen;
}


/****************************************************************/

/* Is the bit, according to the decode rule, identical across all the
   instructions? */
static int
insns_bit_useless (const insn_list *insns, const decode_table *rule, int bit_nr)
{
  const insn_list *entry;
  int value = -1;
  int is_useless = 1;		/* cleared if something actually found */

  /* check the instructions for some constant value in at least one of
     the bit fields */
  for (entry = insns; entry != NULL; entry = entry->next)
    {
      insn_word_entry *word = entry->insn->word[rule->word_nr];
      insn_bit_entry *bit = word->bit[bit_nr];
      switch (bit->field->type)
	{
	case insn_field_invalid:
	  ASSERT (0);
	  break;
	case insn_field_wild:
	case insn_field_reserved:
	  /* neither useless or useful - ignore */
	  break;
	case insn_field_int:
	  switch (rule->search)
	    {
	    case decode_find_strings:
	      /* an integer isn't a string */
	      return 1;
	    case decode_find_constants:
	    case decode_find_mixed:
	      /* an integer is useful if its value isn't the same
	         between all instructions.  The first time through the
	         value is saved, the second time through (if the
	         values differ) it is marked as useful. */
	      if (value < 0)
		value = bit->value;
	      else if (value != bit->value)
		is_useless = 0;
	      break;
	    }
	  break;
	case insn_field_string:
	  switch (rule->search)
	    {
	    case decode_find_strings:
	      /* at least one string, keep checking */
	      is_useless = 0;
	      break;
	    case decode_find_constants:
	    case decode_find_mixed:
	      if (filter_is_member (rule->constant_field_names,
				    bit->field->val_string))
		/* a string field forced to constant? */
		is_useless = 0;
	      else if (bit->field->conditions != NULL
		       && bit->field->conditions->test == insn_field_cond_eq
		       && bit->field->conditions->type == insn_field_cond_value)
		{
		  int shift = bit->field->last - bit_nr;
		  int bitvalue = (bit->field->conditions->value >> shift) & 1;

		  if (value < 0)
		    value = bitvalue;
		  else if (value != bitvalue)
		    is_useless = 0;
		}
	      else if (rule->search == decode_find_constants)
		/* the string field isn't constant */
		return 1;
	      break;
	    }
	}
    }

  /* Given only one constant value has been found, check through all
     the instructions to see if at least one conditional makes it
     useful */
  if (value >= 0 && is_useless)
    {
      for (entry = insns; entry != NULL; entry = entry->next)
	{
	  insn_word_entry *word = entry->insn->word[rule->word_nr];
	  insn_bit_entry *bit = word->bit[bit_nr];
	  switch (bit->field->type)
	    {
	    case insn_field_invalid:
	      ASSERT (0);
	      break;
	    case insn_field_wild:
	    case insn_field_reserved:
	    case insn_field_int:
	      /* already processed */
	      break;
	    case insn_field_string:
	      switch (rule->search)
		{
		case decode_find_strings:
		case decode_find_constants:
		  /* already processed */
		  break;
		case decode_find_mixed:
		  /* string field with conditions.  If this condition
		     eliminates the value then the compare is useful */
		  if (bit->field->conditions != NULL)
		    {
		      insn_field_cond *condition;
		      int shift = bit->field->last - bit_nr;
		      for (condition = bit->field->conditions;
			   condition != NULL; condition = condition->next)
			{
			  switch (condition->type)
			    {
			    case insn_field_cond_value:
			      switch (condition->test)
				{
				case insn_field_cond_ne:
				  if (((condition->value >> shift) & 1)
				      == (unsigned) value)
				    /* conditional field excludes the
				       current value */
				    is_useless = 0;
				  break;
				case insn_field_cond_eq:
				  if (((condition->value >> shift) & 1)
				      != (unsigned) value)
				    /* conditional field requires the
				       current value */
				    is_useless = 0;
				  break;
				}
			      break;
			    case insn_field_cond_field:
			      /* are these handled separatly? */
			      break;
			    }
			}
		    }
		}
	    }
	}
    }

  return is_useless;
}


/* go through a gen-table's list of instruction formats looking for a
   range of bits that meet the decode table RULEs requirements */

static opcode_field *
gen_entry_find_opcode_field (insn_list *insns,
			     const decode_table *rule, int string_only)
{
  opcode_field curr_opcode;
  ASSERT (rule != NULL);

  memset (&curr_opcode, 0, sizeof (curr_opcode));
  curr_opcode.word_nr = rule->word_nr;
  curr_opcode.first = rule->first;
  curr_opcode.last = rule->last;

  /* Try to reduce the size of first..last in accordance with the
     decode rules */

  while (curr_opcode.first <= rule->last)
    {
      if (insns_bit_useless (insns, rule, curr_opcode.first))
	curr_opcode.first++;
      else
	break;
    }
  while (curr_opcode.last >= rule->first)
    {
      if (insns_bit_useless (insns, rule, curr_opcode.last))
	curr_opcode.last--;
      else
	break;
    }

  /* did the final opcode field end up being empty? */
  if (curr_opcode.first > curr_opcode.last)
    {
      return NULL;
    }
  ASSERT (curr_opcode.last >= rule->first);
  ASSERT (curr_opcode.first <= rule->last);
  ASSERT (curr_opcode.first <= curr_opcode.last);

  /* Ensure that, for the non string only case, the opcode includes
     the range forced_first .. forced_last */
  if (!string_only && curr_opcode.first > rule->force_first)
    {
      curr_opcode.first = rule->force_first;
    }
  if (!string_only && curr_opcode.last < rule->force_last)
    {
      curr_opcode.last = rule->force_last;
    }

  /* For the string only case, force just the lower bound (so that the
     shift can be eliminated) */
  if (string_only && rule->force_last == options.insn_bit_size - 1)
    {
      curr_opcode.last = options.insn_bit_size - 1;
    }

  /* handle any special cases */
  switch (rule->type)
    {
    case normal_decode_rule:
      /* let the above apply */
      curr_opcode.nr_opcodes =
	(1 << (curr_opcode.last - curr_opcode.first + 1));
      break;
    case boolean_rule:
      curr_opcode.is_boolean = 1;
      curr_opcode.boolean_constant = rule->constant;
      curr_opcode.nr_opcodes = 2;
      break;
    }

  {
    opcode_field *new_field = ZALLOC (opcode_field);
    memcpy (new_field, &curr_opcode, sizeof (opcode_field));
    return new_field;
  }
}


static void
gen_entry_insert_insn (gen_entry *table,
		       insn_entry * old_insn,
		       int new_word_nr,
		       int new_nr_prefetched_words,
		       int new_opcode_nr, opcode_bits *new_bits)
{
  gen_entry **entry = &table->entries;

  /* find the new table for this entry */
  while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr)
    {
      entry = &(*entry)->sibling;
    }

  if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr)
    {
      /* insert the missing entry */
      gen_entry *new_entry = ZALLOC (gen_entry);
      new_entry->sibling = (*entry);
      (*entry) = new_entry;
      table->nr_entries++;
      /* fill it in */
      new_entry->top = table->top;
      new_entry->opcode_nr = new_opcode_nr;
      new_entry->word_nr = new_word_nr;
      new_entry->expanded_bits = new_bits;
      new_entry->opcode_rule = table->opcode_rule->next;
      new_entry->parent = table;
      new_entry->nr_prefetched_words = new_nr_prefetched_words;
    }
  /* ASSERT new_bits == cur_entry bits */
  ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr);
  insn_list_insert (&(*entry)->insns, &(*entry)->nr_insns, old_insn, NULL,	/* expanded_bits - only in final list */
		    NULL,	/* opcodes - only in final list */
		    new_nr_prefetched_words,	/* for this table */
		    report_duplicate_insns);
}


static void
gen_entry_expand_opcode (gen_entry *table,
			 insn_entry * instruction,
			 int bit_nr, int opcode_nr, opcode_bits *bits)
{
  if (bit_nr > table->opcode->last)
    {
      /* Only include the hardwired bit information with an entry IF
         that entry (and hence its functions) are being duplicated.  */
      if (options.trace.insn_expansion)
	{
	  print_gen_entry_path (table->opcode_rule->line, table, notify);
	  notify (NULL, ": insert %d - %s.%s%s\n",
		  opcode_nr,
		  instruction->format_name,
		  instruction->name,
		  (table->opcode_rule->
		   with_duplicates ? " (duplicated)" : ""));
	}
      if (table->opcode_rule->with_duplicates)
	{
	  gen_entry_insert_insn (table, instruction,
				 table->opcode->word_nr,
				 table->nr_prefetched_words, opcode_nr, bits);
	}
      else
	{
	  gen_entry_insert_insn (table, instruction,
				 table->opcode->word_nr,
				 table->nr_prefetched_words, opcode_nr, NULL);
	}
    }
  else
    {
      insn_word_entry *word = instruction->word[table->opcode->word_nr];
      insn_field_entry *field = word->bit[bit_nr]->field;
      int last_pos = ((field->last < table->opcode->last)
		      ? field->last : table->opcode->last);
      int first_pos = ((field->first > table->opcode->first)
		       ? field->first : table->opcode->first);
      int width = last_pos - first_pos + 1;
      switch (field->type)
	{
	case insn_field_int:
	  {
	    int val;
	    val = sub_val (field->val_int, field->last, first_pos, last_pos);
	    gen_entry_expand_opcode (table, instruction,
				     last_pos + 1,
				     ((opcode_nr << width) | val), bits);
	    break;
	  }
	default:
	  {
	    if (field->type == insn_field_reserved)
	      gen_entry_expand_opcode (table, instruction,
				       last_pos + 1,
				       ((opcode_nr << width)), bits);
	    else
	      {
		int val;
		int last_val = (table->opcode->is_boolean ? 2 : (1 << width));
		for (val = 0; val < last_val; val++)
		  {
		    /* check to see if the value has been precluded
		       (by a conditional) in some way */
		    int is_precluded;
		    insn_field_cond *condition;
		    for (condition = field->conditions, is_precluded = 0;
			 condition != NULL && !is_precluded;
			 condition = condition->next)
		      {
			switch (condition->type)
			  {
			  case insn_field_cond_value:
			    {
			      int value =
				sub_val (condition->value, field->last,
					 first_pos, last_pos);
			      switch (condition->test)
				{
				case insn_field_cond_ne:
				  if (value == val)
				    is_precluded = 1;
				  break;
				case insn_field_cond_eq:
				  if (value != val)
				    is_precluded = 1;
				  break;
				}
			      break;
			    }
			  case insn_field_cond_field:
			    {
			      int value = -1;
			      opcode_bits *bit;
			      gen_entry *t = NULL;
			      /* Try to find a value for the
			         conditional by looking back through
			         the previously defined bits for one
			         that covers the designated
			         conditional field */
			      for (bit = bits; bit != NULL; bit = bit->next)
				{
				  if (bit->field->word_nr ==
				      condition->field->word_nr
				      && bit->first <= condition->field->first
				      && bit->last >= condition->field->last)
				    {
				      /* the bit field fully specified
				         the conditional field's value */
				      value = sub_val (bit->value, bit->last,
						       condition->field->
						       first,
						       condition->field->
						       last);
				    }
				}
			      /* Try to find a value by looking
			         through this and previous tables */
			      if (bit == NULL)
				{
				  for (t = table;
				       t->parent != NULL; t = t->parent)
				    {
				      if (t->parent->opcode->word_nr ==
					  condition->field->word_nr
					  && t->parent->opcode->first <=
					  condition->field->first
					  && t->parent->opcode->last >=
					  condition->field->last)
					{
					  /* the table entry fully
					     specified the condition
					     field's value */
					  /* extract the field's value
					     from the opcode */
					  value =
					    sub_val (t->opcode_nr,
						     t->parent->opcode->last,
						     condition->field->first,
						     condition->field->last);
					  /* this is a requirement of
					     a conditonal field
					     referring to another field */
					  ASSERT ((condition->field->first -
						   condition->field->last) ==
						  (first_pos - last_pos));
					  printf
					    ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
					     value, t->opcode_nr,
					     t->parent->opcode->last,
					     condition->field->first,
					     condition->field->last);
					}
				    }
				}
			      if (bit == NULL && t == NULL)
				error (instruction->line,
				       "Conditional `%s' of field `%s' isn't expanded\n",
				       condition->string, field->val_string);
			      switch (condition->test)
				{
				case insn_field_cond_ne:
				  if (value == val)
				    is_precluded = 1;
				  break;
				case insn_field_cond_eq:
				  if (value != val)
				    is_precluded = 1;
				  break;
				}
			      break;
			    }
			  }
		      }
		    if (!is_precluded)
		      {
			/* Only add additional hardwired bit
			   information if the entry is not going to
			   later be combined */
			if (table->opcode_rule->with_combine)
			  {
			    gen_entry_expand_opcode (table, instruction,
						     last_pos + 1,
						     ((opcode_nr << width) |
						      val), bits);
			  }
			else
			  {
			    opcode_bits *new_bits =
			      new_opcode_bits (bits, val,
					       first_pos, last_pos,
					       field,
					       table->opcode);
			    gen_entry_expand_opcode (table, instruction,
						     last_pos + 1,
						     ((opcode_nr << width) |
						      val), new_bits);
			  }
		      }
		  }
	      }
	  }
	}
    }
}

static void
gen_entry_insert_expanding (gen_entry *table, insn_entry * instruction)
{
  gen_entry_expand_opcode (table,
			   instruction,
			   table->opcode->first, 0, table->expanded_bits);
}


static int
insns_match_format_names (insn_list *insns, filter *format_names)
{
  if (format_names != NULL)
    {
      insn_list *i;
      for (i = insns; i != NULL; i = i->next)
	{
	  if (i->insn->format_name != NULL
	      && !filter_is_member (format_names, i->insn->format_name))
	    return 0;
	}
    }
  return 1;
}

static int
table_matches_path (gen_entry *table, decode_path_list *paths)
{
  if (paths == NULL)
    return 1;
  while (paths != NULL)
    {
      gen_entry *entry = table;
      decode_path *path = paths->path;
      while (1)
	{
	  if (entry == NULL && path == NULL)
	    return 1;
	  if (entry == NULL || path == NULL)
	    break;
	  if (entry->opcode_nr != path->opcode_nr)
	    break;
	  entry = entry->parent;
	  path = path->parent;
	}
      paths = paths->next;
    }
  return 0;
}


static int
insns_match_conditions (insn_list *insns, decode_cond *conditions)
{
  if (conditions != NULL)
    {
      insn_list *i;
      for (i = insns; i != NULL; i = i->next)
	{
	  decode_cond *cond;
	  for (cond = conditions; cond != NULL; cond = cond->next)
	    {
	      int bit_nr;
	      if (i->insn->nr_words <= cond->word_nr)
		return 0;
	      for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
		{
		  if (!cond->mask[bit_nr])
		    continue;
		  if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask)
		    return 0;
		  if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value
		       == cond->value[bit_nr]) == !cond->is_equal)
		    return 0;
		}
	    }
	}
    }
  return 1;
}

static int
insns_match_nr_words (const insn_list *insns, int nr_words)
{
  const insn_list *i;
  for (i = insns; i != NULL; i = i->next)
    {
      if (i->insn->nr_words < nr_words)
	return 0;
    }
  return 1;
}

static int
insn_list_cmp (const insn_list *l, const insn_list *r)
{
  while (1)
    {
      const insn_entry *insn;
      if (l == NULL && r == NULL)
	return 0;
      if (l == NULL)
	return -1;
      if (r == NULL)
	return 1;
      if (l->insn != r->insn)
	return -1;		/* somewhat arbitrary at present */
      /* skip this insn */
      insn = l->insn;
      while (l != NULL && l->insn == insn)
	l = l->next;
      while (r != NULL && r->insn == insn)
	r = r->next;
    }
}



static void
gen_entry_expand_insns (gen_entry *table)
{
  const decode_table *opcode_rule;

  ASSERT (table->nr_insns >= 1);

  /* determine a valid opcode */
  for (opcode_rule = table->opcode_rule;
       opcode_rule != NULL; opcode_rule = opcode_rule->next)
    {
      char *discard_reason;
      if (table->top->model != NULL
	  && opcode_rule->model_names != NULL
	  && !filter_is_member (opcode_rule->model_names,
				table->top->model->name))
	{
	  /* the rule isn't applicable to this processor */
	  discard_reason = "wrong model";
	}
      else if (table->nr_insns == 1 && opcode_rule->conditions == NULL)
	{
	  /* for safety, require a pre-codition when attempting to
	     apply a rule to a single instruction */
	  discard_reason = "need pre-condition when nr-insn == 1";
	}
      else if (table->nr_insns == 1 && !opcode_rule->with_duplicates)
	{
	  /* Little point in expanding a single instruction when we're
	     not duplicating the semantic functions that this table
	     calls */
	  discard_reason = "need duplication with nr-insns == 1";
	}
      else
	if (!insns_match_format_names
	    (table->insns, opcode_rule->format_names))
	{
	  discard_reason = "wrong format name";
	}
      else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1))
	{
	  discard_reason = "wrong nr words";
	}
      else if (!table_matches_path (table, opcode_rule->paths))
	{
	  discard_reason = "path failed";
	}
      else
	if (!insns_match_conditions (table->insns, opcode_rule->conditions))
	{
	  discard_reason = "condition failed";
	}
      else
	{
	  discard_reason = "no opcode field";
	  table->opcode = gen_entry_find_opcode_field (table->insns,
						       opcode_rule,
						       table->nr_insns == 1	/*string-only */
	    );
	  if (table->opcode != NULL)
	    {
	      table->opcode_rule = opcode_rule;
	      break;
	    }
	}

      if (options.trace.rule_rejection)
	{
	  print_gen_entry_path (opcode_rule->line, table, notify);
	  notify (NULL, ": rule discarded - %s\n", discard_reason);
	}
    }

  /* did we find anything */
  if (opcode_rule == NULL)
    {
      /* the decode table failed, this set of instructions haven't
         been uniquely identified */
      if (table->nr_insns > 1)
	{
	  print_gen_entry_insns (table, warning,
				 "was not uniquely decoded",
				 "decodes to the same entry");
	  error (NULL, "unrecoverable\n");
	}
      return;
    }

  /* Determine the number of words that must have been prefetched for
     this table to function */
  if (table->parent == NULL)
    table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
  else if (table->opcode_rule->word_nr + 1 >
	   table->parent->nr_prefetched_words)
    table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
  else
    table->nr_prefetched_words = table->parent->nr_prefetched_words;

  /* back link what we found to its parent */
  if (table->parent != NULL)
    {
      ASSERT (table->parent->opcode != NULL);
      table->opcode->parent = table->parent->opcode;
    }

  /* report the rule being used to expand the instructions */
  if (options.trace.rule_selection)
    {
      print_gen_entry_path (table->opcode_rule->line, table, notify);
      notify (NULL,
	      ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
	      table->opcode->word_nr,
	      i2target (options.hi_bit_nr, table->opcode->first),
	      i2target (options.hi_bit_nr, table->opcode->last),
	      i2target (options.hi_bit_nr, table->opcode_rule->first),
	      i2target (options.hi_bit_nr, table->opcode_rule->last),
	      table->opcode->nr_opcodes, table->nr_entries);
    }

  /* expand the raw instructions according to the opcode */
  {
    insn_list *entry;
    for (entry = table->insns; entry != NULL; entry = entry->next)
      {
	if (options.trace.insn_expansion)
	  {
	    print_gen_entry_path (table->opcode_rule->line, table, notify);
	    notify (NULL, ": expand - %s.%s\n",
		    entry->insn->format_name, entry->insn->name);
	  }
	gen_entry_insert_expanding (table, entry->insn);
      }
  }

  /* dump the results */
  if (options.trace.entries)
    {
      gen_entry *entry;
      for (entry = table->entries; entry != NULL; entry = entry->sibling)
	{
	  insn_list *l;
	  print_gen_entry_path (table->opcode_rule->line, entry, notify);
	  notify (NULL, ": %d - entries %d -",
		  entry->opcode_nr, entry->nr_insns);
	  for (l = entry->insns; l != NULL; l = l->next)
	    notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);
	  notify (NULL, "\n");
	}
    }

  /* perform a combine pass if needed */
  if (table->opcode_rule->with_combine)
    {
      gen_entry *entry;
      for (entry = table->entries; entry != NULL; entry = entry->sibling)
	{
	  if (entry->combined_parent == NULL)
	    {
	      gen_entry **last = &entry->combined_next;
	      gen_entry *alt;
	      for (alt = entry->sibling; alt != NULL; alt = alt->sibling)
		{
		  if (alt->combined_parent == NULL
		      && insn_list_cmp (entry->insns, alt->insns) == 0)
		    {
		      alt->combined_parent = entry;
		      *last = alt;
		      last = &alt->combined_next;
		    }
		}
	    }
	}
      if (options.trace.combine)
	{
	  int nr_unique = 0;
	  gen_entry *entry;
	  for (entry = table->entries; entry != NULL; entry = entry->sibling)
	    {
	      if (entry->combined_parent == NULL)
		{
		  insn_list *l;
		  gen_entry *duplicate;
		  nr_unique++;
		  print_gen_entry_path (table->opcode_rule->line, entry,
					notify);
		  for (duplicate = entry->combined_next; duplicate != NULL;
		       duplicate = duplicate->combined_next)
		    {
		      notify (NULL, "+%d", duplicate->opcode_nr);
		    }
		  notify (NULL, ": entries %d -", entry->nr_insns);
		  for (l = entry->insns; l != NULL; l = l->next)
		    {
		      notify (NULL, " %s.%s",
			      l->insn->format_name, l->insn->name);
		    }
		  notify (NULL, "\n");
		}
	    }
	  print_gen_entry_path (table->opcode_rule->line, table, notify);
	  notify (NULL,
		  ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
		  table->opcode->word_nr, i2target (options.hi_bit_nr,
						    table->opcode->first),
		  i2target (options.hi_bit_nr, table->opcode->last),
		  i2target (options.hi_bit_nr, table->opcode_rule->first),
		  i2target (options.hi_bit_nr, table->opcode_rule->last),
		  table->opcode->nr_opcodes, table->nr_entries, nr_unique);
	}
    }

  /* Check that the rule did more than re-arange the order of the
     instructions */
  {
    gen_entry *entry;
    for (entry = table->entries; entry != NULL; entry = entry->sibling)
      {
	if (entry->combined_parent == NULL)
	  {
	    if (insn_list_cmp (table->insns, entry->insns) == 0)
	      {
		print_gen_entry_path (table->opcode_rule->line, table,
				      warning);
		warning (NULL,
			 ": Applying rule just copied all instructions\n");
		print_gen_entry_insns (entry, warning, "Copied", NULL);
		error (NULL, "unrecoverable\n");
	      }
	  }
      }
  }

  /* if some form of expanded table, fill in the missing dots */
  switch (table->opcode_rule->gen)
    {
    case padded_switch_gen:
    case array_gen:
    case goto_switch_gen:
      if (!table->opcode->is_boolean)
	{
	  gen_entry **entry = &table->entries;
	  gen_entry *illegals = NULL;
	  gen_entry **last_illegal = &illegals;
	  int opcode_nr = 0;
	  while (opcode_nr < table->opcode->nr_opcodes)
	    {
	      if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)
		{
		  /* missing - insert it under our feet at *entry */
		  gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0,	/* nr_prefetched_words == 0 for invalid */
					 opcode_nr, NULL);
		  ASSERT ((*entry) != NULL);
		  ASSERT ((*entry)->opcode_nr == opcode_nr);
		  (*last_illegal) = *entry;
		  (*last_illegal)->combined_parent = illegals;
		  last_illegal = &(*last_illegal)->combined_next;
		}
	      entry = &(*entry)->sibling;
	      opcode_nr++;
	    }
	  /* oops, will have pointed the first illegal insn back to
	     its self.  Fix this */
	  if (illegals != NULL)
	    illegals->combined_parent = NULL;
	}
      break;
    case switch_gen:
    case invalid_gen:
      /* ignore */
      break;
    }

  /* and do the same for the newly created sub entries but *only*
     expand entries that haven't been combined. */
  {
    gen_entry *entry;
    for (entry = table->entries; entry != NULL; entry = entry->sibling)
      {
	if (entry->combined_parent == NULL)
	  {
	    gen_entry_expand_insns (entry);
	  }
      }
  }
}

void
gen_tables_expand_insns (gen_table *gen)
{
  gen_list *entry;
  for (entry = gen->tables; entry != NULL; entry = entry->next)
    {
      gen_entry_expand_insns (entry->table);
    }
}


/* create a list of all the semantic functions that need to be
   generated.  Eliminate any duplicates. Verify that the decode stage
   worked. */

static void
make_gen_semantics_list (lf *file, const gen_entry *entry, int depth, void *data)
{
  gen_table *gen = (gen_table *) data;
  insn_list *insn;
  /* Not interested in an entrie that have been combined into some
     other entry at the same level */
  if (entry->combined_parent != NULL)
    return;

  /* a leaf should contain exactly one instruction. If not the decode
     stage failed. */
  ASSERT (entry->nr_insns == 1);

  /* Enter this instruction into the list of semantic functions. */
  insn = insn_list_insert (&gen->semantics, &gen->nr_semantics,
			   entry->insns->insn,
			   entry->expanded_bits,
			   entry->parent->opcode,
			   entry->insns->nr_prefetched_words,
			   merge_duplicate_insns);
  /* point the table entry at the real semantic function */
  ASSERT (insn != NULL);
  entry->insns->semantic = insn;
}


void
gen_tables_expand_semantics (gen_table *gen)
{
  gen_list *entry;
  for (entry = gen->tables; entry != NULL; entry = entry->next)
    {
      gen_entry_traverse_tree (NULL, entry->table, 1,	/* depth */
			       NULL,	/* start-handler */
			       make_gen_semantics_list,	/* leaf-handler */
			       NULL,	/* end-handler */
			       gen);	/* data */
    }
}



#ifdef MAIN


static void
dump_opcode_field (lf *file,
		   char *prefix,
		   opcode_field *field, char *suffix, int levels)
{
  lf_printf (file, "%s(opcode_field *) %p", prefix, field);
  if (levels && field != NULL)
    {
      lf_indent (file, +1);
      lf_printf (file, "\n(first %d)", field->first);
      lf_printf (file, "\n(last %d)", field->last);
      lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
      lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
      lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
      dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1);
      lf_indent (file, -1);
    }
  lf_printf (file, "%s", suffix);
}


static void
dump_opcode_bits (lf *file,
		  char *prefix, opcode_bits *bits, char *suffix, int levels)
{
  lf_printf (file, "%s(opcode_bits *) %p", prefix, bits);

  if (levels && bits != NULL)
    {
      lf_indent (file, +1);
      lf_printf (file, "\n(value %d)", bits->value);
      dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0);
      dump_insn_field (file, "\n(field ", bits->field, ")");
      dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1);
      lf_indent (file, -1);
    }
  lf_printf (file, "%s", suffix);
}



static void
dump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix)
{
  lf_printf (file, "%s(insn_list *) %p", prefix, entry);

  if (entry != NULL)
    {
      lf_indent (file, +1);
      dump_insn_entry (file, "\n(insn ", entry->insn, ")");
      lf_printf (file, "\n(next %p)", entry->next);
      lf_indent (file, -1);
    }
  lf_printf (file, "%s", suffix);
}


static void
dump_insn_word_entry_list_entries (lf *file,
				   char *prefix,
				   insn_list *entry, char *suffix)
{
  lf_printf (file, "%s", prefix);
  while (entry != NULL)
    {
      dump_insn_list (file, "\n(", entry, ")");
      entry = entry->next;
    }
  lf_printf (file, "%s", suffix);
}


static void
dump_gen_entry (lf *file,
		char *prefix, gen_entry *table, char *suffix, int levels)
{

  lf_printf (file, "%s(gen_entry *) %p", prefix, table);

  if (levels && table !=NULL)
    {

      lf_indent (file, +1);
      lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
      lf_printf (file, "\n(word_nr %d)", table->word_nr);
      dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")",
			-1);
      lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
      dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns,
					 ")");
      dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
      dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
      lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
      dump_gen_entry (file, "\n(entries ", table->entries, ")",
		      table->nr_entries);
      dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
      dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
      lf_indent (file, -1);
    }
  lf_printf (file, "%s", suffix);
}

static void
dump_gen_list (lf *file,
	       char *prefix, gen_list *entry, char *suffix, int levels)
{
  while (entry != NULL)
    {
      lf_printf (file, "%s(gen_list *) %p", prefix, entry);
      dump_gen_entry (file, "\n(", entry->table, ")", levels);
      lf_printf (file, "\n(next (gen_list *) %p)", entry->next);
      lf_printf (file, "%s", suffix);
    }
}


static void
dump_gen_table (lf *file,
		char *prefix, gen_table *gen, char *suffix, int levels)
{
  lf_printf (file, "%s(gen_table *) %p", prefix, gen);
  lf_printf (file, "\n(isa (insn_table *) %p)", gen->isa);
  lf_printf (file, "\n(rules (decode_table *) %p)", gen->rules);
  dump_gen_list (file, "\n(", gen->tables, ")", levels);
  lf_printf (file, "%s", suffix);
}


igen_options options;

int
main (int argc, char **argv)
{
  decode_table *decode_rules;
  insn_table *instructions;
  gen_table *gen;
  lf *l;

  if (argc != 7)
    error (NULL,
	   "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");

  INIT_OPTIONS ();

  filter_parse (&options.flags_filter, argv[1]);

  options.hi_bit_nr = a2i (argv[2]);
  options.insn_bit_size = a2i (argv[3]);
  options.insn_specifying_widths = a2i (argv[4]);
  ASSERT (options.hi_bit_nr < options.insn_bit_size);

  instructions = load_insn_table (argv[6], NULL);
  decode_rules = load_decode_table (argv[5]);
  gen = make_gen_tables (instructions, decode_rules);

  gen_tables_expand_insns (gen);

  l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");

  dump_gen_table (l, "(", gen, ")\n", -1);
  return 0;
}

#endif
