xref: /netbsd-src/external/gpl3/gdb/dist/sim/igen/igen.c (revision 71f621822dbfd5073a314948bec169b7bb05f7be)
14e98e3e1Schristos /* The IGEN simulator generator for GDB, the GNU Debugger.
24e98e3e1Schristos 
3*71f62182Schristos    Copyright 2002-2024 Free Software Foundation, Inc.
44e98e3e1Schristos 
54e98e3e1Schristos    Contributed by Andrew Cagney.
64e98e3e1Schristos 
74e98e3e1Schristos    This file is part of GDB.
84e98e3e1Schristos 
94e98e3e1Schristos    This program is free software; you can redistribute it and/or modify
104e98e3e1Schristos    it under the terms of the GNU General Public License as published by
114e98e3e1Schristos    the Free Software Foundation; either version 3 of the License, or
124e98e3e1Schristos    (at your option) any later version.
134e98e3e1Schristos 
144e98e3e1Schristos    This program is distributed in the hope that it will be useful,
154e98e3e1Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
164e98e3e1Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
174e98e3e1Schristos    GNU General Public License for more details.
184e98e3e1Schristos 
194e98e3e1Schristos    You should have received a copy of the GNU General Public License
204e98e3e1Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
214e98e3e1Schristos 
224e98e3e1Schristos #include <getopt.h>
234b169a6bSchristos #include <stdlib.h>
244e98e3e1Schristos 
254e98e3e1Schristos #include "misc.h"
264e98e3e1Schristos #include "lf.h"
274e98e3e1Schristos #include "table.h"
284e98e3e1Schristos #include "filter.h"
294e98e3e1Schristos 
304e98e3e1Schristos #include "igen.h"
314e98e3e1Schristos 
324e98e3e1Schristos #include "ld-insn.h"
334e98e3e1Schristos #include "ld-decode.h"
344e98e3e1Schristos #include "ld-cache.h"
354e98e3e1Schristos 
364e98e3e1Schristos #include "gen.h"
374e98e3e1Schristos 
384e98e3e1Schristos #include "gen-model.h"
394e98e3e1Schristos #include "gen-icache.h"
404e98e3e1Schristos #include "gen-itable.h"
414e98e3e1Schristos #include "gen-idecode.h"
424e98e3e1Schristos #include "gen-semantics.h"
434e98e3e1Schristos #include "gen-engine.h"
444e98e3e1Schristos #include "gen-support.h"
454e98e3e1Schristos #include "gen-engine.h"
464e98e3e1Schristos 
474e98e3e1Schristos 
484e98e3e1Schristos /****************************************************************/
494e98e3e1Schristos 
504e98e3e1Schristos 
514e98e3e1Schristos /* Semantic functions */
524e98e3e1Schristos 
534e98e3e1Schristos int
544e98e3e1Schristos print_semantic_function_formal (lf *file, int nr_prefetched_words)
554e98e3e1Schristos {
564e98e3e1Schristos   int nr = 0;
574e98e3e1Schristos   int word_nr;
584e98e3e1Schristos   if (options.gen.icache || nr_prefetched_words < 0)
594e98e3e1Schristos     {
604e98e3e1Schristos       nr += lf_printf (file, "SIM_DESC sd,\n");
614e98e3e1Schristos       nr += lf_printf (file, "%sidecode_cache *cache_entry,\n",
624e98e3e1Schristos 		       options.module.global.prefix.l);
634e98e3e1Schristos       nr += lf_printf (file, "%sinstruction_address cia",
644e98e3e1Schristos 		       options.module.global.prefix.l);
654e98e3e1Schristos     }
664e98e3e1Schristos   else if (options.gen.smp)
674e98e3e1Schristos     {
684e98e3e1Schristos       nr += lf_printf (file, "sim_cpu *cpu,\n");
694e98e3e1Schristos       for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
704e98e3e1Schristos 	{
714e98e3e1Schristos 	  nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
724e98e3e1Schristos 			   options.module.global.prefix.l, word_nr);
734e98e3e1Schristos 	}
744e98e3e1Schristos       nr += lf_printf (file, "%sinstruction_address cia",
754e98e3e1Schristos 		       options.module.global.prefix.l);
764e98e3e1Schristos     }
774e98e3e1Schristos   else
784e98e3e1Schristos     {
794e98e3e1Schristos       nr += lf_printf (file, "SIM_DESC sd,\n");
804e98e3e1Schristos       for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
814e98e3e1Schristos 	{
824e98e3e1Schristos 	  nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
834e98e3e1Schristos 			   options.module.global.prefix.l, word_nr);
844e98e3e1Schristos 	}
854e98e3e1Schristos       nr += lf_printf (file, "%sinstruction_address cia",
864e98e3e1Schristos 		       options.module.global.prefix.l);
874e98e3e1Schristos     }
884e98e3e1Schristos   return nr;
894e98e3e1Schristos }
904e98e3e1Schristos 
914e98e3e1Schristos int
924e98e3e1Schristos print_semantic_function_actual (lf *file, int nr_prefetched_words)
934e98e3e1Schristos {
944e98e3e1Schristos   int nr = 0;
954e98e3e1Schristos   int word_nr;
964e98e3e1Schristos   if (options.gen.icache || nr_prefetched_words < 0)
974e98e3e1Schristos     {
984e98e3e1Schristos       nr += lf_printf (file, "sd, cache_entry, cia");
994e98e3e1Schristos     }
1004e98e3e1Schristos   else
1014e98e3e1Schristos     {
1024e98e3e1Schristos       if (options.gen.smp)
1034e98e3e1Schristos 	nr += lf_printf (file, "cpu");
1044e98e3e1Schristos       else
1054e98e3e1Schristos 	nr += lf_printf (file, "sd");
1064e98e3e1Schristos       for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
1074e98e3e1Schristos 	nr += lf_printf (file, ", instruction_%d", word_nr);
1084e98e3e1Schristos       nr += lf_printf (file, ", cia");
1094e98e3e1Schristos     }
1104e98e3e1Schristos   return nr;
1114e98e3e1Schristos }
1124e98e3e1Schristos 
1134e98e3e1Schristos int
1144e98e3e1Schristos print_semantic_function_type (lf *file)
1154e98e3e1Schristos {
1164e98e3e1Schristos   int nr = 0;
1174e98e3e1Schristos   nr += lf_printf (file, "%sinstruction_address",
1184e98e3e1Schristos 		   options.module.global.prefix.l);
1194e98e3e1Schristos   return nr;
1204e98e3e1Schristos }
1214e98e3e1Schristos 
1224e98e3e1Schristos 
1234e98e3e1Schristos /* Idecode functions */
1244e98e3e1Schristos 
1254e98e3e1Schristos int
1264e98e3e1Schristos print_icache_function_formal (lf *file, int nr_prefetched_words)
1274e98e3e1Schristos {
1284e98e3e1Schristos   int nr = 0;
1294e98e3e1Schristos   int word_nr;
1304e98e3e1Schristos   if (options.gen.smp)
1314e98e3e1Schristos     nr += lf_printf (file, "sim_cpu *cpu,\n");
1324e98e3e1Schristos   else
1334e98e3e1Schristos     nr += lf_printf (file, "SIM_DESC sd,\n");
1344e98e3e1Schristos   for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
1354e98e3e1Schristos     nr += lf_printf (file, " %sinstruction_word instruction_%d,\n",
1364e98e3e1Schristos 		     options.module.global.prefix.l, word_nr);
1374e98e3e1Schristos   nr += lf_printf (file, " %sinstruction_address cia,\n",
1384e98e3e1Schristos 		   options.module.global.prefix.l);
1394e98e3e1Schristos   nr += lf_printf (file, " %sidecode_cache *cache_entry",
1404e98e3e1Schristos 		   options.module.global.prefix.l);
1414e98e3e1Schristos   return nr;
1424e98e3e1Schristos }
1434e98e3e1Schristos 
1444e98e3e1Schristos int
1454e98e3e1Schristos print_icache_function_actual (lf *file, int nr_prefetched_words)
1464e98e3e1Schristos {
1474e98e3e1Schristos   int nr = 0;
1484e98e3e1Schristos   int word_nr;
1494e98e3e1Schristos   if (options.gen.smp)
1504e98e3e1Schristos     nr += lf_printf (file, "cpu");
1514e98e3e1Schristos   else
1524e98e3e1Schristos     nr += lf_printf (file, "sd");
1534e98e3e1Schristos   for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
1544e98e3e1Schristos     nr += lf_printf (file, ", instruction_%d", word_nr);
1554e98e3e1Schristos   nr += lf_printf (file, ", cia, cache_entry");
1564e98e3e1Schristos   return nr;
1574e98e3e1Schristos }
1584e98e3e1Schristos 
1594e98e3e1Schristos int
1604e98e3e1Schristos print_icache_function_type (lf *file)
1614e98e3e1Schristos {
1624e98e3e1Schristos   int nr;
1634e98e3e1Schristos   if (options.gen.semantic_icache)
1644e98e3e1Schristos     {
1654e98e3e1Schristos       nr = print_semantic_function_type (file);
1664e98e3e1Schristos     }
1674e98e3e1Schristos   else
1684e98e3e1Schristos     {
1694e98e3e1Schristos       nr = lf_printf (file, "%sidecode_semantic *",
1704e98e3e1Schristos 		      options.module.global.prefix.l);
1714e98e3e1Schristos     }
1724e98e3e1Schristos   return nr;
1734e98e3e1Schristos }
1744e98e3e1Schristos 
1754e98e3e1Schristos 
1764e98e3e1Schristos /* Function names */
1774e98e3e1Schristos 
1784e98e3e1Schristos static int
1794b169a6bSchristos print_opcode_bits (lf *file, const opcode_bits *bits)
1804e98e3e1Schristos {
1814e98e3e1Schristos   int nr = 0;
1824e98e3e1Schristos   if (bits == NULL)
1834e98e3e1Schristos     return nr;
1844e98e3e1Schristos   nr += lf_putchr (file, '_');
1854e98e3e1Schristos   nr += lf_putstr (file, bits->field->val_string);
1864e98e3e1Schristos   if (bits->opcode->is_boolean && bits->value == 0)
1874e98e3e1Schristos     nr += lf_putint (file, bits->opcode->boolean_constant);
1884e98e3e1Schristos   else if (!bits->opcode->is_boolean)
1894e98e3e1Schristos     {
1904e98e3e1Schristos       if (bits->opcode->last < bits->field->last)
1914e98e3e1Schristos 	nr +=
1924e98e3e1Schristos 	  lf_putint (file,
1934e98e3e1Schristos 		     bits->value << (bits->field->last - bits->opcode->last));
1944e98e3e1Schristos       else
1954e98e3e1Schristos 	nr += lf_putint (file, bits->value);
1964e98e3e1Schristos     }
1974e98e3e1Schristos   nr += print_opcode_bits (file, bits->next);
1984e98e3e1Schristos   return nr;
1994e98e3e1Schristos }
2004e98e3e1Schristos 
2014e98e3e1Schristos static int
2024e98e3e1Schristos print_c_name (lf *file, const char *name)
2034e98e3e1Schristos {
2044e98e3e1Schristos   int nr = 0;
2054e98e3e1Schristos   const char *pos;
2064e98e3e1Schristos   for (pos = name; *pos != '\0'; pos++)
2074e98e3e1Schristos     {
2084e98e3e1Schristos       switch (*pos)
2094e98e3e1Schristos 	{
2104e98e3e1Schristos 	case '/':
2114e98e3e1Schristos 	case '-':
2124e98e3e1Schristos 	  break;
2134e98e3e1Schristos 	case ' ':
2144e98e3e1Schristos 	case '.':
2154e98e3e1Schristos 	  nr += lf_putchr (file, '_');
2164e98e3e1Schristos 	  break;
2174e98e3e1Schristos 	default:
2184e98e3e1Schristos 	  nr += lf_putchr (file, *pos);
2194e98e3e1Schristos 	  break;
2204e98e3e1Schristos 	}
2214e98e3e1Schristos     }
2224e98e3e1Schristos   return nr;
2234e98e3e1Schristos }
2244e98e3e1Schristos 
2254e98e3e1Schristos extern int
2264e98e3e1Schristos print_function_name (lf *file,
2274e98e3e1Schristos 		     const char *basename,
2284e98e3e1Schristos 		     const char *format_name,
2294e98e3e1Schristos 		     const char *model_name,
2304b169a6bSchristos 		     const opcode_bits *expanded_bits,
2314e98e3e1Schristos 		     lf_function_name_prefixes prefix)
2324e98e3e1Schristos {
2334e98e3e1Schristos   int nr = 0;
2344e98e3e1Schristos   /* the prefix */
2354e98e3e1Schristos   switch (prefix)
2364e98e3e1Schristos     {
2374e98e3e1Schristos     case function_name_prefix_semantics:
2384e98e3e1Schristos       nr += lf_printf (file, "%s", options.module.semantics.prefix.l);
2394e98e3e1Schristos       nr += lf_printf (file, "semantic_");
2404e98e3e1Schristos       break;
2414e98e3e1Schristos     case function_name_prefix_idecode:
2424e98e3e1Schristos       nr += lf_printf (file, "%s", options.module.idecode.prefix.l);
2434e98e3e1Schristos       nr += lf_printf (file, "idecode_");
2444e98e3e1Schristos       break;
2454e98e3e1Schristos     case function_name_prefix_itable:
2464e98e3e1Schristos       nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l);
2474e98e3e1Schristos       break;
2484e98e3e1Schristos     case function_name_prefix_icache:
2494e98e3e1Schristos       nr += lf_printf (file, "%s", options.module.icache.prefix.l);
2504e98e3e1Schristos       nr += lf_printf (file, "icache_");
2514e98e3e1Schristos       break;
2524e98e3e1Schristos     case function_name_prefix_engine:
2534e98e3e1Schristos       nr += lf_printf (file, "%s", options.module.engine.prefix.l);
2544e98e3e1Schristos       nr += lf_printf (file, "engine_");
2554e98e3e1Schristos     default:
2564e98e3e1Schristos       break;
2574e98e3e1Schristos     }
2584e98e3e1Schristos 
2594e98e3e1Schristos   if (model_name != NULL)
2604e98e3e1Schristos     {
2614e98e3e1Schristos       nr += print_c_name (file, model_name);
2624e98e3e1Schristos       nr += lf_printf (file, "_");
2634e98e3e1Schristos     }
2644e98e3e1Schristos 
2654e98e3e1Schristos   /* the function name */
2664e98e3e1Schristos   nr += print_c_name (file, basename);
2674e98e3e1Schristos 
2684e98e3e1Schristos   /* the format name if available */
2694e98e3e1Schristos   if (format_name != NULL)
2704e98e3e1Schristos     {
2714e98e3e1Schristos       nr += lf_printf (file, "_");
2724e98e3e1Schristos       nr += print_c_name (file, format_name);
2734e98e3e1Schristos     }
2744e98e3e1Schristos 
2754e98e3e1Schristos   /* the suffix */
2764e98e3e1Schristos   nr += print_opcode_bits (file, expanded_bits);
2774e98e3e1Schristos 
2784e98e3e1Schristos   return nr;
2794e98e3e1Schristos }
2804e98e3e1Schristos 
2814e98e3e1Schristos 
2824e98e3e1Schristos void
2834e98e3e1Schristos print_my_defines (lf *file,
2844e98e3e1Schristos 		  const char *basename,
2854b169a6bSchristos 		  const char *format_name,
2864b169a6bSchristos 		  const opcode_bits *expanded_bits)
2874e98e3e1Schristos {
2884e98e3e1Schristos   /* #define MY_INDEX xxxxx */
2894e98e3e1Schristos   lf_indent_suppress (file);
2904e98e3e1Schristos   lf_printf (file, "#undef MY_INDEX\n");
2914e98e3e1Schristos   lf_indent_suppress (file);
2924e98e3e1Schristos   lf_printf (file, "#define MY_INDEX ");
2934e98e3e1Schristos   print_function_name (file,
2944e98e3e1Schristos 		       basename, format_name, NULL,
2954e98e3e1Schristos 		       NULL, function_name_prefix_itable);
2964e98e3e1Schristos   lf_printf (file, "\n");
2974e98e3e1Schristos   /* #define MY_PREFIX xxxxxx */
2984e98e3e1Schristos   lf_indent_suppress (file);
2994e98e3e1Schristos   lf_printf (file, "#undef ");
3004e98e3e1Schristos   print_function_name (file,
3014e98e3e1Schristos 		       basename, format_name, NULL,
3024e98e3e1Schristos 		       expanded_bits, function_name_prefix_none);
3034e98e3e1Schristos   lf_printf (file, "\n");
3044e98e3e1Schristos   lf_indent_suppress (file);
3054e98e3e1Schristos   lf_printf (file, "#undef MY_PREFIX\n");
3064e98e3e1Schristos   lf_indent_suppress (file);
3074e98e3e1Schristos   lf_printf (file, "#define MY_PREFIX ");
3084e98e3e1Schristos   print_function_name (file,
3094e98e3e1Schristos 		       basename, format_name, NULL,
3104e98e3e1Schristos 		       expanded_bits, function_name_prefix_none);
3114e98e3e1Schristos   lf_printf (file, "\n");
3124e98e3e1Schristos   /* #define MY_NAME xxxxxx */
3134e98e3e1Schristos   lf_indent_suppress (file);
3144e98e3e1Schristos   lf_indent_suppress (file);
3154e98e3e1Schristos   lf_printf (file, "#undef MY_NAME\n");
3164e98e3e1Schristos   lf_indent_suppress (file);
3174e98e3e1Schristos   lf_printf (file, "#define MY_NAME \"");
3184e98e3e1Schristos   print_function_name (file,
3194e98e3e1Schristos 		       basename, format_name, NULL,
3204e98e3e1Schristos 		       expanded_bits, function_name_prefix_none);
3214e98e3e1Schristos   lf_printf (file, "\"\n");
3224e98e3e1Schristos }
3234e98e3e1Schristos 
3244e98e3e1Schristos 
3254e98e3e1Schristos static int
3264e98e3e1Schristos print_itrace_prefix (lf *file)
3274e98e3e1Schristos {
3284e98e3e1Schristos   const char *prefix = "trace_prefix (";
3294e98e3e1Schristos   int indent = strlen (prefix);
3304e98e3e1Schristos   lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n",
3314e98e3e1Schristos 	     prefix);
3324e98e3e1Schristos   lf_indent (file, +indent);
3334e98e3e1Schristos   lf_printf (file, "%sitable[MY_INDEX].file, \\\n",
3344e98e3e1Schristos 	     options.module.itable.prefix.l);
3354e98e3e1Schristos   lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n",
3364e98e3e1Schristos 	     options.module.itable.prefix.l);
3374e98e3e1Schristos   lf_printf (file, "\"");
3384e98e3e1Schristos   return indent;
3394e98e3e1Schristos }
3404e98e3e1Schristos 
3414e98e3e1Schristos 
3424e98e3e1Schristos static void
3434b169a6bSchristos print_itrace_format (lf *file, const insn_mnemonic_entry *assembler)
3444e98e3e1Schristos {
3454e98e3e1Schristos   /* pass=1 is fmt string; pass=2 is arguments */
3464e98e3e1Schristos   int pass;
3474e98e3e1Schristos   /* print the format string */
3484e98e3e1Schristos   for (pass = 1; pass <= 2; pass++)
3494e98e3e1Schristos     {
3504e98e3e1Schristos       const char *chp = assembler->format;
3514e98e3e1Schristos       chp++;			/* skip the leading quote */
3524e98e3e1Schristos       /* write out the format/args */
3534e98e3e1Schristos       while (*chp != '\0')
3544e98e3e1Schristos 	{
3554e98e3e1Schristos 	  if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>'))
3564e98e3e1Schristos 	    {
3574e98e3e1Schristos 	      if (pass == 1)
3584e98e3e1Schristos 		lf_putchr (file, chp[1]);
3594e98e3e1Schristos 	      chp += 2;
3604e98e3e1Schristos 	    }
3614e98e3e1Schristos 	  else if (chp[0] == '<' || chp[0] == '%')
3624e98e3e1Schristos 	    {
3634e98e3e1Schristos 	      /* parse [ "%" ... ] "<" [ func "#" ] param ">" */
3644e98e3e1Schristos 	      const char *fmt;
3654e98e3e1Schristos 	      const char *func;
3664e98e3e1Schristos 	      int strlen_func;
3674e98e3e1Schristos 	      const char *param;
3684e98e3e1Schristos 	      int strlen_param;
3694e98e3e1Schristos 	      /* the "%" ... "<" format */
3704e98e3e1Schristos 	      fmt = chp;
3714e98e3e1Schristos 	      while (chp[0] != '<' && chp[0] != '\0')
3724e98e3e1Schristos 		chp++;
3734e98e3e1Schristos 	      if (chp[0] != '<')
3744e98e3e1Schristos 		error (assembler->line, "Missing `<' after `%%'\n");
3754e98e3e1Schristos 	      chp++;
3764e98e3e1Schristos 	      /* [ "func" # ] OR "param" */
3774e98e3e1Schristos 	      func = chp;
3784e98e3e1Schristos 	      param = chp;
3794e98e3e1Schristos 	      while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0')
3804e98e3e1Schristos 		chp++;
3814e98e3e1Schristos 	      strlen_func = chp - func;
3824e98e3e1Schristos 	      if (chp[0] == '#')
3834e98e3e1Schristos 		{
3844e98e3e1Schristos 		  chp++;
3854e98e3e1Schristos 		  param = chp;
3864e98e3e1Schristos 		  while (chp[0] != '>' && chp[0] != '\0')
3874e98e3e1Schristos 		    chp++;
3884e98e3e1Schristos 		}
3894e98e3e1Schristos 	      strlen_param = chp - param;
3904e98e3e1Schristos 	      if (chp[0] != '>')
3914e98e3e1Schristos 		error (assembler->line,
3924e98e3e1Schristos 		       "Missing closing `>' in assembler string\n");
3934e98e3e1Schristos 	      chp++;
3944e98e3e1Schristos 	      /* now process it */
3954e98e3e1Schristos 	      if (pass == 2)
3964e98e3e1Schristos 		lf_printf (file, ", \\\n");
3974e98e3e1Schristos 	      if (strncmp (fmt, "<", 1) == 0)
3984e98e3e1Schristos 		/* implicit long int format */
3994e98e3e1Schristos 		{
4004e98e3e1Schristos 		  if (pass == 1)
4014e98e3e1Schristos 		    lf_printf (file, "%%ld");
4024e98e3e1Schristos 		  else
4034e98e3e1Schristos 		    {
4044e98e3e1Schristos 		      lf_printf (file, "(long) ");
4054e98e3e1Schristos 		      lf_write (file, param, strlen_param);
4064e98e3e1Schristos 		    }
4074e98e3e1Schristos 		}
4084e98e3e1Schristos 	      else if (strncmp (fmt, "%<", 2) == 0)
4094e98e3e1Schristos 		/* explicit format */
4104e98e3e1Schristos 		{
4114e98e3e1Schristos 		  if (pass == 1)
4124e98e3e1Schristos 		    lf_printf (file, "%%");
4134e98e3e1Schristos 		  else
4144e98e3e1Schristos 		    lf_write (file, param, strlen_param);
4154e98e3e1Schristos 		}
4164e98e3e1Schristos 	      else if (strncmp (fmt, "%s<", 3) == 0)
4174e98e3e1Schristos 		/* string format */
4184e98e3e1Schristos 		{
4194e98e3e1Schristos 		  if (pass == 1)
4204e98e3e1Schristos 		    lf_printf (file, "%%s");
4214e98e3e1Schristos 		  else
4224e98e3e1Schristos 		    {
4234e98e3e1Schristos 		      lf_printf (file, "%sstr_",
4244e98e3e1Schristos 				 options.module.global.prefix.l);
4254e98e3e1Schristos 		      lf_write (file, func, strlen_func);
4264e98e3e1Schristos 		      lf_printf (file, " (SD_, ");
4274e98e3e1Schristos 		      lf_write (file, param, strlen_param);
4284e98e3e1Schristos 		      lf_printf (file, ")");
4294e98e3e1Schristos 		    }
4304e98e3e1Schristos 		}
4314e98e3e1Schristos 	      else if (strncmp (fmt, "%lx<", 4) == 0)
4324e98e3e1Schristos 		/* simple hex */
4334e98e3e1Schristos 		{
4344e98e3e1Schristos 		  if (pass == 1)
4354e98e3e1Schristos 		    lf_printf (file, "%%lx");
4364e98e3e1Schristos 		  else
4374e98e3e1Schristos 		    {
4384e98e3e1Schristos 		      lf_printf (file, "(unsigned long) ");
4394e98e3e1Schristos 		      lf_write (file, param, strlen_param);
4404e98e3e1Schristos 		    }
4414e98e3e1Schristos 		}
4424e98e3e1Schristos 	      else if (strncmp (fmt, "%#lx<", 5) == 0)
4434e98e3e1Schristos 		/* simple hex with 0x prefix */
4444e98e3e1Schristos 		{
4454e98e3e1Schristos 		  if (pass == 1)
4464e98e3e1Schristos 		    lf_printf (file, "%%#lx");
4474e98e3e1Schristos 		  else
4484e98e3e1Schristos 		    {
4494e98e3e1Schristos 		      lf_printf (file, "(unsigned long) ");
4504e98e3e1Schristos 		      lf_write (file, param, strlen_param);
4514e98e3e1Schristos 		    }
4524e98e3e1Schristos 		}
4534e98e3e1Schristos 	      else if (strncmp (fmt, "%08lx<", 6) == 0)
4544e98e3e1Schristos 		/* simple hex */
4554e98e3e1Schristos 		{
4564e98e3e1Schristos 		  if (pass == 1)
4574e98e3e1Schristos 		    lf_printf (file, "%%08lx");
4584e98e3e1Schristos 		  else
4594e98e3e1Schristos 		    {
4604e98e3e1Schristos 		      lf_printf (file, "(unsigned long) ");
4614e98e3e1Schristos 		      lf_write (file, param, strlen_param);
4624e98e3e1Schristos 		    }
4634e98e3e1Schristos 		}
4644e98e3e1Schristos 	      else
4654e98e3e1Schristos 		error (assembler->line, "Unknown assembler string format\n");
4664e98e3e1Schristos 	    }
4674e98e3e1Schristos 	  else
4684e98e3e1Schristos 	    {
4694e98e3e1Schristos 	      if (pass == 1)
4704e98e3e1Schristos 		lf_putchr (file, chp[0]);
4714e98e3e1Schristos 	      chp += 1;
4724e98e3e1Schristos 	    }
4734e98e3e1Schristos 	}
4744e98e3e1Schristos     }
4754e98e3e1Schristos   lf_printf (file, ");\n");
4764e98e3e1Schristos }
4774e98e3e1Schristos 
4784e98e3e1Schristos 
4794e98e3e1Schristos void
4804b169a6bSchristos print_itrace (lf *file, const insn_entry *insn, int idecode)
4814e98e3e1Schristos {
4824e98e3e1Schristos   /* NB: Here we escape each EOLN. This is so that the the compiler
4834e98e3e1Schristos      treats a trace function call as a single line.  Consequently any
4844e98e3e1Schristos      errors in the line are refered back to the same igen assembler
4854e98e3e1Schristos      source line */
4864e98e3e1Schristos   const char *phase = (idecode) ? "DECODE" : "INSN";
4874e98e3e1Schristos   lf_printf (file, "\n");
4884e98e3e1Schristos   lf_indent_suppress (file);
4894e98e3e1Schristos   lf_printf (file, "#if defined (WITH_TRACE)\n");
4904e98e3e1Schristos   lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n");
4914e98e3e1Schristos   lf_printf (file, "if (TRACE_ANY_P (CPU))\n");
4924e98e3e1Schristos   lf_printf (file, "  {\n");
4934e98e3e1Schristos   lf_indent (file, +4);
4944e98e3e1Schristos   {
4954e98e3e1Schristos     if (insn->mnemonics != NULL)
4964e98e3e1Schristos       {
4974e98e3e1Schristos 	insn_mnemonic_entry *assembler = insn->mnemonics;
4984e98e3e1Schristos 	int is_first = 1;
4994e98e3e1Schristos 	do
5004e98e3e1Schristos 	  {
5014e98e3e1Schristos 	    if (assembler->condition != NULL)
5024e98e3e1Schristos 	      {
5034e98e3e1Schristos 		int indent;
5044e98e3e1Schristos 		lf_printf (file, "%sif (%s)\n",
5054e98e3e1Schristos 			   is_first ? "" : "else ", assembler->condition);
5064e98e3e1Schristos 		lf_indent (file, +2);
5074e98e3e1Schristos 		lf_print__line_ref (file, assembler->line);
5084e98e3e1Schristos 		indent = print_itrace_prefix (file);
5094e98e3e1Schristos 		print_itrace_format (file, assembler);
5104e98e3e1Schristos 		lf_print__internal_ref (file);
5114e98e3e1Schristos 		lf_indent (file, -indent);
5124e98e3e1Schristos 		lf_indent (file, -2);
5134e98e3e1Schristos 		if (assembler->next == NULL)
5144e98e3e1Schristos 		  error (assembler->line,
5154e98e3e1Schristos 			 "Missing final unconditional assembler\n");
5164e98e3e1Schristos 	      }
5174e98e3e1Schristos 	    else
5184e98e3e1Schristos 	      {
5194e98e3e1Schristos 		int indent;
5204e98e3e1Schristos 		if (!is_first)
5214e98e3e1Schristos 		  {
5224e98e3e1Schristos 		    lf_printf (file, "else\n");
5234e98e3e1Schristos 		    lf_indent (file, +2);
5244e98e3e1Schristos 		  }
5254e98e3e1Schristos 		lf_print__line_ref (file, assembler->line);
5264e98e3e1Schristos 		indent = print_itrace_prefix (file);
5274e98e3e1Schristos 		print_itrace_format (file, assembler);
5284e98e3e1Schristos 		lf_print__internal_ref (file);
5294e98e3e1Schristos 		lf_indent (file, -indent);
5304e98e3e1Schristos 		if (!is_first)
5314e98e3e1Schristos 		  lf_indent (file, -2);
5324e98e3e1Schristos 		if (assembler->next != NULL)
5334e98e3e1Schristos 		  error (assembler->line,
5344e98e3e1Schristos 			 "Unconditional assembler is not last\n");
5354e98e3e1Schristos 	      }
5364e98e3e1Schristos 	    is_first = 0;
5374e98e3e1Schristos 	    assembler = assembler->next;
5384e98e3e1Schristos 	  }
5394e98e3e1Schristos 	while (assembler != NULL);
5404e98e3e1Schristos       }
5414e98e3e1Schristos     else
5424e98e3e1Schristos       {
5434e98e3e1Schristos 	int indent;
5444e98e3e1Schristos 	lf_indent (file, +2);
5454e98e3e1Schristos 	lf_print__line_ref (file, insn->line);
5464e98e3e1Schristos 	indent = print_itrace_prefix (file);
5474e98e3e1Schristos 	lf_printf (file, "%%s\", \\\n");
5484e98e3e1Schristos 	lf_printf (file, "itable[MY_INDEX].name);\n");
5494e98e3e1Schristos 	lf_print__internal_ref (file);
5504e98e3e1Schristos 	lf_indent (file, -indent);
5514e98e3e1Schristos 	lf_indent (file, -2);
5524e98e3e1Schristos       }
5534e98e3e1Schristos     lf_printf (file, "/* trace the instruction execution if enabled */\n");
5544e98e3e1Schristos     lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase);
5554e98e3e1Schristos     lf_printf (file,
5564e98e3e1Schristos 	       "  trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n",
5574e98e3e1Schristos 	       phase);
5584e98e3e1Schristos   }
5594e98e3e1Schristos   lf_indent (file, -4);
5604e98e3e1Schristos   lf_printf (file, "  }\n");
5614e98e3e1Schristos   lf_indent_suppress (file);
5624e98e3e1Schristos   lf_printf (file, "#endif\n");
5634e98e3e1Schristos }
5644e98e3e1Schristos 
5654e98e3e1Schristos 
5664e98e3e1Schristos void
5674e98e3e1Schristos print_sim_engine_abort (lf *file, const char *message)
5684e98e3e1Schristos {
5694e98e3e1Schristos   lf_printf (file, "sim_engine_abort (SD, CPU, cia, ");
5704e98e3e1Schristos   lf_printf (file, "\"%s\"", message);
5714e98e3e1Schristos   lf_printf (file, ");\n");
5724e98e3e1Schristos }
5734e98e3e1Schristos 
5744e98e3e1Schristos 
5754e98e3e1Schristos void
5764e98e3e1Schristos print_include (lf *file, igen_module module)
5774e98e3e1Schristos {
5784e98e3e1Schristos   lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l);
5794e98e3e1Schristos }
5804e98e3e1Schristos 
5814e98e3e1Schristos void
5824e98e3e1Schristos print_include_inline (lf *file, igen_module module)
5834e98e3e1Schristos {
5844e98e3e1Schristos   lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u);
5854e98e3e1Schristos   lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l);
5864e98e3e1Schristos   lf_printf (file, "#else\n");
5874e98e3e1Schristos   print_include (file, module);
5884e98e3e1Schristos   lf_printf (file, "#endif\n");
5894e98e3e1Schristos   lf_printf (file, "\n");
5904e98e3e1Schristos }
5914e98e3e1Schristos 
5924e98e3e1Schristos void
5934e98e3e1Schristos print_includes (lf *file)
5944e98e3e1Schristos {
5954e98e3e1Schristos   lf_printf (file, "\n");
5964e98e3e1Schristos   lf_printf (file, "#include \"sim-inline.c\"\n");
5974e98e3e1Schristos   lf_printf (file, "\n");
5984e98e3e1Schristos   print_include_inline (file, options.module.itable);
5994e98e3e1Schristos   print_include_inline (file, options.module.idecode);
6004e98e3e1Schristos   print_include_inline (file, options.module.support);
6014e98e3e1Schristos }
6024e98e3e1Schristos 
6034e98e3e1Schristos 
6044e98e3e1Schristos /****************************************************************/
6054e98e3e1Schristos 
6064e98e3e1Schristos 
6074e98e3e1Schristos static void
6084b169a6bSchristos gen_semantics_h (lf *file, const insn_list *semantics, int max_nr_words)
6094e98e3e1Schristos {
6104e98e3e1Schristos   int word_nr;
6114b169a6bSchristos   const insn_list *semantic;
6124e98e3e1Schristos   for (word_nr = -1; word_nr <= max_nr_words; word_nr++)
6134e98e3e1Schristos     {
6144e98e3e1Schristos       lf_printf (file, "typedef ");
6154e98e3e1Schristos       print_semantic_function_type (file);
6164e98e3e1Schristos       lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l);
6174e98e3e1Schristos       if (word_nr >= 0)
6184e98e3e1Schristos 	lf_printf (file, "_%d", word_nr);
6194e98e3e1Schristos       lf_printf (file, "\n(");
6204e98e3e1Schristos       lf_indent (file, +1);
6214e98e3e1Schristos       print_semantic_function_formal (file, word_nr);
6224e98e3e1Schristos       lf_indent (file, -1);
6234e98e3e1Schristos       lf_printf (file, ");\n");
6244e98e3e1Schristos       lf_printf (file, "\n");
6254e98e3e1Schristos     }
6264e98e3e1Schristos   switch (options.gen.code)
6274e98e3e1Schristos     {
6284e98e3e1Schristos     case generate_calls:
6294e98e3e1Schristos       for (semantic = semantics; semantic != NULL; semantic = semantic->next)
6304e98e3e1Schristos 	{
6314e98e3e1Schristos 	  /* Ignore any special/internal instructions */
6324e98e3e1Schristos 	  if (semantic->insn->nr_words == 0)
6334e98e3e1Schristos 	    continue;
6344e98e3e1Schristos 	  print_semantic_declaration (file,
6354e98e3e1Schristos 				      semantic->insn,
6364e98e3e1Schristos 				      semantic->expanded_bits,
6374e98e3e1Schristos 				      semantic->opcodes,
6384e98e3e1Schristos 				      semantic->nr_prefetched_words);
6394e98e3e1Schristos 	}
6404e98e3e1Schristos       break;
6414e98e3e1Schristos     case generate_jumps:
6424e98e3e1Schristos       lf_print__this_file_is_empty (file, "generating jumps");
6434e98e3e1Schristos       break;
6444e98e3e1Schristos     }
6454e98e3e1Schristos }
6464e98e3e1Schristos 
6474e98e3e1Schristos 
6484e98e3e1Schristos static void
6494b169a6bSchristos gen_semantics_c (lf *file, const insn_list *semantics, cache_entry *cache_rules)
6504e98e3e1Schristos {
6514e98e3e1Schristos   if (options.gen.code == generate_calls)
6524e98e3e1Schristos     {
6534b169a6bSchristos       const insn_list *semantic;
6544e98e3e1Schristos       print_includes (file);
6554e98e3e1Schristos       print_include (file, options.module.semantics);
6564e98e3e1Schristos       lf_printf (file, "\n");
6574e98e3e1Schristos 
6584e98e3e1Schristos       for (semantic = semantics; semantic != NULL; semantic = semantic->next)
6594e98e3e1Schristos 	{
6604e98e3e1Schristos 	  /* Ignore any special/internal instructions */
6614e98e3e1Schristos 	  if (semantic->insn->nr_words == 0)
6624e98e3e1Schristos 	    continue;
6634e98e3e1Schristos 	  print_semantic_definition (file,
6644e98e3e1Schristos 				     semantic->insn,
6654e98e3e1Schristos 				     semantic->expanded_bits,
6664e98e3e1Schristos 				     semantic->opcodes,
6674e98e3e1Schristos 				     cache_rules,
6684e98e3e1Schristos 				     semantic->nr_prefetched_words);
6694e98e3e1Schristos 	}
6704e98e3e1Schristos     }
6714e98e3e1Schristos   else
6724e98e3e1Schristos     {
6734e98e3e1Schristos       lf_print__this_file_is_empty (file, "generating jump engine");
6744e98e3e1Schristos     }
6754e98e3e1Schristos }
6764e98e3e1Schristos 
6774e98e3e1Schristos 
6784e98e3e1Schristos /****************************************************************/
6794e98e3e1Schristos 
6804e98e3e1Schristos 
6814e98e3e1Schristos static void
6824e98e3e1Schristos gen_icache_h (lf *file,
6834b169a6bSchristos 	      const insn_list *semantic,
6844b169a6bSchristos 	      const function_entry *functions, int max_nr_words)
6854e98e3e1Schristos {
6864e98e3e1Schristos   int word_nr;
6874e98e3e1Schristos   for (word_nr = 0; word_nr <= max_nr_words; word_nr++)
6884e98e3e1Schristos     {
6894e98e3e1Schristos       lf_printf (file, "typedef ");
6904e98e3e1Schristos       print_icache_function_type (file);
6914e98e3e1Schristos       lf_printf (file, " %sidecode_icache_%d\n(",
6924e98e3e1Schristos 		 options.module.global.prefix.l, word_nr);
6934e98e3e1Schristos       print_icache_function_formal (file, word_nr);
6944e98e3e1Schristos       lf_printf (file, ");\n");
6954e98e3e1Schristos       lf_printf (file, "\n");
6964e98e3e1Schristos     }
6974e98e3e1Schristos   if (options.gen.code == generate_calls && options.gen.icache)
6984e98e3e1Schristos     {
6994e98e3e1Schristos       function_entry_traverse (file, functions,
7004e98e3e1Schristos 			       print_icache_internal_function_declaration,
7014e98e3e1Schristos 			       NULL);
7024e98e3e1Schristos       while (semantic != NULL)
7034e98e3e1Schristos 	{
7044e98e3e1Schristos 	  print_icache_declaration (file,
7054e98e3e1Schristos 				    semantic->insn,
7064e98e3e1Schristos 				    semantic->expanded_bits,
7074e98e3e1Schristos 				    semantic->opcodes,
7084e98e3e1Schristos 				    semantic->nr_prefetched_words);
7094e98e3e1Schristos 	  semantic = semantic->next;
7104e98e3e1Schristos 	}
7114e98e3e1Schristos     }
7124e98e3e1Schristos   else
7134e98e3e1Schristos     {
7144e98e3e1Schristos       lf_print__this_file_is_empty (file, "generating jump engine");
7154e98e3e1Schristos     }
7164e98e3e1Schristos }
7174e98e3e1Schristos 
7184e98e3e1Schristos static void
7194e98e3e1Schristos gen_icache_c (lf *file,
7204b169a6bSchristos 	      const insn_list *semantic,
7214b169a6bSchristos 	      const function_entry *functions, cache_entry *cache_rules)
7224e98e3e1Schristos {
7234e98e3e1Schristos   /* output `internal' invalid/floating-point unavailable functions
7244e98e3e1Schristos      where needed */
7254e98e3e1Schristos   if (options.gen.code == generate_calls && options.gen.icache)
7264e98e3e1Schristos     {
7274e98e3e1Schristos       lf_printf (file, "\n");
7284e98e3e1Schristos       lf_printf (file, "#include \"cpu.h\"\n");
7294e98e3e1Schristos       lf_printf (file, "#include \"idecode.h\"\n");
7304e98e3e1Schristos       lf_printf (file, "#include \"semantics.h\"\n");
7314e98e3e1Schristos       lf_printf (file, "#include \"icache.h\"\n");
7324e98e3e1Schristos       lf_printf (file, "#include \"support.h\"\n");
7334e98e3e1Schristos       lf_printf (file, "\n");
7344e98e3e1Schristos       function_entry_traverse (file, functions,
7354e98e3e1Schristos 			       print_icache_internal_function_definition,
7364e98e3e1Schristos 			       NULL);
7374e98e3e1Schristos       lf_printf (file, "\n");
7384e98e3e1Schristos       while (semantic != NULL)
7394e98e3e1Schristos 	{
7404e98e3e1Schristos 	  print_icache_definition (file,
7414e98e3e1Schristos 				   semantic->insn,
7424e98e3e1Schristos 				   semantic->expanded_bits,
7434e98e3e1Schristos 				   semantic->opcodes,
7444e98e3e1Schristos 				   cache_rules,
7454e98e3e1Schristos 				   semantic->nr_prefetched_words);
7464e98e3e1Schristos 	  semantic = semantic->next;
7474e98e3e1Schristos 	}
7484e98e3e1Schristos     }
7494e98e3e1Schristos   else
7504e98e3e1Schristos     {
7514e98e3e1Schristos       lf_print__this_file_is_empty (file, "generating jump engine");
7524e98e3e1Schristos     }
7534e98e3e1Schristos }
7544e98e3e1Schristos 
7554e98e3e1Schristos 
7564e98e3e1Schristos /****************************************************************/
7574e98e3e1Schristos 
7584e98e3e1Schristos 
7594e98e3e1Schristos static void
7604e98e3e1Schristos gen_idecode_h (lf *file,
7614b169a6bSchristos 	       const gen_table *gen,
7624b169a6bSchristos 	       const insn_table *insns,
7634b169a6bSchristos 	       cache_entry *cache_rules)
7644e98e3e1Schristos {
7654b169a6bSchristos   lf_printf (file, "typedef uint%d_t %sinstruction_word;\n",
7664e98e3e1Schristos 	     options.insn_bit_size, options.module.global.prefix.l);
7674e98e3e1Schristos   if (options.gen.delayed_branch)
7684e98e3e1Schristos     {
7694e98e3e1Schristos       lf_printf (file, "typedef struct _%sinstruction_address {\n",
7704e98e3e1Schristos 		 options.module.global.prefix.l);
7714e98e3e1Schristos       lf_printf (file, "  address_word ip; /* instruction pointer */\n");
7724e98e3e1Schristos       lf_printf (file, "  address_word dp; /* delayed-slot pointer */\n");
7734e98e3e1Schristos       lf_printf (file, "} %sinstruction_address;\n",
7744e98e3e1Schristos 		 options.module.global.prefix.l);
7754e98e3e1Schristos     }
7764e98e3e1Schristos   else
7774e98e3e1Schristos     {
7784e98e3e1Schristos       lf_printf (file, "typedef address_word %sinstruction_address;\n",
7794e98e3e1Schristos 		 options.module.global.prefix.l);
7804e98e3e1Schristos 
7814e98e3e1Schristos     }
7824e98e3e1Schristos   if (options.gen.nia == nia_is_invalid
7834e98e3e1Schristos       && strlen (options.module.global.prefix.u) > 0)
7844e98e3e1Schristos     {
7854e98e3e1Schristos       lf_indent_suppress (file);
7864e98e3e1Schristos       lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ",
7874e98e3e1Schristos 		 options.module.global.prefix.u);
7884e98e3e1Schristos       lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n");
7894e98e3e1Schristos     }
7904e98e3e1Schristos   lf_printf (file, "\n");
7914e98e3e1Schristos   print_icache_struct (file, insns, cache_rules);
7924e98e3e1Schristos   lf_printf (file, "\n");
7934e98e3e1Schristos   if (options.gen.icache)
7944e98e3e1Schristos     {
7954e98e3e1Schristos       ERROR ("FIXME - idecode with icache suffering from bit-rot");
7964e98e3e1Schristos     }
7974e98e3e1Schristos   else
7984e98e3e1Schristos     {
7994e98e3e1Schristos       gen_list *entry;
8004e98e3e1Schristos       for (entry = gen->tables; entry != NULL; entry = entry->next)
8014e98e3e1Schristos 	{
8024e98e3e1Schristos 	  print_idecode_issue_function_header (file,
8034e98e3e1Schristos 					       (options.gen.multi_sim
8044e98e3e1Schristos 						? entry->model->name
8054e98e3e1Schristos 						: NULL),
8064e98e3e1Schristos 					       is_function_declaration,
8074e98e3e1Schristos 					       1 /*ALWAYS ONE WORD */ );
8084e98e3e1Schristos 	}
8094e98e3e1Schristos       if (options.gen.multi_sim)
8104e98e3e1Schristos 	{
8114e98e3e1Schristos 	  print_idecode_issue_function_header (file,
8124e98e3e1Schristos 					       NULL,
8134e98e3e1Schristos 					       is_function_variable,
8144e98e3e1Schristos 					       1 /*ALWAYS ONE WORD */ );
8154e98e3e1Schristos 	}
8164e98e3e1Schristos     }
8174e98e3e1Schristos }
8184e98e3e1Schristos 
8194e98e3e1Schristos 
8204e98e3e1Schristos static void
8214e98e3e1Schristos gen_idecode_c (lf *file,
8224b169a6bSchristos 	       const gen_table *gen,
8234b169a6bSchristos 	       const insn_table *isa,
8244b169a6bSchristos 	       cache_entry *cache_rules)
8254e98e3e1Schristos {
8264e98e3e1Schristos   /* the intro */
8274e98e3e1Schristos   print_includes (file);
8284e98e3e1Schristos   print_include_inline (file, options.module.semantics);
8294e98e3e1Schristos   lf_printf (file, "\n");
8304e98e3e1Schristos 
8314e98e3e1Schristos   print_idecode_globals (file);
8324e98e3e1Schristos   lf_printf (file, "\n");
8334e98e3e1Schristos 
8344e98e3e1Schristos   switch (options.gen.code)
8354e98e3e1Schristos     {
8364e98e3e1Schristos     case generate_calls:
8374e98e3e1Schristos       {
8384e98e3e1Schristos 	gen_list *entry;
8394e98e3e1Schristos 	for (entry = gen->tables; entry != NULL; entry = entry->next)
8404e98e3e1Schristos 	  {
8414e98e3e1Schristos 	    print_idecode_lookups (file, entry->table, cache_rules);
8424e98e3e1Schristos 
8434e98e3e1Schristos 	    /* output the main idecode routine */
8444e98e3e1Schristos 	    if (!options.gen.icache)
8454e98e3e1Schristos 	      {
8464e98e3e1Schristos 		print_idecode_issue_function_header (file,
8474e98e3e1Schristos 						     (options.gen.multi_sim
8484e98e3e1Schristos 						      ? entry->model->name
8494e98e3e1Schristos 						      : NULL),
8504e98e3e1Schristos 						     1 /*is definition */ ,
8514e98e3e1Schristos 						     1 /*ALWAYS ONE WORD */ );
8524e98e3e1Schristos 		lf_printf (file, "{\n");
8534e98e3e1Schristos 		lf_indent (file, +2);
8544e98e3e1Schristos 		lf_printf (file, "%sinstruction_address nia;\n",
8554e98e3e1Schristos 			   options.module.global.prefix.l);
8564e98e3e1Schristos 		print_idecode_body (file, entry->table, "nia =");
8574e98e3e1Schristos 		lf_printf (file, "return nia;");
8584e98e3e1Schristos 		lf_indent (file, -2);
8594e98e3e1Schristos 		lf_printf (file, "}\n");
8604e98e3e1Schristos 	      }
8614e98e3e1Schristos 	  }
8624e98e3e1Schristos 	break;
8634e98e3e1Schristos       }
8644e98e3e1Schristos     case generate_jumps:
8654e98e3e1Schristos       {
8664e98e3e1Schristos 	lf_print__this_file_is_empty (file, "generating a jump engine");
8674e98e3e1Schristos 	break;
8684e98e3e1Schristos       }
8694e98e3e1Schristos     }
8704e98e3e1Schristos }
8714e98e3e1Schristos 
8724e98e3e1Schristos 
8734e98e3e1Schristos /****************************************************************/
8744e98e3e1Schristos 
8754e98e3e1Schristos 
8764e98e3e1Schristos static void
8774b169a6bSchristos gen_run_c (lf *file, const gen_table *gen)
8784e98e3e1Schristos {
8794e98e3e1Schristos   gen_list *entry;
8804e98e3e1Schristos   lf_printf (file, "#include \"sim-main.h\"\n");
8814e98e3e1Schristos   lf_printf (file, "#include \"engine.h\"\n");
8824e98e3e1Schristos   lf_printf (file, "#include \"idecode.h\"\n");
8834e98e3e1Schristos   lf_printf (file, "#include \"bfd.h\"\n");
8844e98e3e1Schristos   lf_printf (file, "\n");
8854e98e3e1Schristos 
8864e98e3e1Schristos   if (options.gen.multi_sim)
8874e98e3e1Schristos     {
8884e98e3e1Schristos       print_idecode_issue_function_header (file, NULL, is_function_variable,
8894e98e3e1Schristos 					   1);
8904e98e3e1Schristos       lf_printf (file, "\n");
8914e98e3e1Schristos       print_engine_run_function_header (file, NULL, is_function_variable);
8924e98e3e1Schristos       lf_printf (file, "\n");
8934e98e3e1Schristos     }
8944e98e3e1Schristos 
8954e98e3e1Schristos   lf_printf (file, "void\n");
8964e98e3e1Schristos   lf_printf (file, "sim_engine_run (SIM_DESC sd,\n");
8974e98e3e1Schristos   lf_printf (file, "                int next_cpu_nr,\n");
8984e98e3e1Schristos   lf_printf (file, "                int nr_cpus,\n");
8994e98e3e1Schristos   lf_printf (file, "                int siggnal)\n");
9004e98e3e1Schristos   lf_printf (file, "{\n");
9014e98e3e1Schristos   lf_indent (file, +2);
9024e98e3e1Schristos   if (options.gen.multi_sim)
9034e98e3e1Schristos     {
9044e98e3e1Schristos       lf_printf (file, "int mach;\n");
9054e98e3e1Schristos       lf_printf (file, "if (STATE_ARCHITECTURE (sd) == NULL)\n");
9064e98e3e1Schristos       lf_printf (file, "  mach = 0;\n");
9074e98e3e1Schristos       lf_printf (file, "else\n");
9084e98e3e1Schristos       lf_printf (file, "  mach = STATE_ARCHITECTURE (sd)->mach;\n");
9094e98e3e1Schristos       lf_printf (file, "switch (mach)\n");
9104e98e3e1Schristos       lf_printf (file, "  {\n");
9114e98e3e1Schristos       lf_indent (file, +2);
9124e98e3e1Schristos       for (entry = gen->tables; entry != NULL; entry = entry->next)
9134e98e3e1Schristos 	{
9144e98e3e1Schristos 	  if (options.gen.default_model != NULL
9154e98e3e1Schristos 	      && (strcmp (entry->model->name, options.gen.default_model) == 0
9164e98e3e1Schristos 		  || strcmp (entry->model->full_name,
9174e98e3e1Schristos 			     options.gen.default_model) == 0))
9184e98e3e1Schristos 	    lf_printf (file, "default:\n");
9194e98e3e1Schristos 	  lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name);
9204e98e3e1Schristos 	  lf_indent (file, +2);
9214e98e3e1Schristos 	  print_function_name (file, "issue", NULL,	/* format name */
9224e98e3e1Schristos 			       NULL,	/* NO processor */
9234e98e3e1Schristos 			       NULL,	/* expanded bits */
9244e98e3e1Schristos 			       function_name_prefix_idecode);
9254e98e3e1Schristos 	  lf_printf (file, " = ");
9264e98e3e1Schristos 	  print_function_name (file, "issue", NULL,	/* format name */
9274e98e3e1Schristos 			       entry->model->name, NULL,	/* expanded bits */
9284e98e3e1Schristos 			       function_name_prefix_idecode);
9294e98e3e1Schristos 	  lf_printf (file, ";\n");
9304e98e3e1Schristos 	  print_function_name (file, "run", NULL,	/* format name */
9314e98e3e1Schristos 			       NULL,	/* NO processor */
9324e98e3e1Schristos 			       NULL,	/* expanded bits */
9334e98e3e1Schristos 			       function_name_prefix_engine);
9344e98e3e1Schristos 	  lf_printf (file, " = ");
9354e98e3e1Schristos 	  print_function_name (file, "run", NULL,	/* format name */
9364e98e3e1Schristos 			       entry->model->name, NULL,	/* expanded bits */
9374e98e3e1Schristos 			       function_name_prefix_engine);
9384e98e3e1Schristos 	  lf_printf (file, ";\n");
9394e98e3e1Schristos 	  lf_printf (file, "break;\n");
9404e98e3e1Schristos 	  lf_indent (file, -2);
9414e98e3e1Schristos 	}
9424e98e3e1Schristos       if (options.gen.default_model == NULL)
9434e98e3e1Schristos 	{
9444e98e3e1Schristos 	  lf_printf (file, "default:\n");
9454e98e3e1Schristos 	  lf_indent (file, +2);
9464e98e3e1Schristos 	  lf_printf (file, "sim_engine_abort (sd, NULL, NULL_CIA,\n");
9474e98e3e1Schristos 	  lf_printf (file,
9484e98e3e1Schristos 		     "                  \"sim_engine_run - unknown machine\");\n");
9494e98e3e1Schristos 	  lf_printf (file, "break;\n");
9504e98e3e1Schristos 	  lf_indent (file, -2);
9514e98e3e1Schristos 	}
9524e98e3e1Schristos       lf_indent (file, -2);
9534e98e3e1Schristos       lf_printf (file, "  }\n");
9544e98e3e1Schristos     }
9554e98e3e1Schristos   print_function_name (file, "run", NULL,	/* format name */
9564e98e3e1Schristos 		       NULL,	/* NO processor */
9574e98e3e1Schristos 		       NULL,	/* expanded bits */
9584e98e3e1Schristos 		       function_name_prefix_engine);
9594e98e3e1Schristos   lf_printf (file, " (sd, next_cpu_nr, nr_cpus, siggnal);\n");
9604e98e3e1Schristos   lf_indent (file, -2);
9614e98e3e1Schristos   lf_printf (file, "}\n");
9624e98e3e1Schristos }
9634e98e3e1Schristos 
9644e98e3e1Schristos /****************************************************************/
9654e98e3e1Schristos 
9664e98e3e1Schristos static gen_table *
9674b169a6bSchristos do_gen (const insn_table *isa, const decode_table *decode_rules)
9684e98e3e1Schristos {
9694e98e3e1Schristos   gen_table *gen;
9704e98e3e1Schristos   if (decode_rules == NULL)
9714e98e3e1Schristos     error (NULL, "Must specify a decode table\n");
9724e98e3e1Schristos   if (isa == NULL)
9734e98e3e1Schristos     error (NULL, "Must specify an instruction table\n");
9744e98e3e1Schristos   if (decode_table_max_word_nr (decode_rules) > 0)
9754e98e3e1Schristos     options.gen.multi_word = decode_table_max_word_nr (decode_rules);
9764e98e3e1Schristos   gen = make_gen_tables (isa, decode_rules);
9774e98e3e1Schristos   gen_tables_expand_insns (gen);
9784e98e3e1Schristos   gen_tables_expand_semantics (gen);
9794e98e3e1Schristos   return gen;
9804e98e3e1Schristos }
9814e98e3e1Schristos 
9824e98e3e1Schristos /****************************************************************/
9834e98e3e1Schristos 
9844e98e3e1Schristos igen_options options;
9854e98e3e1Schristos 
9864e98e3e1Schristos int
9874e98e3e1Schristos main (int argc, char **argv, char **envp)
9884e98e3e1Schristos {
9894e98e3e1Schristos   cache_entry *cache_rules = NULL;
9904e98e3e1Schristos   lf_file_references file_references = lf_include_references;
9914e98e3e1Schristos   decode_table *decode_rules = NULL;
9924e98e3e1Schristos   insn_table *isa = NULL;
9934e98e3e1Schristos   gen_table *gen = NULL;
9944e98e3e1Schristos   char *real_file_name = NULL;
9954e98e3e1Schristos   int is_header = 0;
9964e98e3e1Schristos   int ch;
9974b169a6bSchristos   static const struct option longopts[] = { { 0 } };
9984e98e3e1Schristos   lf *standard_out =
9994e98e3e1Schristos     lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen");
10004e98e3e1Schristos 
10014e98e3e1Schristos   INIT_OPTIONS ();
10024e98e3e1Schristos 
10034e98e3e1Schristos   if (argc == 1)
10044e98e3e1Schristos     {
10054e98e3e1Schristos       printf ("Usage:\n");
10064e98e3e1Schristos       printf ("\n");
10074e98e3e1Schristos       printf ("  igen <config-opts> ... <input-opts>... <output-opts>...\n");
10084e98e3e1Schristos       printf ("\n");
10094e98e3e1Schristos       printf ("Config options:\n");
10104e98e3e1Schristos       printf ("\n");
10114e98e3e1Schristos       printf ("  -B <bit-size>\n");
10124e98e3e1Schristos       printf ("\t Set the number of bits in an instruction (deprecated).\n");
10134e98e3e1Schristos       printf
10144e98e3e1Schristos 	("\t This option can now be set directly in the instruction table.\n");
10154e98e3e1Schristos       printf ("\n");
10164e98e3e1Schristos       printf ("  -D <data-structure>\n");
10174e98e3e1Schristos       printf
10184e98e3e1Schristos 	("\t Dump the specified data structure to stdout. Valid structures include:\n");
10194e98e3e1Schristos       printf
10204e98e3e1Schristos 	("\t processor-names - list the names of all the processors (models)\n");
10214e98e3e1Schristos       printf ("\n");
10224e98e3e1Schristos       printf ("  -F <filter-list>\n");
10234e98e3e1Schristos       printf
10244e98e3e1Schristos 	("\t Filter out any instructions with a non-empty flags field that contains\n");
10254e98e3e1Schristos       printf ("\t a flag not listed in the <filter-list>.\n");
10264e98e3e1Schristos       printf ("\n");
10274e98e3e1Schristos       printf ("  -H <high-bit>\n");
10284e98e3e1Schristos       printf
10294e98e3e1Schristos 	("\t Set the number of the high (most significant) instruction bit (deprecated).\n");
10304e98e3e1Schristos       printf
10314e98e3e1Schristos 	("\t This option can now be set directly in the instruction table.\n");
10324e98e3e1Schristos       printf ("\n");
10334e98e3e1Schristos       printf ("  -I <directory>\n");
10344e98e3e1Schristos       printf
10354e98e3e1Schristos 	("\t Add <directory> to the list of directories searched when opening a file\n");
10364e98e3e1Schristos       printf ("\n");
10374e98e3e1Schristos       printf ("  -M <model-list>\n");
10384e98e3e1Schristos       printf
10394e98e3e1Schristos 	("\t Filter out any instructions that do not support at least one of the listed\n");
10404e98e3e1Schristos       printf
10414e98e3e1Schristos 	("\t models (An instructions with no model information is considered to support\n");
10424e98e3e1Schristos       printf ("\t all models.).\n");
10434e98e3e1Schristos       printf ("\n");
10444e98e3e1Schristos       printf ("  -N <nr-cpus>\n");
10454e98e3e1Schristos       printf ("\t Generate a simulator supporting <nr-cpus>\n");
10464e98e3e1Schristos       printf
10474e98e3e1Schristos 	("\t Specify `-N 0' to disable generation of the SMP. Specifying `-N 1' will\n");
10484e98e3e1Schristos       printf
10494e98e3e1Schristos 	("\t still generate an SMP enabled simulator but will only support one CPU.\n");
10504e98e3e1Schristos       printf ("\n");
10514e98e3e1Schristos       printf ("  -T <mechanism>\n");
10524e98e3e1Schristos       printf
10534e98e3e1Schristos 	("\t Override the decode mechanism specified by the decode rules\n");
10544e98e3e1Schristos       printf ("\n");
10554e98e3e1Schristos       printf ("  -P <prefix>\n");
10564e98e3e1Schristos       printf
10574e98e3e1Schristos 	("\t Prepend global names (except itable) with the string <prefix>.\n");
10584e98e3e1Schristos       printf
10594e98e3e1Schristos 	("\t Specify -P <module>=<prefix> to set a specific <module>'s prefix.\n");
10604e98e3e1Schristos       printf ("\n");
10614e98e3e1Schristos       printf ("  -S <suffix>\n");
10624e98e3e1Schristos       printf
10634e98e3e1Schristos 	("\t Replace a global name (suffix) (except itable) with the string <suffix>.\n");
10644e98e3e1Schristos       printf
10654e98e3e1Schristos 	("\t Specify -S <module>=<suffix> to change a specific <module>'s name (suffix).\n");
10664e98e3e1Schristos       printf ("\n");
10674e98e3e1Schristos       printf ("  -Werror\n");
10684e98e3e1Schristos       printf ("\t Make warnings errors\n");
10694e98e3e1Schristos       printf ("  -Wnodiscard\n");
10704e98e3e1Schristos       printf
10714e98e3e1Schristos 	("\t Suppress warnings about discarded functions and instructions\n");
10724e98e3e1Schristos       printf ("  -Wnowidth\n");
10734e98e3e1Schristos       printf
10744e98e3e1Schristos 	("\t Suppress warnings about instructions with invalid widths\n");
10754e98e3e1Schristos       printf ("  -Wnounimplemented\n");
10764e98e3e1Schristos       printf ("\t Suppress warnings about unimplemented instructions\n");
10774e98e3e1Schristos       printf ("\n");
10784e98e3e1Schristos       printf ("  -G [!]<gen-option>\n");
10794e98e3e1Schristos       printf ("\t Any of the following options:\n");
10804e98e3e1Schristos       printf ("\n");
10814e98e3e1Schristos       printf
10824e98e3e1Schristos 	("\t decode-duplicate       - Override the decode rules, forcing the duplication of\n");
10834e98e3e1Schristos       printf ("\t                          semantic functions\n");
10844e98e3e1Schristos       printf
10854e98e3e1Schristos 	("\t decode-combine         - Combine any duplicated entries within a table\n");
10864e98e3e1Schristos       printf
10874e98e3e1Schristos 	("\t decode-zero-reserved   - Override the decode rules, forcing reserved bits to be\n");
10884e98e3e1Schristos       printf ("\t                          treated as zero.\n");
10894e98e3e1Schristos       printf
10904e98e3e1Schristos 	("\t decode-switch-is-goto  - Overfide the padded-switch code type as a goto-switch\n");
10914e98e3e1Schristos       printf ("\n");
10924e98e3e1Schristos       printf
10934e98e3e1Schristos 	("\t gen-conditional-issue  - conditionally issue each instruction\n");
10944e98e3e1Schristos       printf
10954e98e3e1Schristos 	("\t gen-delayed-branch     - need both cia and nia passed around\n");
10964e98e3e1Schristos       printf
10974e98e3e1Schristos 	("\t gen-direct-access      - use #defines to directly access values\n");
10984e98e3e1Schristos       printf
10994e98e3e1Schristos 	("\t gen-zero-r<N>          - arch assumes GPR(<N>) == 0, keep it that way\n");
11004e98e3e1Schristos       printf
11014e98e3e1Schristos 	("\t gen-icache[=<N>        - generate an instruction cracking cache of size <N>\n");
11024e98e3e1Schristos       printf ("\t                          Default size is %d\n",
11034e98e3e1Schristos 	      options.gen.icache_size);
11044e98e3e1Schristos       printf
11054e98e3e1Schristos 	("\t gen-insn-in-icache     - save original instruction when cracking\n");
11064e98e3e1Schristos       printf
11074e98e3e1Schristos 	("\t gen-multi-sim[=MODEL]  - generate multiple simulators - one per model\n");
11084e98e3e1Schristos       printf
11094e98e3e1Schristos 	("\t                          If specified MODEL is made the default architecture.\n");
11104e98e3e1Schristos       printf
11114e98e3e1Schristos 	("\t                          By default, a single simulator that will\n");
11124e98e3e1Schristos       printf
11134e98e3e1Schristos 	("\t                          execute any instruction is generated\n");
11144e98e3e1Schristos       printf
11154e98e3e1Schristos 	("\t gen-multi-word         - generate code allowing for multi-word insns\n");
11164e98e3e1Schristos       printf
11174e98e3e1Schristos 	("\t gen-semantic-icache    - include semantic code in cracking functions\n");
11184e98e3e1Schristos       printf
11194e98e3e1Schristos 	("\t gen-slot-verification  - perform slot verification as part of decode\n");
11204e98e3e1Schristos       printf ("\t gen-nia-invalid        - NIA defaults to nia_invalid\n");
11214e98e3e1Schristos       printf ("\t gen-nia-void           - do not compute/return NIA\n");
11224e98e3e1Schristos       printf ("\n");
11234e98e3e1Schristos       printf
11244e98e3e1Schristos 	("\t trace-combine          - report combined entries a rule application\n");
11254e98e3e1Schristos       printf
11264e98e3e1Schristos 	("\t trace-entries          - report entries after a rules application\n");
11274e98e3e1Schristos       printf ("\t trace-rule-rejection   - report each rule as rejected\n");
11284e98e3e1Schristos       printf ("\t trace-rule-selection   - report each rule as selected\n");
11294e98e3e1Schristos       printf
11304e98e3e1Schristos 	("\t trace-insn-insertion   - report each instruction as it is inserted into a decode table\n");
11314e98e3e1Schristos       printf
11324e98e3e1Schristos 	("\t trace-rule-expansion   - report each instruction as it is expanded (before insertion into a decode table)\n");
11334e98e3e1Schristos       printf ("\t trace-all              - enable all trace options\n");
11344e98e3e1Schristos       printf ("\n");
11354e98e3e1Schristos       printf
11364e98e3e1Schristos 	("\t field-widths           - instruction formats specify widths (deprecated)\n");
11374e98e3e1Schristos       printf
11384e98e3e1Schristos 	("\t                          By default, an instruction format specifies bit\n");
11394e98e3e1Schristos       printf ("\t                          positions\n");
11404e98e3e1Schristos       printf
11414e98e3e1Schristos 	("\t                          This option can now be set directly in the\n");
11424e98e3e1Schristos       printf ("\t                          instruction table\n");
11434e98e3e1Schristos       printf
11444e98e3e1Schristos 	("\t jumps                  - use jumps instead of function calls\n");
11454e98e3e1Schristos       printf
11464e98e3e1Schristos 	("\t omit-line-numbers      - do not include line number information in the output\n");
11474e98e3e1Schristos       printf ("\n");
11484e98e3e1Schristos       printf ("Input options:\n");
11494e98e3e1Schristos       printf ("\n");
11504e98e3e1Schristos       printf ("  -k <cache-rules> (deprecated)\n");
11514e98e3e1Schristos       printf ("  -o <decode-rules>\n");
11524e98e3e1Schristos       printf ("  -i <instruction-table>\n");
11534e98e3e1Schristos       printf ("\n");
11544e98e3e1Schristos       printf ("Output options:\n");
11554e98e3e1Schristos       printf ("\n");
11564e98e3e1Schristos       printf ("  -x                    Perform expansion (required)\n");
11574e98e3e1Schristos       printf
11584e98e3e1Schristos 	("  -n <real-name>        Specify the real name of the next output file\n");
11594e98e3e1Schristos       printf
11604e98e3e1Schristos 	("  -h 		       Generate the header (.h) file rather than the body (.c)\n");
11614e98e3e1Schristos       printf ("  -c <output-file>      output icache\n");
11624e98e3e1Schristos       printf ("  -d <output-file>      output idecode\n");
11634e98e3e1Schristos       printf ("  -e <output-file>      output engine\n");
11644e98e3e1Schristos       printf ("  -f <output-file>      output support functions\n");
11654e98e3e1Schristos       printf ("  -m <output-file>      output model\n");
11664e98e3e1Schristos       printf ("  -r <output-file>      output multi-sim run\n");
11674e98e3e1Schristos       printf ("  -s <output-file>      output schematic\n");
11684e98e3e1Schristos       printf ("  -t <output-file>      output itable\n");
11694e98e3e1Schristos     }
11704e98e3e1Schristos 
11714b169a6bSchristos   while ((ch = getopt_long (argc, argv,
11724b169a6bSchristos 			    "B:D:F:G:H:I:M:N:P:T:W:o:k:i:n:hc:d:e:m:r:s:t:f:x",
11734b169a6bSchristos 			    longopts, NULL))
11744e98e3e1Schristos 	 != -1)
11754e98e3e1Schristos     {
11764b169a6bSchristos #if 0  /* For debugging.  */
11774e98e3e1Schristos       fprintf (stderr, "  -%c ", ch);
11784e98e3e1Schristos       if (optarg)
11794e98e3e1Schristos 	fprintf (stderr, "%s ", optarg);
11804e98e3e1Schristos       fprintf (stderr, "\\\n");
11814b169a6bSchristos #endif
11824e98e3e1Schristos 
11834e98e3e1Schristos       switch (ch)
11844e98e3e1Schristos 	{
11854e98e3e1Schristos 
11864e98e3e1Schristos 	case 'M':
11874e98e3e1Schristos 	  filter_parse (&options.model_filter, optarg);
11884e98e3e1Schristos 	  break;
11894e98e3e1Schristos 
11904e98e3e1Schristos 	case 'D':
11914e98e3e1Schristos 	  if (strcmp (optarg, "processor-names"))
11924e98e3e1Schristos 	    {
11934b169a6bSchristos 	      const char *processor;
11944e98e3e1Schristos 	      for (processor = filter_next (options.model_filter, "");
11954e98e3e1Schristos 		   processor != NULL;
11964e98e3e1Schristos 		   processor = filter_next (options.model_filter, processor))
11974e98e3e1Schristos 		lf_printf (standard_out, "%s\n", processor);
11984e98e3e1Schristos 	    }
11994e98e3e1Schristos 	  else
12004e98e3e1Schristos 	    error (NULL, "Unknown data structure %s, not dumped\n", optarg);
12014e98e3e1Schristos 	  break;
12024e98e3e1Schristos 
12034e98e3e1Schristos 	case 'F':
12044e98e3e1Schristos 	  filter_parse (&options.flags_filter, optarg);
12054e98e3e1Schristos 	  break;
12064e98e3e1Schristos 
12074e98e3e1Schristos 	case 'I':
12084e98e3e1Schristos 	  {
12094e98e3e1Schristos 	    table_include **dir = &options.include;
12104e98e3e1Schristos 	    while ((*dir) != NULL)
12114e98e3e1Schristos 	      dir = &(*dir)->next;
12124e98e3e1Schristos 	    (*dir) = ZALLOC (table_include);
12134e98e3e1Schristos 	    (*dir)->dir = strdup (optarg);
12144e98e3e1Schristos 	  }
12154e98e3e1Schristos 	  break;
12164e98e3e1Schristos 
12174e98e3e1Schristos 	case 'B':
12184e98e3e1Schristos 	  options.insn_bit_size = a2i (optarg);
12194e98e3e1Schristos 	  if (options.insn_bit_size <= 0
12204e98e3e1Schristos 	      || options.insn_bit_size > max_insn_bit_size)
12214e98e3e1Schristos 	    {
12224e98e3e1Schristos 	      error (NULL, "Instruction bitsize must be in range 1..%d\n",
12234e98e3e1Schristos 		     max_insn_bit_size);
12244e98e3e1Schristos 	    }
12254e98e3e1Schristos 	  if (options.hi_bit_nr != options.insn_bit_size - 1
12264e98e3e1Schristos 	      && options.hi_bit_nr != 0)
12274e98e3e1Schristos 	    {
12284e98e3e1Schristos 	      error (NULL, "Conflict betweem hi-bit-nr and insn-bit-size\n");
12294e98e3e1Schristos 	    }
12304e98e3e1Schristos 	  break;
12314e98e3e1Schristos 
12324e98e3e1Schristos 	case 'H':
12334e98e3e1Schristos 	  options.hi_bit_nr = a2i (optarg);
12344e98e3e1Schristos 	  if (options.hi_bit_nr != options.insn_bit_size - 1
12354e98e3e1Schristos 	      && options.hi_bit_nr != 0)
12364e98e3e1Schristos 	    {
12374e98e3e1Schristos 	      error (NULL, "Conflict between hi-bit-nr and insn-bit-size\n");
12384e98e3e1Schristos 	    }
12394e98e3e1Schristos 	  break;
12404e98e3e1Schristos 
12414e98e3e1Schristos 	case 'N':
12424e98e3e1Schristos 	  options.gen.smp = a2i (optarg);
12434e98e3e1Schristos 	  break;
12444e98e3e1Schristos 
12454e98e3e1Schristos 	case 'P':
12464e98e3e1Schristos 	case 'S':
12474e98e3e1Schristos 	  {
12484e98e3e1Schristos 	    igen_module *names;
12494e98e3e1Schristos 	    igen_name *name;
12504e98e3e1Schristos 	    char *chp;
12514e98e3e1Schristos 	    chp = strchr (optarg, '=');
12524e98e3e1Schristos 	    if (chp == NULL)
12534e98e3e1Schristos 	      {
12544e98e3e1Schristos 		names = &options.module.global;
12554e98e3e1Schristos 		chp = optarg;
12564e98e3e1Schristos 	      }
12574e98e3e1Schristos 	    else
12584e98e3e1Schristos 	      {
12594e98e3e1Schristos 		chp = chp + 1;	/* skip `=' */
12604e98e3e1Schristos 		names = NULL;
12614e98e3e1Schristos 		if (strncmp (optarg, "global=", chp - optarg) == 0)
12624e98e3e1Schristos 		  {
12634e98e3e1Schristos 		    names = &options.module.global;
12644e98e3e1Schristos 		  }
12654e98e3e1Schristos 		if (strncmp (optarg, "engine=", chp - optarg) == 0)
12664e98e3e1Schristos 		  {
12674e98e3e1Schristos 		    names = &options.module.engine;
12684e98e3e1Schristos 		  }
12694e98e3e1Schristos 		if (strncmp (optarg, "icache=", chp - optarg) == 0)
12704e98e3e1Schristos 		  {
12714e98e3e1Schristos 		    names = &options.module.icache;
12724e98e3e1Schristos 		  }
12734e98e3e1Schristos 		if (strncmp (optarg, "idecode=", chp - optarg) == 0)
12744e98e3e1Schristos 		  {
12754e98e3e1Schristos 		    names = &options.module.idecode;
12764e98e3e1Schristos 		  }
12774e98e3e1Schristos 		if (strncmp (optarg, "itable=", chp - optarg) == 0)
12784e98e3e1Schristos 		  {
12794e98e3e1Schristos 		    names = &options.module.itable;
12804e98e3e1Schristos 		  }
12814e98e3e1Schristos 		if (strncmp (optarg, "semantics=", chp - optarg) == 0)
12824e98e3e1Schristos 		  {
12834e98e3e1Schristos 		    names = &options.module.semantics;
12844e98e3e1Schristos 		  }
12854e98e3e1Schristos 		if (strncmp (optarg, "support=", chp - optarg) == 0)
12864e98e3e1Schristos 		  {
12874e98e3e1Schristos 		    names = &options.module.support;
12884e98e3e1Schristos 		  }
12894e98e3e1Schristos 		if (names == NULL)
12904e98e3e1Schristos 		  {
12914e98e3e1Schristos 		    error (NULL, "Prefix `%s' unreconized\n", optarg);
12924e98e3e1Schristos 		  }
12934e98e3e1Schristos 	      }
12944e98e3e1Schristos 	    switch (ch)
12954e98e3e1Schristos 	      {
12964e98e3e1Schristos 	      case 'P':
12974e98e3e1Schristos 		name = &names->prefix;
12984e98e3e1Schristos 		break;
12994e98e3e1Schristos 	      case 'S':
13004e98e3e1Schristos 		name = &names->suffix;
13014e98e3e1Schristos 		break;
13024e98e3e1Schristos 	      default:
13034e98e3e1Schristos 		abort ();	/* Bad switch.  */
13044e98e3e1Schristos 	      }
13054e98e3e1Schristos 	    name->u = strdup (chp);
13064e98e3e1Schristos 	    name->l = strdup (chp);
13074e98e3e1Schristos 	    chp = name->u;
13084e98e3e1Schristos 	    while (*chp)
13094e98e3e1Schristos 	      {
13104e98e3e1Schristos 		if (islower (*chp))
13114e98e3e1Schristos 		  *chp = toupper (*chp);
13124e98e3e1Schristos 		chp++;
13134e98e3e1Schristos 	      }
13144e98e3e1Schristos 	    if (name == &options.module.global.prefix)
13154e98e3e1Schristos 	      {
13164e98e3e1Schristos 		options.module.engine.prefix = options.module.global.prefix;
13174e98e3e1Schristos 		options.module.icache.prefix = options.module.global.prefix;
13184e98e3e1Schristos 		options.module.idecode.prefix = options.module.global.prefix;
13194e98e3e1Schristos 		/* options.module.itable.prefix = options.module.global.prefix; */
13204e98e3e1Schristos 		options.module.semantics.prefix =
13214e98e3e1Schristos 		  options.module.global.prefix;
13224e98e3e1Schristos 		options.module.support.prefix = options.module.global.prefix;
13234e98e3e1Schristos 	      }
13244e98e3e1Schristos 	    if (name == &options.module.global.suffix)
13254e98e3e1Schristos 	      {
13264e98e3e1Schristos 		options.module.engine.suffix = options.module.global.suffix;
13274e98e3e1Schristos 		options.module.icache.suffix = options.module.global.suffix;
13284e98e3e1Schristos 		options.module.idecode.suffix = options.module.global.suffix;
13294e98e3e1Schristos 		/* options.module.itable.suffix = options.module.global.suffix; */
13304e98e3e1Schristos 		options.module.semantics.suffix =
13314e98e3e1Schristos 		  options.module.global.suffix;
13324e98e3e1Schristos 		options.module.support.suffix = options.module.global.suffix;
13334e98e3e1Schristos 	      }
13344e98e3e1Schristos 	    break;
13354e98e3e1Schristos 	  }
13364e98e3e1Schristos 
13374e98e3e1Schristos 	case 'W':
13384e98e3e1Schristos 	  {
13394e98e3e1Schristos 	    if (strcmp (optarg, "error") == 0)
13404e98e3e1Schristos 	      options.warning = error;
13414e98e3e1Schristos 	    else if (strcmp (optarg, "nodiscard") == 0)
13424e98e3e1Schristos 	      options.warn.discard = 0;
13434e98e3e1Schristos 	    else if (strcmp (optarg, "discard") == 0)
13444e98e3e1Schristos 	      options.warn.discard = 1;
13454e98e3e1Schristos 	    else if (strcmp (optarg, "nowidth") == 0)
13464e98e3e1Schristos 	      options.warn.width = 0;
13474e98e3e1Schristos 	    else if (strcmp (optarg, "width") == 0)
13484e98e3e1Schristos 	      options.warn.width = 1;
13494e98e3e1Schristos 	    else if (strcmp (optarg, "nounimplemented") == 0)
13504e98e3e1Schristos 	      options.warn.unimplemented = 0;
13514e98e3e1Schristos 	    else if (strcmp (optarg, "unimplemented") == 0)
13524e98e3e1Schristos 	      options.warn.unimplemented = 1;
13534e98e3e1Schristos 	    else
13544e98e3e1Schristos 	      error (NULL, "Unknown -W argument `%s'\n", optarg);
13554e98e3e1Schristos 	    break;
13564e98e3e1Schristos 	  }
13574e98e3e1Schristos 
13584e98e3e1Schristos 
13594e98e3e1Schristos 	case 'G':
13604e98e3e1Schristos 	  {
13614e98e3e1Schristos 	    int enable_p;
13624e98e3e1Schristos 	    char *argp;
13634e98e3e1Schristos 	    if (strncmp (optarg, "no-", strlen ("no-")) == 0)
13644e98e3e1Schristos 	      {
13654e98e3e1Schristos 		argp = optarg + strlen ("no-");
13664e98e3e1Schristos 		enable_p = 0;
13674e98e3e1Schristos 	      }
13684e98e3e1Schristos 	    else if (strncmp (optarg, "!", strlen ("!")) == 0)
13694e98e3e1Schristos 	      {
13704e98e3e1Schristos 		argp = optarg + strlen ("no-");
13714e98e3e1Schristos 		enable_p = 0;
13724e98e3e1Schristos 	      }
13734e98e3e1Schristos 	    else
13744e98e3e1Schristos 	      {
13754e98e3e1Schristos 		argp = optarg;
13764e98e3e1Schristos 		enable_p = 1;
13774e98e3e1Schristos 	      }
13784e98e3e1Schristos 	    if (strcmp (argp, "decode-duplicate") == 0)
13794e98e3e1Schristos 	      {
13804e98e3e1Schristos 		options.decode.duplicate = enable_p;
13814e98e3e1Schristos 	      }
13824e98e3e1Schristos 	    else if (strcmp (argp, "decode-combine") == 0)
13834e98e3e1Schristos 	      {
13844e98e3e1Schristos 		options.decode.combine = enable_p;
13854e98e3e1Schristos 	      }
13864e98e3e1Schristos 	    else if (strcmp (argp, "decode-zero-reserved") == 0)
13874e98e3e1Schristos 	      {
13884e98e3e1Schristos 		options.decode.zero_reserved = enable_p;
13894e98e3e1Schristos 	      }
13904e98e3e1Schristos 
13914e98e3e1Schristos 	    else if (strcmp (argp, "gen-conditional-issue") == 0)
13924e98e3e1Schristos 	      {
13934e98e3e1Schristos 		options.gen.conditional_issue = enable_p;
13944e98e3e1Schristos 	      }
13954e98e3e1Schristos 	    else if (strcmp (argp, "conditional-issue") == 0)
13964e98e3e1Schristos 	      {
13974e98e3e1Schristos 		options.gen.conditional_issue = enable_p;
13984e98e3e1Schristos 		options.warning (NULL,
13994e98e3e1Schristos 				 "Option conditional-issue replaced by gen-conditional-issue\n");
14004e98e3e1Schristos 	      }
14014e98e3e1Schristos 	    else if (strcmp (argp, "gen-delayed-branch") == 0)
14024e98e3e1Schristos 	      {
14034e98e3e1Schristos 		options.gen.delayed_branch = enable_p;
14044e98e3e1Schristos 	      }
14054e98e3e1Schristos 	    else if (strcmp (argp, "delayed-branch") == 0)
14064e98e3e1Schristos 	      {
14074e98e3e1Schristos 		options.gen.delayed_branch = enable_p;
14084e98e3e1Schristos 		options.warning (NULL,
14094e98e3e1Schristos 				 "Option delayed-branch replaced by gen-delayed-branch\n");
14104e98e3e1Schristos 	      }
14114e98e3e1Schristos 	    else if (strcmp (argp, "gen-direct-access") == 0)
14124e98e3e1Schristos 	      {
14134e98e3e1Schristos 		options.gen.direct_access = enable_p;
14144e98e3e1Schristos 	      }
14154e98e3e1Schristos 	    else if (strcmp (argp, "direct-access") == 0)
14164e98e3e1Schristos 	      {
14174e98e3e1Schristos 		options.gen.direct_access = enable_p;
14184e98e3e1Schristos 		options.warning (NULL,
14194e98e3e1Schristos 				 "Option direct-access replaced by gen-direct-access\n");
14204e98e3e1Schristos 	      }
14214e98e3e1Schristos 	    else if (strncmp (argp, "gen-zero-r", strlen ("gen-zero-r")) == 0)
14224e98e3e1Schristos 	      {
14234e98e3e1Schristos 		options.gen.zero_reg = enable_p;
14244e98e3e1Schristos 		options.gen.zero_reg_nr = atoi (argp + strlen ("gen-zero-r"));
14254e98e3e1Schristos 	      }
14264e98e3e1Schristos 	    else if (strncmp (argp, "zero-r", strlen ("zero-r")) == 0)
14274e98e3e1Schristos 	      {
14284e98e3e1Schristos 		options.gen.zero_reg = enable_p;
14294e98e3e1Schristos 		options.gen.zero_reg_nr = atoi (argp + strlen ("zero-r"));
14304e98e3e1Schristos 		options.warning (NULL,
14314e98e3e1Schristos 				 "Option zero-r<N> replaced by gen-zero-r<N>\n");
14324e98e3e1Schristos 	      }
14334e98e3e1Schristos 	    else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0)
14344e98e3e1Schristos 	      {
14354e98e3e1Schristos 		switch (argp[strlen ("gen-icache")])
14364e98e3e1Schristos 		  {
14374e98e3e1Schristos 		  case '=':
14384e98e3e1Schristos 		    options.gen.icache_size =
14394e98e3e1Schristos 		      atoi (argp + strlen ("gen-icache") + 1);
14404e98e3e1Schristos 		    options.gen.icache = enable_p;
14414e98e3e1Schristos 		    break;
14424e98e3e1Schristos 		  case '\0':
14434e98e3e1Schristos 		    options.gen.icache = enable_p;
14444e98e3e1Schristos 		    break;
14454e98e3e1Schristos 		  default:
14464e98e3e1Schristos 		    error (NULL,
14474e98e3e1Schristos 			   "Expecting -Ggen-icache or -Ggen-icache=<N>\n");
14484e98e3e1Schristos 		  }
14494e98e3e1Schristos 	      }
14504e98e3e1Schristos 	    else if (strcmp (argp, "gen-insn-in-icache") == 0)
14514e98e3e1Schristos 	      {
14524e98e3e1Schristos 		options.gen.insn_in_icache = enable_p;
14534e98e3e1Schristos 	      }
14544e98e3e1Schristos 	    else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim"))
14554e98e3e1Schristos 		     == 0)
14564e98e3e1Schristos 	      {
14574e98e3e1Schristos 		char *arg = &argp[strlen ("gen-multi-sim")];
14584e98e3e1Schristos 		switch (arg[0])
14594e98e3e1Schristos 		  {
14604e98e3e1Schristos 		  case '=':
14614e98e3e1Schristos 		    options.gen.multi_sim = enable_p;
14624e98e3e1Schristos 		    options.gen.default_model = arg + 1;
14634e98e3e1Schristos 		    if (!filter_is_member
14644e98e3e1Schristos 			(options.model_filter, options.gen.default_model))
14654e98e3e1Schristos 		      error (NULL, "multi-sim model %s unknown\n",
14664e98e3e1Schristos 			     options.gen.default_model);
14674e98e3e1Schristos 		    break;
14684e98e3e1Schristos 		  case '\0':
14694e98e3e1Schristos 		    options.gen.multi_sim = enable_p;
14704e98e3e1Schristos 		    options.gen.default_model = NULL;
14714e98e3e1Schristos 		    break;
14724e98e3e1Schristos 		  default:
14734e98e3e1Schristos 		    error (NULL,
14744e98e3e1Schristos 			   "Expecting -Ggen-multi-sim or -Ggen-multi-sim=<MODEL>\n");
14754e98e3e1Schristos 		    break;
14764e98e3e1Schristos 		  }
14774e98e3e1Schristos 	      }
14784e98e3e1Schristos 	    else if (strcmp (argp, "gen-multi-word") == 0)
14794e98e3e1Schristos 	      {
14804e98e3e1Schristos 		options.gen.multi_word = enable_p;
14814e98e3e1Schristos 	      }
14824e98e3e1Schristos 	    else if (strcmp (argp, "gen-semantic-icache") == 0)
14834e98e3e1Schristos 	      {
14844e98e3e1Schristos 		options.gen.semantic_icache = enable_p;
14854e98e3e1Schristos 	      }
14864e98e3e1Schristos 	    else if (strcmp (argp, "gen-slot-verification") == 0)
14874e98e3e1Schristos 	      {
14884e98e3e1Schristos 		options.gen.slot_verification = enable_p;
14894e98e3e1Schristos 	      }
14904e98e3e1Schristos 	    else if (strcmp (argp, "verify-slot") == 0)
14914e98e3e1Schristos 	      {
14924e98e3e1Schristos 		options.gen.slot_verification = enable_p;
14934e98e3e1Schristos 		options.warning (NULL,
14944e98e3e1Schristos 				 "Option verify-slot replaced by gen-slot-verification\n");
14954e98e3e1Schristos 	      }
14964e98e3e1Schristos 	    else if (strcmp (argp, "gen-nia-invalid") == 0)
14974e98e3e1Schristos 	      {
14984e98e3e1Schristos 		options.gen.nia = nia_is_invalid;
14994e98e3e1Schristos 	      }
15004e98e3e1Schristos 	    else if (strcmp (argp, "default-nia-minus-one") == 0)
15014e98e3e1Schristos 	      {
15024e98e3e1Schristos 		options.gen.nia = nia_is_invalid;
15034e98e3e1Schristos 		options.warning (NULL,
15044e98e3e1Schristos 				 "Option default-nia-minus-one replaced by gen-nia-invalid\n");
15054e98e3e1Schristos 	      }
15064e98e3e1Schristos 	    else if (strcmp (argp, "gen-nia-void") == 0)
15074e98e3e1Schristos 	      {
15084e98e3e1Schristos 		options.gen.nia = nia_is_void;
15094e98e3e1Schristos 	      }
15104e98e3e1Schristos 	    else if (strcmp (argp, "trace-all") == 0)
15114e98e3e1Schristos 	      {
15124e98e3e1Schristos 		memset (&options.trace, enable_p, sizeof (options.trace));
15134e98e3e1Schristos 	      }
15144e98e3e1Schristos 	    else if (strcmp (argp, "trace-combine") == 0)
15154e98e3e1Schristos 	      {
15164e98e3e1Schristos 		options.trace.combine = enable_p;
15174e98e3e1Schristos 	      }
15184e98e3e1Schristos 	    else if (strcmp (argp, "trace-entries") == 0)
15194e98e3e1Schristos 	      {
15204e98e3e1Schristos 		options.trace.entries = enable_p;
15214e98e3e1Schristos 	      }
15224e98e3e1Schristos 	    else if (strcmp (argp, "trace-rule-rejection") == 0)
15234e98e3e1Schristos 	      {
15244e98e3e1Schristos 		options.trace.rule_rejection = enable_p;
15254e98e3e1Schristos 	      }
15264e98e3e1Schristos 	    else if (strcmp (argp, "trace-rule-selection") == 0)
15274e98e3e1Schristos 	      {
15284e98e3e1Schristos 		options.trace.rule_selection = enable_p;
15294e98e3e1Schristos 	      }
15304e98e3e1Schristos 	    else if (strcmp (argp, "trace-insn-insertion") == 0)
15314e98e3e1Schristos 	      {
15324e98e3e1Schristos 		options.trace.insn_insertion = enable_p;
15334e98e3e1Schristos 	      }
15344e98e3e1Schristos 	    else if (strcmp (argp, "trace-insn-expansion") == 0)
15354e98e3e1Schristos 	      {
15364e98e3e1Schristos 		options.trace.insn_expansion = enable_p;
15374e98e3e1Schristos 	      }
15384e98e3e1Schristos 	    else if (strcmp (argp, "jumps") == 0)
15394e98e3e1Schristos 	      {
15404e98e3e1Schristos 		options.gen.code = generate_jumps;
15414e98e3e1Schristos 	      }
15424e98e3e1Schristos 	    else if (strcmp (argp, "field-widths") == 0)
15434e98e3e1Schristos 	      {
15444e98e3e1Schristos 		options.insn_specifying_widths = enable_p;
15454e98e3e1Schristos 	      }
15464e98e3e1Schristos 	    else if (strcmp (argp, "omit-line-numbers") == 0)
15474e98e3e1Schristos 	      {
15484e98e3e1Schristos 		file_references = lf_omit_references;
15494e98e3e1Schristos 	      }
15504e98e3e1Schristos 	    else
15514e98e3e1Schristos 	      {
15524e98e3e1Schristos 		error (NULL, "Unknown option %s\n", optarg);
15534e98e3e1Schristos 	      }
15544e98e3e1Schristos 	    break;
15554e98e3e1Schristos 	  }
15564e98e3e1Schristos 
15574e98e3e1Schristos 	case 'i':
15584e98e3e1Schristos 	  isa = load_insn_table (optarg, cache_rules);
15594e98e3e1Schristos 	  if (isa->illegal_insn == NULL)
15604e98e3e1Schristos 	    error (NULL, "illegal-instruction missing from insn table\n");
15614e98e3e1Schristos 	  break;
15624e98e3e1Schristos 
15634e98e3e1Schristos 	case 'x':
15644e98e3e1Schristos 	  gen = do_gen (isa, decode_rules);
15654e98e3e1Schristos 	  break;
15664e98e3e1Schristos 
15674e98e3e1Schristos 	case 'o':
15684e98e3e1Schristos 	  decode_rules = load_decode_table (optarg);
15694e98e3e1Schristos 	  break;
15704e98e3e1Schristos 
15714e98e3e1Schristos 	case 'k':
15724e98e3e1Schristos 	  if (isa != NULL)
15734e98e3e1Schristos 	    error (NULL, "Cache file must appear before the insn file\n");
15744e98e3e1Schristos 	  cache_rules = load_cache_table (optarg);
15754e98e3e1Schristos 	  break;
15764e98e3e1Schristos 
15774e98e3e1Schristos 	case 'n':
15784e98e3e1Schristos 	  real_file_name = strdup (optarg);
15794e98e3e1Schristos 	  break;
15804e98e3e1Schristos 
15814e98e3e1Schristos 	case 'h':
15824e98e3e1Schristos 	  is_header = 1;
15834e98e3e1Schristos 	  break;
15844e98e3e1Schristos 
15854e98e3e1Schristos 	case 'c':
15864e98e3e1Schristos 	case 'd':
15874e98e3e1Schristos 	case 'e':
15884e98e3e1Schristos 	case 'f':
15894e98e3e1Schristos 	case 'm':
15904e98e3e1Schristos 	case 'r':
15914e98e3e1Schristos 	case 's':
15924e98e3e1Schristos 	case 't':
15934e98e3e1Schristos 	  {
15944e98e3e1Schristos 	    lf *file = lf_open (optarg, real_file_name, file_references,
15954e98e3e1Schristos 				(is_header ? lf_is_h : lf_is_c),
15964e98e3e1Schristos 				argv[0]);
15974e98e3e1Schristos 	    if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f')
15984e98e3e1Schristos 	      {
15994e98e3e1Schristos 		options.warning (NULL,
16004e98e3e1Schristos 				 "Explicitly generate tables with -x option\n");
16014e98e3e1Schristos 		gen = do_gen (isa, decode_rules);
16024e98e3e1Schristos 	      }
16034e98e3e1Schristos 	    lf_print__file_start (file);
16044e98e3e1Schristos 	    switch (ch)
16054e98e3e1Schristos 	      {
16064e98e3e1Schristos 	      case 'm':
16074e98e3e1Schristos 		if (is_header)
16084e98e3e1Schristos 		  gen_model_h (file, isa);
16094e98e3e1Schristos 		else
16104e98e3e1Schristos 		  gen_model_c (file, isa);
16114e98e3e1Schristos 		break;
16124e98e3e1Schristos 	      case 't':
16134e98e3e1Schristos 		if (is_header)
16144e98e3e1Schristos 		  gen_itable_h (file, isa);
16154e98e3e1Schristos 		else
16164e98e3e1Schristos 		  gen_itable_c (file, isa);
16174e98e3e1Schristos 		break;
16184e98e3e1Schristos 	      case 'f':
16194e98e3e1Schristos 		if (is_header)
16204e98e3e1Schristos 		  gen_support_h (file, isa);
16214e98e3e1Schristos 		else
16224e98e3e1Schristos 		  gen_support_c (file, isa);
16234e98e3e1Schristos 		break;
16244e98e3e1Schristos 	      case 'r':
16254e98e3e1Schristos 		if (is_header)
16264e98e3e1Schristos 		  options.warning (NULL, "-hr option ignored\n");
16274e98e3e1Schristos 		else
16284e98e3e1Schristos 		  gen_run_c (file, gen);
16294e98e3e1Schristos 		break;
16304e98e3e1Schristos 	      case 's':
16314e98e3e1Schristos 		if (is_header)
16324e98e3e1Schristos 		  gen_semantics_h (file, gen->semantics, isa->max_nr_words);
16334e98e3e1Schristos 		else
16344e98e3e1Schristos 		  gen_semantics_c (file, gen->semantics, isa->caches);
16354e98e3e1Schristos 		break;
16364e98e3e1Schristos 	      case 'd':
16374e98e3e1Schristos 		if (is_header)
16384e98e3e1Schristos 		  gen_idecode_h (file, gen, isa, cache_rules);
16394e98e3e1Schristos 		else
16404e98e3e1Schristos 		  gen_idecode_c (file, gen, isa, cache_rules);
16414e98e3e1Schristos 		break;
16424e98e3e1Schristos 	      case 'e':
16434e98e3e1Schristos 		if (is_header)
16444e98e3e1Schristos 		  gen_engine_h (file, gen, isa, cache_rules);
16454e98e3e1Schristos 		else
16464e98e3e1Schristos 		  gen_engine_c (file, gen, isa, cache_rules);
16474e98e3e1Schristos 		break;
16484e98e3e1Schristos 	      case 'c':
16494e98e3e1Schristos 		if (is_header)
16504e98e3e1Schristos 		  gen_icache_h (file,
16514e98e3e1Schristos 				gen->semantics,
16524e98e3e1Schristos 				isa->functions, isa->max_nr_words);
16534e98e3e1Schristos 		else
16544e98e3e1Schristos 		  gen_icache_c (file,
16554e98e3e1Schristos 				gen->semantics, isa->functions, cache_rules);
16564e98e3e1Schristos 		break;
16574e98e3e1Schristos 	      }
16584e98e3e1Schristos 	    lf_print__file_finish (file);
16594e98e3e1Schristos 	    lf_close (file);
16604e98e3e1Schristos 	    is_header = 0;
16614e98e3e1Schristos 	  }
16624e98e3e1Schristos 	  real_file_name = NULL;
16634e98e3e1Schristos 	  break;
16644e98e3e1Schristos 	default:
16654e98e3e1Schristos 	  ERROR ("Bad switch");
16664e98e3e1Schristos 	}
16674e98e3e1Schristos     }
16684e98e3e1Schristos   return (0);
16694e98e3e1Schristos }
1670