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

   Copyright 2002-2021 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 <stdlib.h>

#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"

#include "gen-semantics.h"
#include "gen-idecode.h"
#include "gen-icache.h"



static void
print_icache_function_header (lf *file,
			      const char *basename,
			      const char *format_name,
			      opcode_bits *expanded_bits,
			      int is_function_definition,
			      int nr_prefetched_words)
{
  lf_printf (file, "\n");
  lf_print__function_type_function (file, print_icache_function_type,
				    "EXTERN_ICACHE", " ");
  print_function_name (file,
		       basename, format_name, NULL,
		       expanded_bits, function_name_prefix_icache);
  lf_printf (file, "\n(");
  print_icache_function_formal (file, nr_prefetched_words);
  lf_printf (file, ")");
  if (!is_function_definition)
    lf_printf (file, ";");
  lf_printf (file, "\n");
}


void
print_icache_declaration (lf *file,
			  insn_entry * insn,
			  opcode_bits *expanded_bits,
			  insn_opcodes *opcodes, int nr_prefetched_words)
{
  print_icache_function_header (file,
				insn->name,
				insn->format_name,
				expanded_bits,
				0 /* is not function definition */ ,
				nr_prefetched_words);
}



static void
print_icache_extraction (lf *file,
			 const char *format_name,
			 cache_entry_type cache_type,
			 const char *entry_name,
			 const char *entry_type,
			 const char *entry_expression,
			 char *single_insn_field,
			 line_ref *line,
			 insn_field_entry *cur_field,
			 opcode_bits *expanded_bits,
			 icache_decl_type what_to_declare,
			 icache_body_type what_to_do)
{
  const char *expression;
  opcode_bits *bits;
  char *reason;
  ASSERT (format_name != NULL);
  ASSERT (entry_name != NULL);

  /* figure out exactly what should be going on here */
  switch (cache_type)
    {
    case scratch_value:
      if ((what_to_do & put_values_in_icache)
	  || what_to_do == do_not_use_icache)
	{
	  reason = "scratch";
	  what_to_do = do_not_use_icache;
	}
      else
	return;
      break;
    case compute_value:
      if ((what_to_do & get_values_from_icache)
	  || what_to_do == do_not_use_icache)
	{
	  reason = "compute";
	  what_to_do = do_not_use_icache;
	}
      else
	return;
      break;
    case cache_value:
      if ((what_to_declare != undef_variables)
	  || !(what_to_do & put_values_in_icache))
	{
	  reason = "cache";
	  what_to_declare = ((what_to_do & put_values_in_icache)
			     ? declare_variables : what_to_declare);
	}
      else
	return;
      break;
    default:
      abort ();			/* Bad switch.  */
    }

  /* For the type, default to a simple unsigned */
  if (entry_type == NULL || strlen (entry_type) == 0)
    entry_type = "unsigned";

  /* look through the set of expanded sub fields to see if this field
     has been given a constant value */
  for (bits = expanded_bits; bits != NULL; bits = bits->next)
    {
      if (bits->field == cur_field)
	break;
    }

  /* Define a storage area for the cache element */
  switch (what_to_declare)
    {
    case undef_variables:
      /* We've finished with the #define value - destory it */
      lf_indent_suppress (file);
      lf_printf (file, "#undef %s\n", entry_name);
      return;
    case define_variables:
      /* Using direct access for this entry, clear any prior
         definition, then define it */
      lf_indent_suppress (file);
      lf_printf (file, "#undef %s\n", entry_name);
      /* Don't type cast pointer types! */
      lf_indent_suppress (file);
      if (strchr (entry_type, '*') != NULL)
	lf_printf (file, "#define %s (", entry_name);
      else
	lf_printf (file, "#define %s ((%s) ", entry_name, entry_type);
      break;
    case declare_variables:
      /* using variables to define the value */
      if (line != NULL)
	lf_print__line_ref (file, line);
      lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
      break;
    }


  /* define a value for that storage area as determined by what is in
     the cache */
  if (bits != NULL
      && single_insn_field != NULL
      && strcmp (entry_name, single_insn_field) == 0
      && strcmp (entry_name, cur_field->val_string) == 0
      && ((bits->opcode->is_boolean && bits->value == 0)
	  || (!bits->opcode->is_boolean)))
    {
      /* The cache rule is specifying what to do with a simple
         instruction field.

         Because of instruction expansion, the field is either a
         constant value or equal to the specified constant (boolean
         comparison). (The latter indicated by bits->value == 0).

         The case of a field not being equal to the specified boolean
         value is handled later. */
      expression = "constant field";
      ASSERT (bits->field == cur_field);
      if (bits->opcode->is_boolean)
	{
	  ASSERT (bits->value == 0);
	  lf_printf (file, "%d", bits->opcode->boolean_constant);
	}
      else if (bits->opcode->last < bits->field->last)
	{
	  lf_printf (file, "%d",
		     bits->value << (bits->field->last - bits->opcode->last));
	}
      else
	{
	  lf_printf (file, "%d", bits->value);
	}
    }
  else if (bits != NULL
	   && single_insn_field != NULL
	   && strncmp (entry_name,
		       single_insn_field,
		       strlen (single_insn_field)) == 0
	   && strncmp (entry_name + strlen (single_insn_field),
		       "_is_",
		       strlen ("_is_")) == 0
	   && ((bits->opcode->is_boolean
		&& ((unsigned)
		    atol (entry_name + strlen (single_insn_field) +
			  strlen ("_is_")) == bits->opcode->boolean_constant))
	       || (!bits->opcode->is_boolean)))
    {
      /* The cache rule defines an entry for the comparison between a
         single instruction field and a constant.  The value of the
         comparison in someway matches that of the opcode field that
         was made constant through expansion. */
      expression = "constant compare";
      if (bits->opcode->is_boolean)
	{
	  lf_printf (file, "%d /* %s == %d */",
		     bits->value == 0,
		     single_insn_field, bits->opcode->boolean_constant);
	}
      else if (bits->opcode->last < bits->field->last)
	{
	  lf_printf (file, "%d /* %s == %d */",
		     (atol
		      (entry_name + strlen (single_insn_field) +
		       strlen ("_is_")) ==
		      (bits->
		       value << (bits->field->last - bits->opcode->last))),
		     single_insn_field,
		     (bits->
		      value << (bits->field->last - bits->opcode->last)));
	}
      else
	{
	  lf_printf (file, "%d /* %s == %d */",
		     (atol
		      (entry_name + strlen (single_insn_field) +
		       strlen ("_is_")) == bits->value), single_insn_field,
		     bits->value);
	}
    }
  else
    {
      /* put the field in the local variable, possibly also enter it
         into the cache */
      expression = "extraction";
      /* handle the cache */
      if ((what_to_do & get_values_from_icache)
	  || (what_to_do & put_values_in_icache))
	{
	  lf_printf (file, "cache_entry->crack.%s.%s",
		     format_name, entry_name);
	  if (what_to_do & put_values_in_icache)	/* also put it in the cache? */
	    {
	      lf_printf (file, " = ");
	    }
	}
      if ((what_to_do & put_values_in_icache)
	  || what_to_do == do_not_use_icache)
	{
	  if (cur_field != NULL)
	    {
	      if (entry_expression != NULL && strlen (entry_expression) > 0)
		error (line,
		       "Instruction field entry with nonempty expression\n");
	      if (cur_field->first == 0
		  && cur_field->last == options.insn_bit_size - 1)
		lf_printf (file, "(instruction_%d)", cur_field->word_nr);
	      else if (cur_field->last == options.insn_bit_size - 1)
		lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",
			   options.insn_bit_size,
			   cur_field->word_nr,
			   i2target (options.hi_bit_nr, cur_field->first),
			   i2target (options.hi_bit_nr, cur_field->last));
	      else
		lf_printf (file, "EXTRACTED%d (instruction_%d, %d, %d)",
			   options.insn_bit_size,
			   cur_field->word_nr,
			   i2target (options.hi_bit_nr, cur_field->first),
			   i2target (options.hi_bit_nr, cur_field->last));
	    }
	  else
	    {
	      lf_printf (file, "%s", entry_expression);
	    }
	}
    }

  switch (what_to_declare)
    {
    case define_variables:
      lf_printf (file, ")");
      break;
    case undef_variables:
      break;
    case declare_variables:
      lf_printf (file, ";");
      break;
    }

  ASSERT (reason != NULL && expression != NULL);
  lf_printf (file, " /* %s - %s */\n", reason, expression);
}


