Home | History | Annotate | Line # | Download | only in igen
      1 /* The IGEN simulator generator for GDB, the GNU Debugger.
      2 
      3    Copyright 2002-2024 Free Software Foundation, Inc.
      4 
      5    Contributed by Andrew Cagney.
      6 
      7    This file is part of GDB.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 3 of the License, or
     12    (at your option) any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21 
     22 
     23 #include "misc.h"
     24 #include "lf.h"
     25 #include "table.h"
     26 #include "filter.h"
     27 
     28 #include "igen.h"
     29 
     30 #include "ld-insn.h"
     31 #include "ld-decode.h"
     32 
     33 #include "gen.h"
     34 
     35 #include "gen-semantics.h"
     36 #include "gen-support.h"
     37 
     38 static void
     39 print_support_function_name (lf *file,
     40 			     const function_entry *function,
     41 			     int is_function_definition)
     42 {
     43   if (function->is_internal)
     44     {
     45       lf_print__function_type_function (file, print_semantic_function_type,
     46 					"INLINE_SUPPORT",
     47 					(is_function_definition ? "\n" :
     48 					 " "));
     49       print_function_name (file, function->name, NULL, NULL, NULL,
     50 			   function_name_prefix_semantics);
     51       lf_printf (file, "\n(");
     52       lf_indent (file, +1);
     53       print_semantic_function_formal (file, 0);
     54       lf_indent (file, -1);
     55       lf_printf (file, ")");
     56       if (!is_function_definition)
     57 	lf_printf (file, ";");
     58       lf_printf (file, "\n");
     59     }
     60   else
     61     {
     62       /* map the name onto a globally valid name */
     63       if (!is_function_definition
     64 	  && strcmp (options.module.support.prefix.l, "") != 0)
     65 	{
     66 	  lf_indent_suppress (file);
     67 	  lf_printf (file, "#define %s %s%s\n",
     68 		     function->name,
     69 		     options.module.support.prefix.l, function->name);
     70 	}
     71       lf_print__function_type (file,
     72 			       function->type,
     73 			       "INLINE_SUPPORT",
     74 			       (is_function_definition ? "\n" : " "));
     75       lf_printf (file, "%s%s\n(",
     76 		 options.module.support.prefix.l, function->name);
     77       if (options.gen.smp)
     78 	lf_printf (file,
     79 		   "sim_cpu *cpu, %sinstruction_address cia, int MY_INDEX",
     80 		   options.module.support.prefix.l);
     81       else
     82 	lf_printf (file,
     83 		   "SIM_DESC sd, %sinstruction_address cia, int MY_INDEX",
     84 		   options.module.support.prefix.l);
     85       if (function->param != NULL && strlen (function->param) > 0)
     86 	lf_printf (file, ", %s", function->param);
     87       lf_printf (file, ")%s", (is_function_definition ? "\n" : ";\n"));
     88     }
     89 }
     90 
     91 
     92 static void
     93 support_h_function (lf *file, const function_entry *function, void *data)
     94 {
     95   ASSERT (function->type != NULL);
     96   print_support_function_name (file, function, 0 /*!is_definition */ );
     97   lf_printf (file, "\n");
     98 }
     99 
    100 
    101 extern void
    102 gen_support_h (lf *file, const insn_table *table)
    103 {
    104   /* output the definition of `SD_' */
    105   if (options.gen.smp)
    106     {
    107       lf_printf (file, "#define SD CPU_STATE (cpu)\n");
    108       lf_printf (file, "#define CPU cpu\n");
    109       lf_printf (file, "#define CPU_ cpu\n");
    110     }
    111   else
    112     {
    113       lf_printf (file, "#define SD sd\n");
    114       lf_printf (file, "#define CPU (STATE_CPU (sd, 0))\n");
    115       lf_printf (file, "#define CPU_ sd\n");
    116     }
    117 
    118   lf_printf (file, "#define CIA_ cia\n");
    119   if (options.gen.delayed_branch)
    120     {
    121       lf_printf (file, "#define CIA cia.ip\n");
    122       lf_printf (file,
    123 		 "/* #define NIA nia.dp -- do not define, ambigious */\n");
    124     }
    125   else
    126     {
    127       lf_printf (file, "#define CIA cia\n");
    128       lf_printf (file, "#define NIA nia\n");
    129     }
    130   lf_printf (file, "\n");
    131 
    132   lf_printf (file, "#define SD_ CPU_, CIA_, MY_INDEX\n");
    133   lf_printf (file, "#define _SD SD_ /* deprecated */\n");
    134   lf_printf (file, "\n");
    135 
    136   /* Map <PREFIX>_xxxx onto the shorter xxxx for the following names:
    137 
    138      instruction_word
    139      idecode_issue
    140      semantic_illegal
    141 
    142      Map defined here as name space problems are created when the name is
    143      defined in idecode.h  */
    144   if (strcmp (options.module.idecode.prefix.l, "") != 0)
    145     {
    146       lf_indent_suppress (file);
    147       lf_printf (file, "#define %s %s%s\n",
    148 		 "instruction_word",
    149 		 options.module.idecode.prefix.l, "instruction_word");
    150       lf_printf (file, "\n");
    151       lf_indent_suppress (file);
    152       lf_printf (file, "#define %s %s%s\n",
    153 		 "idecode_issue",
    154 		 options.module.idecode.prefix.l, "idecode_issue");
    155       lf_printf (file, "\n");
    156       lf_indent_suppress (file);
    157       lf_printf (file, "#define %s %s%s\n",
    158 		 "semantic_illegal",
    159 		 options.module.idecode.prefix.l, "semantic_illegal");
    160       lf_printf (file, "\n");
    161     }
    162 
    163   /* output a declaration for all functions */
    164   function_entry_traverse (file, table->functions, support_h_function, NULL);
    165   lf_printf (file, "\n");
    166   lf_printf (file, "#if defined(SUPPORT_INLINE)\n");
    167   lf_printf (file, "# if ((SUPPORT_INLINE & INCLUDE_MODULE)\\\n");
    168   lf_printf (file, "      && (SUPPORT_INLINE & INCLUDED_BY_MODULE))\n");
    169   lf_printf (file, "#  include \"%ssupport.c\"\n",
    170 	     options.module.support.prefix.l);
    171   lf_printf (file, "# endif\n");
    172   lf_printf (file, "#endif\n");
    173 }
    174 
    175 static void
    176 support_c_function (lf *file, const function_entry *function, void *data)
    177 {
    178   ASSERT (function->type != NULL);
    179   print_support_function_name (file, function, 1 /*!is_definition */ );
    180   lf_printf (file, "{\n");
    181   lf_indent (file, +2);
    182   if (function->code == NULL)
    183     error (function->line, "Function without body (or null statement)\n");
    184   lf_print__line_ref (file, function->code->line);
    185   table_print_code (file, function->code);
    186   if (function->is_internal)
    187     {
    188       lf_printf (file,
    189 		 "sim_engine_abort (SD, CPU, cia, \"Internal function must longjump\\n\");\n");
    190       lf_printf (file, "return cia;\n");
    191     }
    192   lf_indent (file, -2);
    193   lf_printf (file, "}\n");
    194   lf_print__internal_ref (file);
    195   lf_printf (file, "\n");
    196 }
    197 
    198 
    199 void
    200 gen_support_c (lf *file, const insn_table *table)
    201 {
    202   lf_printf (file, "#include \"sim-main.h\"\n");
    203   lf_printf (file, "#include \"%sidecode.h\"\n",
    204 	     options.module.idecode.prefix.l);
    205   lf_printf (file, "#include \"%sitable.h\"\n",
    206 	     options.module.itable.prefix.l);
    207   lf_printf (file, "#include \"%ssupport.h\"\n",
    208 	     options.module.support.prefix.l);
    209   lf_printf (file, "\n");
    210 
    211   /* output a definition (c-code) for all functions */
    212   function_entry_traverse (file, table->functions, support_c_function, NULL);
    213 }
    214