/* 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"

#include "gen-semantics.h"
#include "gen-support.h"

static void
print_support_function_name (lf *file,
			     const function_entry *function,
			     int is_function_definition)
{
  if (function->is_internal)
    {
      lf_print__function_type_function (file, print_semantic_function_type,
					"INLINE_SUPPORT",
					(is_function_definition ? "\n" :
					 " "));
      print_function_name (file, function->name, NULL, NULL, NULL,
			   function_name_prefix_semantics);
      lf_printf (file, "\n(");
      lf_indent (file, +1);
      print_semantic_function_formal (file, 0);
      lf_indent (file, -1);
      lf_printf (file, ")");
      if (!is_function_definition)
	lf_printf (file, ";");
      lf_printf (file, "\n");
    }
  else
    {
      /* map the name onto a globally valid name */
      if (!is_function_definition
	  && strcmp (options.module.support.prefix.l, "") != 0)
	{
	  lf_indent_suppress (file);
	  lf_printf (file, "#define %s %s%s\n",
		     function->name,
		     options.module.support.prefix.l, function->name);
	}
      lf_print__function_type (file,
			       function->type,
			       "INLINE_SUPPORT",
			       (is_function_definition ? "\n" : " "));
      lf_printf (file, "%s%s\n(",
		 options.module.support.prefix.l, function->name);
      if (options.gen.smp)
	lf_printf (file,
		   "sim_cpu *cpu, %sinstruction_address cia, int MY_INDEX",
		   options.module.support.prefix.l);
      else
	lf_printf (file,
		   "SIM_DESC sd, %sinstruction_address cia, int MY_INDEX",
		   options.module.support.prefix.l);
      if (function->param != NULL && strlen (function->param) > 0)
	lf_printf (file, ", %s", function->param);
      lf_printf (file, ")%s", (is_function_definition ? "\n" : ";\n"));
    }
}


static void
support_h_function (lf *file, const function_entry *function, void *data)
{
  ASSERT (function->type != NULL);
  print_support_function_name (file, function, 0 /*!is_definition */ );
  lf_printf (file, "\n");
}


extern void
gen_support_h (lf *file, const insn_table *table)
{
  /* output the definition of `SD_' */
  if (options.gen.smp)
    {
      lf_printf (file, "#define SD CPU_STATE (cpu)\n");
      lf_printf (file, "#define CPU cpu\n");
      lf_printf (file, "#define CPU_ cpu\n");
    }
  else
    {
      lf_printf (file, "#define SD sd\n");
      lf_printf (file, "#define CPU (STATE_CPU (sd, 0))\n");
      lf_printf (file, "#define CPU_ sd\n");
    }

  lf_printf (file, "#define CIA_ cia\n");
  if (options.gen.delayed_branch)
    {
      lf_printf (file, "#define CIA cia.ip\n");
      lf_printf (file,
		 "/* #define NIA nia.dp -- do not define, ambigious */\n");
    }
  else
    {
      lf_printf (file, "#define CIA cia\n");
      lf_printf (file, "#define NIA nia\n");
    }
  lf_printf (file, "\n");

  lf_printf (file, "#define SD_ CPU_, CIA_, MY_INDEX\n");
  lf_printf (file, "#define _SD SD_ /* deprecated */\n");
  lf_printf (file, "\n");

  /* Map <PREFIX>_xxxx onto the shorter xxxx for the following names:

     instruction_word
     idecode_issue
     semantic_illegal

     Map defined here as name space problems are created when the name is
     defined in idecode.h  */
  if (strcmp (options.module.idecode.prefix.l, "") != 0)
    {
      lf_indent_suppress (file);
      lf_printf (file, "#define %s %s%s\n",
		 "instruction_word",
		 options.module.idecode.prefix.l, "instruction_word");
      lf_printf (file, "\n");
      lf_indent_suppress (file);
      lf_printf (file, "#define %s %s%s\n",
		 "idecode_issue",
		 options.module.idecode.prefix.l, "idecode_issue");
      lf_printf (file, "\n");
      lf_indent_suppress (file);
      lf_printf (file, "#define %s %s%s\n",
		 "semantic_illegal",
		 options.module.idecode.prefix.l, "semantic_illegal");
      lf_printf (file, "\n");
    }

  /* output a declaration for all functions */
  function_entry_traverse (file, table->functions, support_h_function, NULL);
  lf_printf (file, "\n");
  lf_printf (file, "#if defined(SUPPORT_INLINE)\n");
  lf_printf (file, "# if ((SUPPORT_INLINE & INCLUDE_MODULE)\\\n");
  lf_printf (file, "      && (SUPPORT_INLINE & INCLUDED_BY_MODULE))\n");
  lf_printf (file, "#  include \"%ssupport.c\"\n",
	     options.module.support.prefix.l);
  lf_printf (file, "# endif\n");
  lf_printf (file, "#endif\n");
}

static void
support_c_function (lf *file, const function_entry *function, void *data)
{
  ASSERT (function->type != NULL);
  print_support_function_name (file, function, 1 /*!is_definition */ );
  lf_printf (file, "{\n");
  lf_indent (file, +2);
  if (function->code == NULL)
    error (function->line, "Function without body (or null statement)\n");
  lf_print__line_ref (file, function->code->line);
  table_print_code (file, function->code);
  if (function->is_internal)
    {
      lf_printf (file,
		 "sim_engine_abort (SD, CPU, cia, \"Internal function must longjump\\n\");\n");
      lf_printf (file, "return cia;\n");
    }
  lf_indent (file, -2);
  lf_printf (file, "}\n");
  lf_print__internal_ref (file);
  lf_printf (file, "\n");
}


void
gen_support_c (lf *file, const insn_table *table)
{
  lf_printf (file, "#include \"sim-main.h\"\n");
  lf_printf (file, "#include \"%sidecode.h\"\n",
	     options.module.idecode.prefix.l);
  lf_printf (file, "#include \"%sitable.h\"\n",
	     options.module.itable.prefix.l);
  lf_printf (file, "#include \"%ssupport.h\"\n",
	     options.module.support.prefix.l);
  lf_printf (file, "\n");

  /* output a definition (c-code) for all functions */
  function_entry_traverse (file, table->functions, support_c_function, NULL);
}