void
print_icache_body (lf *file,
		   insn_entry * instruction,
		   opcode_bits *expanded_bits,
		   cache_entry *cache_rules,
		   icache_decl_type what_to_declare,
		   icache_body_type what_to_do, int nr_prefetched_words)
{
  /* extract instruction fields */
  lf_printf (file, "/* Extraction: %s\n", instruction->name);
  lf_printf (file, "     ");
  switch (what_to_declare)
    {
    case define_variables:
      lf_printf (file, "#define");
      break;
    case declare_variables:
      lf_printf (file, "declare");
      break;
    case undef_variables:
      lf_printf (file, "#undef");
      break;
    }
  lf_printf (file, " ");
  switch (what_to_do)
    {
    case get_values_from_icache:
      lf_printf (file, "get-values-from-icache");
      break;
    case put_values_in_icache:
      lf_printf (file, "put-values-in-icache");
      break;
    case both_values_and_icache:
      lf_printf (file, "get-values-from-icache|put-values-in-icache");
      break;
    case do_not_use_icache:
      lf_printf (file, "do-not-use-icache");
      break;
    }
  lf_printf (file, "\n     ");
  print_insn_words (file, instruction);
  lf_printf (file, " */\n");

  /* pass zero - fetch from memory any missing instructions.

     Some of the instructions will have already been fetched (in the
     instruction array), others will still need fetching. */
  switch (what_to_do)
    {
    case get_values_from_icache:
      break;
    case put_values_in_icache:
    case both_values_and_icache:
    case do_not_use_icache:
      {
	int word_nr;
	switch (what_to_declare)
	  {
	  case undef_variables:
	    break;
	  case define_variables:
	  case declare_variables:
	    for (word_nr = nr_prefetched_words;
		 word_nr < instruction->nr_words; word_nr++)
	      {
		/* FIXME - should be using print_icache_extraction? */
		lf_printf (file,
			   "%sinstruction_word instruction_%d UNUSED = ",
			   options.module.global.prefix.l, word_nr);
		lf_printf (file, "IMEM%d_IMMED (cia, %d)",
			   options.insn_bit_size, word_nr);
		lf_printf (file, ";\n");
	      }
	  }
      }
    }

  /* if putting the instruction words in the cache, define references
     for them */
  if (options.gen.insn_in_icache)
    {
      /* FIXME: is the instruction_word type correct? */
      print_icache_extraction (file, instruction->format_name, cache_value, "insn",	/* name */
			       "instruction_word",	/* type */
			       "instruction",	/* expression */
			       NULL,	/* origin */
			       NULL,	/* line */
			       NULL, NULL, what_to_declare, what_to_do);
    }
  lf_printf (file, "\n");

  /* pass one - process instruction fields.

     If there is no cache rule, the default is to enter the field into
     the cache */
  {
    insn_word_entry *word;
    for (word = instruction->words; word != NULL; word = word->next)
      {
	insn_field_entry *cur_field;
	for (cur_field = word->first;
	     cur_field->first < options.insn_bit_size;
	     cur_field = cur_field->next)
	  {
	    /* Always expand named fields (even if constant), so
	       references are valid.  */
	    if (cur_field->type == insn_field_string)
	      {
		cache_entry *cache_rule;
		cache_entry_type value_type = cache_value;
		line_ref *value_line = instruction->line;
		/* check the cache table to see if it contains a rule
		   overriding the default cache action for an
		   instruction field */
		for (cache_rule = cache_rules;
		     cache_rule != NULL; cache_rule = cache_rule->next)
		  {
		    if (filter_is_subset (instruction->field_names,
					  cache_rule->original_fields)
			&& strcmp (cache_rule->name,
				   cur_field->val_string) == 0)
		      {
			value_type = cache_rule->entry_type;
			value_line = cache_rule->line;
			if (value_type == compute_value)
			  {
			    options.warning (cache_rule->line,
					     "instruction field of type `compute' changed to `cache'\n");
			    cache_rule->entry_type = cache_value;
			  }
			break;
		      }
		  }
		/* Define an entry for the field within the
		   instruction */
		print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string,	/* name */
					 NULL,	/* type */
					 NULL,	/* expression */
					 cur_field->val_string,	/* insn field */
					 value_line,
					 cur_field,
					 expanded_bits,
					 what_to_declare, what_to_do);
	      }
	  }
      }
  }

  /* pass two - any cache fields not processed above */
  {
    cache_entry *cache_rule;
    for (cache_rule = cache_rules;
	 cache_rule != NULL; cache_rule = cache_rule->next)
      {
	if (filter_is_subset (instruction->field_names,
			      cache_rule->original_fields)
	    && !filter_is_member (instruction->field_names, cache_rule->name))
	  {
	    char *single_field =
	      filter_next (cache_rule->original_fields, "");
	    if (filter_next (cache_rule->original_fields, single_field) !=
		NULL)
	      single_field = NULL;
	    print_icache_extraction (file, instruction->format_name, cache_rule->entry_type, cache_rule->name, cache_rule->type, cache_rule->expression, single_field, cache_rule->line, NULL,	/* cur_field */
				     expanded_bits,
				     what_to_declare, what_to_do);
	  }
      }
  }

  lf_print__internal_ref (file);
}



typedef struct _form_fields form_fields;
struct _form_fields
{
  char *name;
  filter *fields;
  form_fields *next;
};

static form_fields *
insn_table_cache_fields (insn_table *isa)
{
  form_fields *forms = NULL;
  insn_entry *insn;
  for (insn = isa->insns; insn != NULL; insn = insn->next)
    {
      form_fields **form = &forms;
      while (1)
	{
	  if (*form == NULL)
	    {
	      /* new format name, add it */
	      form_fields *new_form = ZALLOC (form_fields);
	      new_form->name = insn->format_name;
	      filter_add (&new_form->fields, insn->field_names);
	      *form = new_form;
	      break;
	    }
	  else if (strcmp ((*form)->name, insn->format_name) == 0)
	    {
	      /* already present, add field names to the existing list */
	      filter_add (&(*form)->fields, insn->field_names);
	      break;
	    }
	  form = &(*form)->next;
	}
    }
  return forms;
}



extern void
print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules)
{
  /* Create a list of all the different instruction formats with their
     corresponding field names. */
  form_fields *formats = insn_table_cache_fields (isa);

  lf_printf (file, "\n");
  lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
	     options.module.global.prefix.u,
	     (options.gen.icache ? options.gen.icache_size : 0));
  lf_printf (file, "\n");

  /* create an instruction cache if being used */
  if (options.gen.icache)
    {
      lf_printf (file, "typedef struct _%sidecode_cache {\n",
		 options.module.global.prefix.l);
      lf_indent (file, +2);
      {
	form_fields *format;
	lf_printf (file, "unsigned_word address;\n");
	lf_printf (file, "void *semantic;\n");
	lf_printf (file, "union {\n");
	lf_indent (file, +2);
	for (format = formats; format != NULL; format = format->next)
	  {
	    lf_printf (file, "struct {\n");
	    lf_indent (file, +2);
	    {
	      cache_entry *cache_rule;
	      char *field;
	      /* space for any instruction words */
	      if (options.gen.insn_in_icache)
		lf_printf (file, "instruction_word insn[%d];\n",
			   isa->max_nr_words);
	      /* define an entry for any applicable cache rules */
	      for (cache_rule = cache_rules;
		   cache_rule != NULL; cache_rule = cache_rule->next)
		{
		  /* nb - sort of correct - should really check against
		     individual instructions */
		  if (filter_is_subset
		      (format->fields, cache_rule->original_fields))
		    {
		      char *memb;
		      lf_printf (file, "%s %s;",
				 (cache_rule->type == NULL
				  ? "unsigned"
				  : cache_rule->type), cache_rule->name);
		      lf_printf (file, " /*");
		      for (memb =
			   filter_next (cache_rule->original_fields, "");
			   memb != NULL;
			   memb =
			   filter_next (cache_rule->original_fields, memb))
			{
			  lf_printf (file, " %s", memb);
			}
		      lf_printf (file, " */\n");
		    }
		}
	      /* define an entry for any fields not covered by a cache rule */
	      for (field = filter_next (format->fields, "");
		   field != NULL; field = filter_next (format->fields, field))
		{
		  cache_entry *cache_rule;
		  int found_rule = 0;
		  for (cache_rule = cache_rules;
		       cache_rule != NULL; cache_rule = cache_rule->next)
		    {
		      if (strcmp (cache_rule->name, field) == 0)
			{
			  found_rule = 1;
			  break;
			}
		    }
		  if (!found_rule)
		    lf_printf (file, "unsigned %s; /* default */\n", field);
		}
	    }
	    lf_indent (file, -2);
	    lf_printf (file, "} %s;\n", format->name);
	  }
	lf_indent (file, -2);
	lf_printf (file, "} crack;\n");
      }
      lf_indent (file, -2);
      lf_printf (file, "} %sidecode_cache;\n",
		 options.module.global.prefix.l);
    }
  else
    {
      /* alernativly, since no cache, emit a dummy definition for
         idecode_cache so that code refering to the type can still compile */
      lf_printf (file, "typedef void %sidecode_cache;\n",
		 options.module.global.prefix.l);
    }
  lf_printf (file, "\n");
}



static void
print_icache_function (lf *file,
		       insn_entry * instruction,
		       opcode_bits *expanded_bits,
		       insn_opcodes *opcodes,
		       cache_entry *cache_rules, int nr_prefetched_words)
{
  int indent;

  /* generate code to enter decoded instruction into the icache */
  lf_printf (file, "\n");
  lf_print__function_type_function (file, print_icache_function_type,
				    "EXTERN_ICACHE", "\n");
  indent = print_function_name (file,
				instruction->name,
				instruction->format_name,
				NULL,
				expanded_bits, function_name_prefix_icache);
  indent += lf_printf (file, " ");
  lf_indent (file, +indent);
  lf_printf (file, "(");
  print_icache_function_formal (file, nr_prefetched_words);
  lf_printf (file, ")\n");
  lf_indent (file, -indent);

  /* function header */
  lf_printf (file, "{\n");
  lf_indent (file, +2);

  print_my_defines (file,
		    instruction->name,
		    instruction->format_name, expanded_bits);
  print_itrace (file, instruction, 1 /*putting-value-in-cache */ );

  print_idecode_validate (file, instruction, opcodes);

  lf_printf (file, "\n");
  lf_printf (file, "{\n");
  lf_indent (file, +2);
  if (options.gen.semantic_icache)
    lf_printf (file, "unsigned_word nia;\n");
  print_icache_body (file,
		     instruction,
		     expanded_bits,
		     cache_rules,
		     (options.gen.direct_access
		      ? define_variables
		      : declare_variables),
		     (options.gen.semantic_icache
		      ? both_values_and_icache
		      : put_values_in_icache), nr_prefetched_words);

  lf_printf (file, "\n");
  lf_printf (file, "cache_entry->address = cia;\n");
  lf_printf (file, "cache_entry->semantic = ");
  print_function_name (file,
		       instruction->name,
		       instruction->format_name,
		       NULL, expanded_bits, function_name_prefix_semantics);
  lf_printf (file, ";\n");
  lf_printf (file, "\n");

  if (options.gen.semantic_icache)
    {
      lf_printf (file, "/* semantic routine */\n");
      print_semantic_body (file, instruction, expanded_bits, opcodes);
      lf_printf (file, "return nia;\n");
    }

  if (!options.gen.semantic_icache)
    {
      lf_printf (file, "/* return the function proper */\n");
      lf_printf (file, "return ");
      print_function_name (file,
			   instruction->name,
			   instruction->format_name,
			   NULL,
			   expanded_bits, function_name_prefix_semantics);
      lf_printf (file, ";\n");
    }

  if (options.gen.direct_access)
    {
      print_icache_body (file,
			 instruction,
			 expanded_bits,
			 cache_rules,
			 undef_variables,
			 (options.gen.semantic_icache
			  ? both_values_and_icache
			  : put_values_in_icache), nr_prefetched_words);
    }

  lf_indent (file, -2);
  lf_printf (file, "}\n");
  lf_indent (file, -2);
  lf_printf (file, "}\n");
}


void
print_icache_definition (lf *file,
			 insn_entry * insn,
			 opcode_bits *expanded_bits,
			 insn_opcodes *opcodes,
			 cache_entry *cache_rules, int nr_prefetched_words)
{
  print_icache_function (file,
			 insn,
			 expanded_bits,
			 opcodes, cache_rules, nr_prefetched_words);
}



void
print_icache_internal_function_declaration (lf *file,
					    function_entry * function,
					    void *data)
{
  ASSERT (options.gen.icache);
  if (function->is_internal)
    {
      lf_printf (file, "\n");
      lf_print__function_type_function (file, print_icache_function_type,
					"INLINE_ICACHE", "\n");
      print_function_name (file,
			   function->name,
			   NULL, NULL, NULL, function_name_prefix_icache);
      lf_printf (file, "\n(");
      print_icache_function_formal (file, 0);
      lf_printf (file, ");\n");
    }
}


void
print_icache_internal_function_definition (lf *file,
					   function_entry * function,
					   void *data)
{
  ASSERT (options.gen.icache);
  if (function->is_internal)
    {
      lf_printf (file, "\n");
      lf_print__function_type_function (file, print_icache_function_type,
					"INLINE_ICACHE", "\n");
      print_function_name (file,
			   function->name,
			   NULL, NULL, NULL, function_name_prefix_icache);
      lf_printf (file, "\n(");
      print_icache_function_formal (file, 0);
      lf_printf (file, ")\n");
      lf_printf (file, "{\n");
      lf_indent (file, +2);
      lf_printf (file, "/* semantic routine */\n");
      if (options.gen.semantic_icache)
	{
	  lf_print__line_ref (file, function->code->line);
	  table_print_code (file, function->code);
	  lf_printf (file,
		     "error (\"Internal function must longjump\\n\");\n");
	  lf_printf (file, "return 0;\n");
	}
      else
	{
	  lf_printf (file, "return ");
	  print_function_name (file,
			       function->name,
			       NULL,
			       NULL, NULL, function_name_prefix_semantics);
	  lf_printf (file, ";\n");
	}

      lf_print__internal_ref (file);
      lf_indent (file, -2);
      lf_printf (file, "}\n");
    }
}
