Home | History | Annotate | Line # | Download | only in igen
igen.c revision 1.1
      1  1.1  christos /* The IGEN simulator generator for GDB, the GNU Debugger.
      2  1.1  christos 
      3  1.1  christos    Copyright 2002-2014 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    Contributed by Andrew Cagney.
      6  1.1  christos 
      7  1.1  christos    This file is part of GDB.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21  1.1  christos 
     22  1.1  christos 
     23  1.1  christos 
     24  1.1  christos #include <getopt.h>
     25  1.1  christos 
     26  1.1  christos #include "misc.h"
     27  1.1  christos #include "lf.h"
     28  1.1  christos #include "table.h"
     29  1.1  christos #include "config.h"
     30  1.1  christos #include "filter.h"
     31  1.1  christos 
     32  1.1  christos #include "igen.h"
     33  1.1  christos 
     34  1.1  christos #include "ld-insn.h"
     35  1.1  christos #include "ld-decode.h"
     36  1.1  christos #include "ld-cache.h"
     37  1.1  christos 
     38  1.1  christos #include "gen.h"
     39  1.1  christos 
     40  1.1  christos #include "gen-model.h"
     41  1.1  christos #include "gen-icache.h"
     42  1.1  christos #include "gen-itable.h"
     43  1.1  christos #include "gen-idecode.h"
     44  1.1  christos #include "gen-semantics.h"
     45  1.1  christos #include "gen-engine.h"
     46  1.1  christos #include "gen-support.h"
     47  1.1  christos #include "gen-engine.h"
     48  1.1  christos 
     49  1.1  christos 
     50  1.1  christos /****************************************************************/
     51  1.1  christos 
     52  1.1  christos 
     53  1.1  christos /* Semantic functions */
     54  1.1  christos 
     55  1.1  christos int
     56  1.1  christos print_semantic_function_formal (lf *file, int nr_prefetched_words)
     57  1.1  christos {
     58  1.1  christos   int nr = 0;
     59  1.1  christos   int word_nr;
     60  1.1  christos   if (options.gen.icache || nr_prefetched_words < 0)
     61  1.1  christos     {
     62  1.1  christos       nr += lf_printf (file, "SIM_DESC sd,\n");
     63  1.1  christos       nr += lf_printf (file, "%sidecode_cache *cache_entry,\n",
     64  1.1  christos 		       options.module.global.prefix.l);
     65  1.1  christos       nr += lf_printf (file, "%sinstruction_address cia",
     66  1.1  christos 		       options.module.global.prefix.l);
     67  1.1  christos     }
     68  1.1  christos   else if (options.gen.smp)
     69  1.1  christos     {
     70  1.1  christos       nr += lf_printf (file, "sim_cpu *cpu,\n");
     71  1.1  christos       for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
     72  1.1  christos 	{
     73  1.1  christos 	  nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
     74  1.1  christos 			   options.module.global.prefix.l, word_nr);
     75  1.1  christos 	}
     76  1.1  christos       nr += lf_printf (file, "%sinstruction_address cia",
     77  1.1  christos 		       options.module.global.prefix.l);
     78  1.1  christos     }
     79  1.1  christos   else
     80  1.1  christos     {
     81  1.1  christos       nr += lf_printf (file, "SIM_DESC sd,\n");
     82  1.1  christos       for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
     83  1.1  christos 	{
     84  1.1  christos 	  nr += lf_printf (file, "%sinstruction_word instruction_%d,\n",
     85  1.1  christos 			   options.module.global.prefix.l, word_nr);
     86  1.1  christos 	}
     87  1.1  christos       nr += lf_printf (file, "%sinstruction_address cia",
     88  1.1  christos 		       options.module.global.prefix.l);
     89  1.1  christos     }
     90  1.1  christos   return nr;
     91  1.1  christos }
     92  1.1  christos 
     93  1.1  christos int
     94  1.1  christos print_semantic_function_actual (lf *file, int nr_prefetched_words)
     95  1.1  christos {
     96  1.1  christos   int nr = 0;
     97  1.1  christos   int word_nr;
     98  1.1  christos   if (options.gen.icache || nr_prefetched_words < 0)
     99  1.1  christos     {
    100  1.1  christos       nr += lf_printf (file, "sd, cache_entry, cia");
    101  1.1  christos     }
    102  1.1  christos   else
    103  1.1  christos     {
    104  1.1  christos       if (options.gen.smp)
    105  1.1  christos 	nr += lf_printf (file, "cpu");
    106  1.1  christos       else
    107  1.1  christos 	nr += lf_printf (file, "sd");
    108  1.1  christos       for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
    109  1.1  christos 	nr += lf_printf (file, ", instruction_%d", word_nr);
    110  1.1  christos       nr += lf_printf (file, ", cia");
    111  1.1  christos     }
    112  1.1  christos   return nr;
    113  1.1  christos }
    114  1.1  christos 
    115  1.1  christos int
    116  1.1  christos print_semantic_function_type (lf *file)
    117  1.1  christos {
    118  1.1  christos   int nr = 0;
    119  1.1  christos   nr += lf_printf (file, "%sinstruction_address",
    120  1.1  christos 		   options.module.global.prefix.l);
    121  1.1  christos   return nr;
    122  1.1  christos }
    123  1.1  christos 
    124  1.1  christos 
    125  1.1  christos /* Idecode functions */
    126  1.1  christos 
    127  1.1  christos int
    128  1.1  christos print_icache_function_formal (lf *file, int nr_prefetched_words)
    129  1.1  christos {
    130  1.1  christos   int nr = 0;
    131  1.1  christos   int word_nr;
    132  1.1  christos   if (options.gen.smp)
    133  1.1  christos     nr += lf_printf (file, "sim_cpu *cpu,\n");
    134  1.1  christos   else
    135  1.1  christos     nr += lf_printf (file, "SIM_DESC sd,\n");
    136  1.1  christos   for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
    137  1.1  christos     nr += lf_printf (file, " %sinstruction_word instruction_%d,\n",
    138  1.1  christos 		     options.module.global.prefix.l, word_nr);
    139  1.1  christos   nr += lf_printf (file, " %sinstruction_address cia,\n",
    140  1.1  christos 		   options.module.global.prefix.l);
    141  1.1  christos   nr += lf_printf (file, " %sidecode_cache *cache_entry",
    142  1.1  christos 		   options.module.global.prefix.l);
    143  1.1  christos   return nr;
    144  1.1  christos }
    145  1.1  christos 
    146  1.1  christos int
    147  1.1  christos print_icache_function_actual (lf *file, int nr_prefetched_words)
    148  1.1  christos {
    149  1.1  christos   int nr = 0;
    150  1.1  christos   int word_nr;
    151  1.1  christos   if (options.gen.smp)
    152  1.1  christos     nr += lf_printf (file, "cpu");
    153  1.1  christos   else
    154  1.1  christos     nr += lf_printf (file, "sd");
    155  1.1  christos   for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
    156  1.1  christos     nr += lf_printf (file, ", instruction_%d", word_nr);
    157  1.1  christos   nr += lf_printf (file, ", cia, cache_entry");
    158  1.1  christos   return nr;
    159  1.1  christos }
    160  1.1  christos 
    161  1.1  christos int
    162  1.1  christos print_icache_function_type (lf *file)
    163  1.1  christos {
    164  1.1  christos   int nr;
    165  1.1  christos   if (options.gen.semantic_icache)
    166  1.1  christos     {
    167  1.1  christos       nr = print_semantic_function_type (file);
    168  1.1  christos     }
    169  1.1  christos   else
    170  1.1  christos     {
    171  1.1  christos       nr = lf_printf (file, "%sidecode_semantic *",
    172  1.1  christos 		      options.module.global.prefix.l);
    173  1.1  christos     }
    174  1.1  christos   return nr;
    175  1.1  christos }
    176  1.1  christos 
    177  1.1  christos 
    178  1.1  christos /* Function names */
    179  1.1  christos 
    180  1.1  christos static int
    181  1.1  christos print_opcode_bits (lf *file, opcode_bits *bits)
    182  1.1  christos {
    183  1.1  christos   int nr = 0;
    184  1.1  christos   if (bits == NULL)
    185  1.1  christos     return nr;
    186  1.1  christos   nr += lf_putchr (file, '_');
    187  1.1  christos   nr += lf_putstr (file, bits->field->val_string);
    188  1.1  christos   if (bits->opcode->is_boolean && bits->value == 0)
    189  1.1  christos     nr += lf_putint (file, bits->opcode->boolean_constant);
    190  1.1  christos   else if (!bits->opcode->is_boolean)
    191  1.1  christos     {
    192  1.1  christos       if (bits->opcode->last < bits->field->last)
    193  1.1  christos 	nr +=
    194  1.1  christos 	  lf_putint (file,
    195  1.1  christos 		     bits->value << (bits->field->last - bits->opcode->last));
    196  1.1  christos       else
    197  1.1  christos 	nr += lf_putint (file, bits->value);
    198  1.1  christos     }
    199  1.1  christos   nr += print_opcode_bits (file, bits->next);
    200  1.1  christos   return nr;
    201  1.1  christos }
    202  1.1  christos 
    203  1.1  christos static int
    204  1.1  christos print_c_name (lf *file, const char *name)
    205  1.1  christos {
    206  1.1  christos   int nr = 0;
    207  1.1  christos   const char *pos;
    208  1.1  christos   for (pos = name; *pos != '\0'; pos++)
    209  1.1  christos     {
    210  1.1  christos       switch (*pos)
    211  1.1  christos 	{
    212  1.1  christos 	case '/':
    213  1.1  christos 	case '-':
    214  1.1  christos 	  break;
    215  1.1  christos 	case ' ':
    216  1.1  christos 	case '.':
    217  1.1  christos 	  nr += lf_putchr (file, '_');
    218  1.1  christos 	  break;
    219  1.1  christos 	default:
    220  1.1  christos 	  nr += lf_putchr (file, *pos);
    221  1.1  christos 	  break;
    222  1.1  christos 	}
    223  1.1  christos     }
    224  1.1  christos   return nr;
    225  1.1  christos }
    226  1.1  christos 
    227  1.1  christos extern int
    228  1.1  christos print_function_name (lf *file,
    229  1.1  christos 		     const char *basename,
    230  1.1  christos 		     const char *format_name,
    231  1.1  christos 		     const char *model_name,
    232  1.1  christos 		     opcode_bits *expanded_bits,
    233  1.1  christos 		     lf_function_name_prefixes prefix)
    234  1.1  christos {
    235  1.1  christos   int nr = 0;
    236  1.1  christos   /* the prefix */
    237  1.1  christos   switch (prefix)
    238  1.1  christos     {
    239  1.1  christos     case function_name_prefix_semantics:
    240  1.1  christos       nr += lf_printf (file, "%s", options.module.semantics.prefix.l);
    241  1.1  christos       nr += lf_printf (file, "semantic_");
    242  1.1  christos       break;
    243  1.1  christos     case function_name_prefix_idecode:
    244  1.1  christos       nr += lf_printf (file, "%s", options.module.idecode.prefix.l);
    245  1.1  christos       nr += lf_printf (file, "idecode_");
    246  1.1  christos       break;
    247  1.1  christos     case function_name_prefix_itable:
    248  1.1  christos       nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l);
    249  1.1  christos       break;
    250  1.1  christos     case function_name_prefix_icache:
    251  1.1  christos       nr += lf_printf (file, "%s", options.module.icache.prefix.l);
    252  1.1  christos       nr += lf_printf (file, "icache_");
    253  1.1  christos       break;
    254  1.1  christos     case function_name_prefix_engine:
    255  1.1  christos       nr += lf_printf (file, "%s", options.module.engine.prefix.l);
    256  1.1  christos       nr += lf_printf (file, "engine_");
    257  1.1  christos     default:
    258  1.1  christos       break;
    259  1.1  christos     }
    260  1.1  christos 
    261  1.1  christos   if (model_name != NULL)
    262  1.1  christos     {
    263  1.1  christos       nr += print_c_name (file, model_name);
    264  1.1  christos       nr += lf_printf (file, "_");
    265  1.1  christos     }
    266  1.1  christos 
    267  1.1  christos   /* the function name */
    268  1.1  christos   nr += print_c_name (file, basename);
    269  1.1  christos 
    270  1.1  christos   /* the format name if available */
    271  1.1  christos   if (format_name != NULL)
    272  1.1  christos     {
    273  1.1  christos       nr += lf_printf (file, "_");
    274  1.1  christos       nr += print_c_name (file, format_name);
    275  1.1  christos     }
    276  1.1  christos 
    277  1.1  christos   /* the suffix */
    278  1.1  christos   nr += print_opcode_bits (file, expanded_bits);
    279  1.1  christos 
    280  1.1  christos   return nr;
    281  1.1  christos }
    282  1.1  christos 
    283  1.1  christos 
    284  1.1  christos void
    285  1.1  christos print_my_defines (lf *file,
    286  1.1  christos 		  const char *basename,
    287  1.1  christos 		  const char *format_name, opcode_bits *expanded_bits)
    288  1.1  christos {
    289  1.1  christos   /* #define MY_INDEX xxxxx */
    290  1.1  christos   lf_indent_suppress (file);
    291  1.1  christos   lf_printf (file, "#undef MY_INDEX\n");
    292  1.1  christos   lf_indent_suppress (file);
    293  1.1  christos   lf_printf (file, "#define MY_INDEX ");
    294  1.1  christos   print_function_name (file,
    295  1.1  christos 		       basename, format_name, NULL,
    296  1.1  christos 		       NULL, function_name_prefix_itable);
    297  1.1  christos   lf_printf (file, "\n");
    298  1.1  christos   /* #define MY_PREFIX xxxxxx */
    299  1.1  christos   lf_indent_suppress (file);
    300  1.1  christos   lf_printf (file, "#undef ");
    301  1.1  christos   print_function_name (file,
    302  1.1  christos 		       basename, format_name, NULL,
    303  1.1  christos 		       expanded_bits, function_name_prefix_none);
    304  1.1  christos   lf_printf (file, "\n");
    305  1.1  christos   lf_indent_suppress (file);
    306  1.1  christos   lf_printf (file, "#undef MY_PREFIX\n");
    307  1.1  christos   lf_indent_suppress (file);
    308  1.1  christos   lf_printf (file, "#define MY_PREFIX ");
    309  1.1  christos   print_function_name (file,
    310  1.1  christos 		       basename, format_name, NULL,
    311  1.1  christos 		       expanded_bits, function_name_prefix_none);
    312  1.1  christos   lf_printf (file, "\n");
    313  1.1  christos   /* #define MY_NAME xxxxxx */
    314  1.1  christos   lf_indent_suppress (file);
    315  1.1  christos   lf_indent_suppress (file);
    316  1.1  christos   lf_printf (file, "#undef MY_NAME\n");
    317  1.1  christos   lf_indent_suppress (file);
    318  1.1  christos   lf_printf (file, "#define MY_NAME \"");
    319  1.1  christos   print_function_name (file,
    320  1.1  christos 		       basename, format_name, NULL,
    321  1.1  christos 		       expanded_bits, function_name_prefix_none);
    322  1.1  christos   lf_printf (file, "\"\n");
    323  1.1  christos }
    324  1.1  christos 
    325  1.1  christos 
    326  1.1  christos static int
    327  1.1  christos print_itrace_prefix (lf *file)
    328  1.1  christos {
    329  1.1  christos   const char *prefix = "trace_prefix (";
    330  1.1  christos   int indent = strlen (prefix);
    331  1.1  christos   lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n",
    332  1.1  christos 	     prefix);
    333  1.1  christos   lf_indent (file, +indent);
    334  1.1  christos   lf_printf (file, "%sitable[MY_INDEX].file, \\\n",
    335  1.1  christos 	     options.module.itable.prefix.l);
    336  1.1  christos   lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n",
    337  1.1  christos 	     options.module.itable.prefix.l);
    338  1.1  christos   lf_printf (file, "\"");
    339  1.1  christos   return indent;
    340  1.1  christos }
    341  1.1  christos 
    342  1.1  christos 
    343  1.1  christos static void
    344  1.1  christos print_itrace_format (lf *file, insn_mnemonic_entry *assembler)
    345  1.1  christos {
    346  1.1  christos   /* pass=1 is fmt string; pass=2 is arguments */
    347  1.1  christos   int pass;
    348  1.1  christos   /* print the format string */
    349  1.1  christos   for (pass = 1; pass <= 2; pass++)
    350  1.1  christos     {
    351  1.1  christos       const char *chp = assembler->format;
    352  1.1  christos       chp++;			/* skip the leading quote */
    353  1.1  christos       /* write out the format/args */
    354  1.1  christos       while (*chp != '\0')
    355  1.1  christos 	{
    356  1.1  christos 	  if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>'))
    357  1.1  christos 	    {
    358  1.1  christos 	      if (pass == 1)
    359  1.1  christos 		lf_putchr (file, chp[1]);
    360  1.1  christos 	      chp += 2;
    361  1.1  christos 	    }
    362  1.1  christos 	  else if (chp[0] == '<' || chp[0] == '%')
    363  1.1  christos 	    {
    364  1.1  christos 	      /* parse [ "%" ... ] "<" [ func "#" ] param ">" */
    365  1.1  christos 	      const char *fmt;
    366  1.1  christos 	      const char *func;
    367  1.1  christos 	      int strlen_func;
    368  1.1  christos 	      const char *param;
    369  1.1  christos 	      int strlen_param;
    370  1.1  christos 	      /* the "%" ... "<" format */
    371  1.1  christos 	      fmt = chp;
    372  1.1  christos 	      while (chp[0] != '<' && chp[0] != '\0')
    373  1.1  christos 		chp++;
    374  1.1  christos 	      if (chp[0] != '<')
    375  1.1  christos 		error (assembler->line, "Missing `<' after `%%'\n");
    376  1.1  christos 	      chp++;
    377  1.1  christos 	      /* [ "func" # ] OR "param" */
    378  1.1  christos 	      func = chp;
    379  1.1  christos 	      param = chp;
    380  1.1  christos 	      while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0')
    381  1.1  christos 		chp++;
    382  1.1  christos 	      strlen_func = chp - func;
    383  1.1  christos 	      if (chp[0] == '#')
    384  1.1  christos 		{
    385  1.1  christos 		  chp++;
    386  1.1  christos 		  param = chp;
    387  1.1  christos 		  while (chp[0] != '>' && chp[0] != '\0')
    388  1.1  christos 		    chp++;
    389  1.1  christos 		}
    390  1.1  christos 	      strlen_param = chp - param;
    391  1.1  christos 	      if (chp[0] != '>')
    392  1.1  christos 		error (assembler->line,
    393  1.1  christos 		       "Missing closing `>' in assembler string\n");
    394  1.1  christos 	      chp++;
    395  1.1  christos 	      /* now process it */
    396  1.1  christos 	      if (pass == 2)
    397  1.1  christos 		lf_printf (file, ", \\\n");
    398  1.1  christos 	      if (strncmp (fmt, "<", 1) == 0)
    399  1.1  christos 		/* implicit long int format */
    400  1.1  christos 		{
    401  1.1  christos 		  if (pass == 1)
    402  1.1  christos 		    lf_printf (file, "%%ld");
    403  1.1  christos 		  else
    404  1.1  christos 		    {
    405  1.1  christos 		      lf_printf (file, "(long) ");
    406  1.1  christos 		      lf_write (file, param, strlen_param);
    407  1.1  christos 		    }
    408  1.1  christos 		}
    409  1.1  christos 	      else if (strncmp (fmt, "%<", 2) == 0)
    410  1.1  christos 		/* explicit format */
    411  1.1  christos 		{
    412  1.1  christos 		  if (pass == 1)
    413  1.1  christos 		    lf_printf (file, "%%");
    414  1.1  christos 		  else
    415  1.1  christos 		    lf_write (file, param, strlen_param);
    416  1.1  christos 		}
    417  1.1  christos 	      else if (strncmp (fmt, "%s<", 3) == 0)
    418  1.1  christos 		/* string format */
    419  1.1  christos 		{
    420  1.1  christos 		  if (pass == 1)
    421  1.1  christos 		    lf_printf (file, "%%s");
    422  1.1  christos 		  else
    423  1.1  christos 		    {
    424  1.1  christos 		      lf_printf (file, "%sstr_",
    425  1.1  christos 				 options.module.global.prefix.l);
    426  1.1  christos 		      lf_write (file, func, strlen_func);
    427  1.1  christos 		      lf_printf (file, " (SD_, ");
    428  1.1  christos 		      lf_write (file, param, strlen_param);
    429  1.1  christos 		      lf_printf (file, ")");
    430  1.1  christos 		    }
    431  1.1  christos 		}
    432  1.1  christos 	      else if (strncmp (fmt, "%lx<", 4) == 0)
    433  1.1  christos 		/* simple hex */
    434  1.1  christos 		{
    435  1.1  christos 		  if (pass == 1)
    436  1.1  christos 		    lf_printf (file, "%%lx");
    437  1.1  christos 		  else
    438  1.1  christos 		    {
    439  1.1  christos 		      lf_printf (file, "(unsigned long) ");
    440  1.1  christos 		      lf_write (file, param, strlen_param);
    441  1.1  christos 		    }
    442  1.1  christos 		}
    443  1.1  christos 	      else if (strncmp (fmt, "%#lx<", 5) == 0)
    444  1.1  christos 		/* simple hex with 0x prefix */
    445  1.1  christos 		{
    446  1.1  christos 		  if (pass == 1)
    447  1.1  christos 		    lf_printf (file, "%%#lx");
    448  1.1  christos 		  else
    449  1.1  christos 		    {
    450  1.1  christos 		      lf_printf (file, "(unsigned long) ");
    451  1.1  christos 		      lf_write (file, param, strlen_param);
    452  1.1  christos 		    }
    453  1.1  christos 		}
    454  1.1  christos 	      else if (strncmp (fmt, "%08lx<", 6) == 0)
    455  1.1  christos 		/* simple hex */
    456  1.1  christos 		{
    457  1.1  christos 		  if (pass == 1)
    458  1.1  christos 		    lf_printf (file, "%%08lx");
    459  1.1  christos 		  else
    460  1.1  christos 		    {
    461  1.1  christos 		      lf_printf (file, "(unsigned long) ");
    462  1.1  christos 		      lf_write (file, param, strlen_param);
    463  1.1  christos 		    }
    464  1.1  christos 		}
    465  1.1  christos 	      else
    466  1.1  christos 		error (assembler->line, "Unknown assembler string format\n");
    467  1.1  christos 	    }
    468  1.1  christos 	  else
    469  1.1  christos 	    {
    470  1.1  christos 	      if (pass == 1)
    471  1.1  christos 		lf_putchr (file, chp[0]);
    472  1.1  christos 	      chp += 1;
    473  1.1  christos 	    }
    474  1.1  christos 	}
    475  1.1  christos     }
    476  1.1  christos   lf_printf (file, ");\n");
    477  1.1  christos }
    478  1.1  christos 
    479  1.1  christos 
    480  1.1  christos void
    481  1.1  christos print_itrace (lf *file, insn_entry * insn, int idecode)
    482  1.1  christos {
    483  1.1  christos   /* NB: Here we escape each EOLN. This is so that the the compiler
    484  1.1  christos      treats a trace function call as a single line.  Consequently any
    485  1.1  christos      errors in the line are refered back to the same igen assembler
    486  1.1  christos      source line */
    487  1.1  christos   const char *phase = (idecode) ? "DECODE" : "INSN";
    488  1.1  christos   lf_printf (file, "\n");
    489  1.1  christos   lf_indent_suppress (file);
    490  1.1  christos   lf_printf (file, "#if defined (WITH_TRACE)\n");
    491  1.1  christos   lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n");
    492  1.1  christos   lf_printf (file, "if (TRACE_ANY_P (CPU))\n");
    493  1.1  christos   lf_printf (file, "  {\n");
    494  1.1  christos   lf_indent (file, +4);
    495  1.1  christos   {
    496  1.1  christos     if (insn->mnemonics != NULL)
    497  1.1  christos       {
    498  1.1  christos 	insn_mnemonic_entry *assembler = insn->mnemonics;
    499  1.1  christos 	int is_first = 1;
    500  1.1  christos 	do
    501  1.1  christos 	  {
    502  1.1  christos 	    if (assembler->condition != NULL)
    503  1.1  christos 	      {
    504  1.1  christos 		int indent;
    505  1.1  christos 		lf_printf (file, "%sif (%s)\n",
    506  1.1  christos 			   is_first ? "" : "else ", assembler->condition);
    507  1.1  christos 		lf_indent (file, +2);
    508  1.1  christos 		lf_print__line_ref (file, assembler->line);
    509  1.1  christos 		indent = print_itrace_prefix (file);
    510  1.1  christos 		print_itrace_format (file, assembler);
    511  1.1  christos 		lf_print__internal_ref (file);
    512  1.1  christos 		lf_indent (file, -indent);
    513  1.1  christos 		lf_indent (file, -2);
    514  1.1  christos 		if (assembler->next == NULL)
    515  1.1  christos 		  error (assembler->line,
    516  1.1  christos 			 "Missing final unconditional assembler\n");
    517  1.1  christos 	      }
    518  1.1  christos 	    else
    519  1.1  christos 	      {
    520  1.1  christos 		int indent;
    521  1.1  christos 		if (!is_first)
    522  1.1  christos 		  {
    523  1.1  christos 		    lf_printf (file, "else\n");
    524  1.1  christos 		    lf_indent (file, +2);
    525  1.1  christos 		  }
    526  1.1  christos 		lf_print__line_ref (file, assembler->line);
    527  1.1  christos 		indent = print_itrace_prefix (file);
    528  1.1  christos 		print_itrace_format (file, assembler);
    529  1.1  christos 		lf_print__internal_ref (file);
    530  1.1  christos 		lf_indent (file, -indent);
    531  1.1  christos 		if (!is_first)
    532  1.1  christos 		  lf_indent (file, -2);
    533  1.1  christos 		if (assembler->next != NULL)
    534  1.1  christos 		  error (assembler->line,
    535  1.1  christos 			 "Unconditional assembler is not last\n");
    536  1.1  christos 	      }
    537  1.1  christos 	    is_first = 0;
    538  1.1  christos 	    assembler = assembler->next;
    539  1.1  christos 	  }
    540  1.1  christos 	while (assembler != NULL);
    541  1.1  christos       }
    542  1.1  christos     else
    543  1.1  christos       {
    544  1.1  christos 	int indent;
    545  1.1  christos 	lf_indent (file, +2);
    546  1.1  christos 	lf_print__line_ref (file, insn->line);
    547  1.1  christos 	indent = print_itrace_prefix (file);
    548  1.1  christos 	lf_printf (file, "%%s\", \\\n");
    549  1.1  christos 	lf_printf (file, "itable[MY_INDEX].name);\n");
    550  1.1  christos 	lf_print__internal_ref (file);
    551  1.1  christos 	lf_indent (file, -indent);
    552  1.1  christos 	lf_indent (file, -2);
    553  1.1  christos       }
    554  1.1  christos     lf_printf (file, "/* trace the instruction execution if enabled */\n");
    555  1.1  christos     lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase);
    556  1.1  christos     lf_printf (file,
    557  1.1  christos 	       "  trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n",
    558  1.1  christos 	       phase);
    559  1.1  christos   }
    560  1.1  christos   lf_indent (file, -4);
    561  1.1  christos   lf_printf (file, "  }\n");
    562  1.1  christos   lf_indent_suppress (file);
    563  1.1  christos   lf_printf (file, "#endif\n");
    564  1.1  christos }
    565  1.1  christos 
    566  1.1  christos 
    567  1.1  christos void
    568  1.1  christos print_sim_engine_abort (lf *file, const char *message)
    569  1.1  christos {
    570  1.1  christos   lf_printf (file, "sim_engine_abort (SD, CPU, cia, ");
    571  1.1  christos   lf_printf (file, "\"%s\"", message);
    572  1.1  christos   lf_printf (file, ");\n");
    573  1.1  christos }
    574  1.1  christos 
    575  1.1  christos 
    576  1.1  christos void
    577  1.1  christos print_include (lf *file, igen_module module)
    578  1.1  christos {
    579  1.1  christos   lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l);
    580  1.1  christos }
    581  1.1  christos 
    582  1.1  christos void
    583  1.1  christos print_include_inline (lf *file, igen_module module)
    584  1.1  christos {
    585  1.1  christos   lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u);
    586  1.1  christos   lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l);
    587  1.1  christos   lf_printf (file, "#else\n");
    588  1.1  christos   print_include (file, module);
    589  1.1  christos   lf_printf (file, "#endif\n");
    590  1.1  christos   lf_printf (file, "\n");
    591  1.1  christos }
    592  1.1  christos 
    593  1.1  christos void
    594  1.1  christos print_includes (lf *file)
    595  1.1  christos {
    596  1.1  christos   lf_printf (file, "\n");
    597  1.1  christos   lf_printf (file, "#include \"sim-inline.c\"\n");
    598  1.1  christos   lf_printf (file, "\n");
    599  1.1  christos   print_include_inline (file, options.module.itable);
    600  1.1  christos   print_include_inline (file, options.module.idecode);
    601  1.1  christos   print_include_inline (file, options.module.support);
    602  1.1  christos }
    603  1.1  christos 
    604  1.1  christos 
    605  1.1  christos /****************************************************************/
    606  1.1  christos 
    607  1.1  christos 
    608  1.1  christos static void
    609  1.1  christos gen_semantics_h (lf *file, insn_list *semantics, int max_nr_words)
    610  1.1  christos {
    611  1.1  christos   int word_nr;
    612  1.1  christos   insn_list *semantic;
    613  1.1  christos   for (word_nr = -1; word_nr <= max_nr_words; word_nr++)
    614  1.1  christos     {
    615  1.1  christos       lf_printf (file, "typedef ");
    616  1.1  christos       print_semantic_function_type (file);
    617  1.1  christos       lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l);
    618  1.1  christos       if (word_nr >= 0)
    619  1.1  christos 	lf_printf (file, "_%d", word_nr);
    620  1.1  christos       lf_printf (file, "\n(");
    621  1.1  christos       lf_indent (file, +1);
    622  1.1  christos       print_semantic_function_formal (file, word_nr);
    623  1.1  christos       lf_indent (file, -1);
    624  1.1  christos       lf_printf (file, ");\n");
    625  1.1  christos       lf_printf (file, "\n");
    626  1.1  christos     }
    627  1.1  christos   switch (options.gen.code)
    628  1.1  christos     {
    629  1.1  christos     case generate_calls:
    630  1.1  christos       for (semantic = semantics; semantic != NULL; semantic = semantic->next)
    631  1.1  christos 	{
    632  1.1  christos 	  /* Ignore any special/internal instructions */
    633  1.1  christos 	  if (semantic->insn->nr_words == 0)
    634  1.1  christos 	    continue;
    635  1.1  christos 	  print_semantic_declaration (file,
    636  1.1  christos 				      semantic->insn,
    637  1.1  christos 				      semantic->expanded_bits,
    638  1.1  christos 				      semantic->opcodes,
    639  1.1  christos 				      semantic->nr_prefetched_words);
    640  1.1  christos 	}
    641  1.1  christos       break;
    642  1.1  christos     case generate_jumps:
    643  1.1  christos       lf_print__this_file_is_empty (file, "generating jumps");
    644  1.1  christos       break;
    645  1.1  christos     }
    646  1.1  christos }
    647  1.1  christos 
    648  1.1  christos 
    649  1.1  christos static void
    650  1.1  christos gen_semantics_c (lf *file, insn_list *semantics, cache_entry *cache_rules)
    651  1.1  christos {
    652  1.1  christos   if (options.gen.code == generate_calls)
    653  1.1  christos     {
    654  1.1  christos       insn_list *semantic;
    655  1.1  christos       print_includes (file);
    656  1.1  christos       print_include (file, options.module.semantics);
    657  1.1  christos       lf_printf (file, "\n");
    658  1.1  christos 
    659  1.1  christos       for (semantic = semantics; semantic != NULL; semantic = semantic->next)
    660  1.1  christos 	{
    661  1.1  christos 	  /* Ignore any special/internal instructions */
    662  1.1  christos 	  if (semantic->insn->nr_words == 0)
    663  1.1  christos 	    continue;
    664  1.1  christos 	  print_semantic_definition (file,
    665  1.1  christos 				     semantic->insn,
    666  1.1  christos 				     semantic->expanded_bits,
    667  1.1  christos 				     semantic->opcodes,
    668  1.1  christos 				     cache_rules,
    669  1.1  christos 				     semantic->nr_prefetched_words);
    670  1.1  christos 	}
    671  1.1  christos     }
    672  1.1  christos   else
    673  1.1  christos     {
    674  1.1  christos       lf_print__this_file_is_empty (file, "generating jump engine");
    675  1.1  christos     }
    676  1.1  christos }
    677  1.1  christos 
    678  1.1  christos 
    679  1.1  christos /****************************************************************/
    680  1.1  christos 
    681  1.1  christos 
    682  1.1  christos static void
    683  1.1  christos gen_icache_h (lf *file,
    684  1.1  christos 	      insn_list *semantic,
    685  1.1  christos 	      function_entry * functions, int max_nr_words)
    686  1.1  christos {
    687  1.1  christos   int word_nr;
    688  1.1  christos   for (word_nr = 0; word_nr <= max_nr_words; word_nr++)
    689  1.1  christos     {
    690  1.1  christos       lf_printf (file, "typedef ");
    691  1.1  christos       print_icache_function_type (file);
    692  1.1  christos       lf_printf (file, " %sidecode_icache_%d\n(",
    693  1.1  christos 		 options.module.global.prefix.l, word_nr);
    694  1.1  christos       print_icache_function_formal (file, word_nr);
    695  1.1  christos       lf_printf (file, ");\n");
    696  1.1  christos       lf_printf (file, "\n");
    697  1.1  christos     }
    698  1.1  christos   if (options.gen.code == generate_calls && options.gen.icache)
    699  1.1  christos     {
    700  1.1  christos       function_entry_traverse (file, functions,
    701  1.1  christos 			       print_icache_internal_function_declaration,
    702  1.1  christos 			       NULL);
    703  1.1  christos       while (semantic != NULL)
    704  1.1  christos 	{
    705  1.1  christos 	  print_icache_declaration (file,
    706  1.1  christos 				    semantic->insn,
    707  1.1  christos 				    semantic->expanded_bits,
    708  1.1  christos 				    semantic->opcodes,
    709  1.1  christos 				    semantic->nr_prefetched_words);
    710  1.1  christos 	  semantic = semantic->next;
    711  1.1  christos 	}
    712  1.1  christos     }
    713  1.1  christos   else
    714  1.1  christos     {
    715  1.1  christos       lf_print__this_file_is_empty (file, "generating jump engine");
    716  1.1  christos     }
    717  1.1  christos }
    718  1.1  christos 
    719  1.1  christos static void
    720  1.1  christos gen_icache_c (lf *file,
    721  1.1  christos 	      insn_list *semantic,
    722  1.1  christos 	      function_entry * functions, cache_entry *cache_rules)
    723  1.1  christos {
    724  1.1  christos   /* output `internal' invalid/floating-point unavailable functions
    725  1.1  christos      where needed */
    726  1.1  christos   if (options.gen.code == generate_calls && options.gen.icache)
    727  1.1  christos     {
    728  1.1  christos       lf_printf (file, "\n");
    729  1.1  christos       lf_printf (file, "#include \"cpu.h\"\n");
    730  1.1  christos       lf_printf (file, "#include \"idecode.h\"\n");
    731  1.1  christos       lf_printf (file, "#include \"semantics.h\"\n");
    732  1.1  christos       lf_printf (file, "#include \"icache.h\"\n");
    733  1.1  christos       lf_printf (file, "#include \"support.h\"\n");
    734  1.1  christos       lf_printf (file, "\n");
    735  1.1  christos       function_entry_traverse (file, functions,
    736  1.1  christos 			       print_icache_internal_function_definition,
    737  1.1  christos 			       NULL);
    738  1.1  christos       lf_printf (file, "\n");
    739  1.1  christos       while (semantic != NULL)
    740  1.1  christos 	{
    741  1.1  christos 	  print_icache_definition (file,
    742  1.1  christos 				   semantic->insn,
    743  1.1  christos 				   semantic->expanded_bits,
    744  1.1  christos 				   semantic->opcodes,
    745  1.1  christos 				   cache_rules,
    746  1.1  christos 				   semantic->nr_prefetched_words);
    747  1.1  christos 	  semantic = semantic->next;
    748  1.1  christos 	}
    749  1.1  christos     }
    750  1.1  christos   else
    751  1.1  christos     {
    752  1.1  christos       lf_print__this_file_is_empty (file, "generating jump engine");
    753  1.1  christos     }
    754  1.1  christos }
    755  1.1  christos 
    756  1.1  christos 
    757  1.1  christos /****************************************************************/
    758  1.1  christos 
    759  1.1  christos 
    760  1.1  christos static void
    761  1.1  christos gen_idecode_h (lf *file,
    762  1.1  christos 	       gen_table *gen, insn_table *insns, cache_entry *cache_rules)
    763  1.1  christos {
    764  1.1  christos   lf_printf (file, "typedef unsigned%d %sinstruction_word;\n",
    765  1.1  christos 	     options.insn_bit_size, options.module.global.prefix.l);
    766  1.1  christos   if (options.gen.delayed_branch)
    767  1.1  christos     {
    768  1.1  christos       lf_printf (file, "typedef struct _%sinstruction_address {\n",
    769  1.1  christos 		 options.module.global.prefix.l);
    770  1.1  christos       lf_printf (file, "  address_word ip; /* instruction pointer */\n");
    771  1.1  christos       lf_printf (file, "  address_word dp; /* delayed-slot pointer */\n");
    772  1.1  christos       lf_printf (file, "} %sinstruction_address;\n",
    773  1.1  christos 		 options.module.global.prefix.l);
    774  1.1  christos     }
    775  1.1  christos   else
    776  1.1  christos     {
    777  1.1  christos       lf_printf (file, "typedef address_word %sinstruction_address;\n",
    778  1.1  christos 		 options.module.global.prefix.l);
    779  1.1  christos 
    780  1.1  christos     }
    781  1.1  christos   if (options.gen.nia == nia_is_invalid
    782  1.1  christos       && strlen (options.module.global.prefix.u) > 0)
    783  1.1  christos     {
    784  1.1  christos       lf_indent_suppress (file);
    785  1.1  christos       lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ",
    786  1.1  christos 		 options.module.global.prefix.u);
    787  1.1  christos       lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n");
    788  1.1  christos     }
    789  1.1  christos   lf_printf (file, "\n");
    790  1.1  christos   print_icache_struct (file, insns, cache_rules);
    791  1.1  christos   lf_printf (file, "\n");
    792  1.1  christos   if (options.gen.icache)
    793  1.1  christos     {
    794  1.1  christos       ERROR ("FIXME - idecode with icache suffering from bit-rot");
    795  1.1  christos     }
    796  1.1  christos   else
    797  1.1  christos     {
    798  1.1  christos       gen_list *entry;
    799  1.1  christos       for (entry = gen->tables; entry != NULL; entry = entry->next)
    800  1.1  christos 	{
    801  1.1  christos 	  print_idecode_issue_function_header (file,
    802  1.1  christos 					       (options.gen.multi_sim
    803  1.1  christos 						? entry->model->name
    804  1.1  christos 						: NULL),
    805  1.1  christos 					       is_function_declaration,
    806  1.1  christos 					       1 /*ALWAYS ONE WORD */ );
    807  1.1  christos 	}
    808  1.1  christos       if (options.gen.multi_sim)
    809  1.1  christos 	{
    810  1.1  christos 	  print_idecode_issue_function_header (file,
    811  1.1  christos 					       NULL,
    812  1.1  christos 					       is_function_variable,
    813  1.1  christos 					       1 /*ALWAYS ONE WORD */ );
    814  1.1  christos 	}
    815  1.1  christos     }
    816  1.1  christos }
    817  1.1  christos 
    818  1.1  christos 
    819  1.1  christos static void
    820  1.1  christos gen_idecode_c (lf *file,
    821  1.1  christos 	       gen_table *gen, insn_table *isa, cache_entry *cache_rules)
    822  1.1  christos {
    823  1.1  christos   /* the intro */
    824  1.1  christos   print_includes (file);
    825  1.1  christos   print_include_inline (file, options.module.semantics);
    826  1.1  christos   lf_printf (file, "\n");
    827  1.1  christos 
    828  1.1  christos   print_idecode_globals (file);
    829  1.1  christos   lf_printf (file, "\n");
    830  1.1  christos 
    831  1.1  christos   switch (options.gen.code)
    832  1.1  christos     {
    833  1.1  christos     case generate_calls:
    834  1.1  christos       {
    835  1.1  christos 	gen_list *entry;
    836  1.1  christos 	for (entry = gen->tables; entry != NULL; entry = entry->next)
    837  1.1  christos 	  {
    838  1.1  christos 	    print_idecode_lookups (file, entry->table, cache_rules);
    839  1.1  christos 
    840  1.1  christos 	    /* output the main idecode routine */
    841  1.1  christos 	    if (!options.gen.icache)
    842  1.1  christos 	      {
    843  1.1  christos 		print_idecode_issue_function_header (file,
    844  1.1  christos 						     (options.gen.multi_sim
    845  1.1  christos 						      ? entry->model->name
    846  1.1  christos 						      : NULL),
    847  1.1  christos 						     1 /*is definition */ ,
    848  1.1  christos 						     1 /*ALWAYS ONE WORD */ );
    849  1.1  christos 		lf_printf (file, "{\n");
    850  1.1  christos 		lf_indent (file, +2);
    851  1.1  christos 		lf_printf (file, "%sinstruction_address nia;\n",
    852  1.1  christos 			   options.module.global.prefix.l);
    853  1.1  christos 		print_idecode_body (file, entry->table, "nia =");
    854  1.1  christos 		lf_printf (file, "return nia;");
    855  1.1  christos 		lf_indent (file, -2);
    856  1.1  christos 		lf_printf (file, "}\n");
    857  1.1  christos 	      }
    858  1.1  christos 	  }
    859  1.1  christos 	break;
    860  1.1  christos       }
    861  1.1  christos     case generate_jumps:
    862  1.1  christos       {
    863  1.1  christos 	lf_print__this_file_is_empty (file, "generating a jump engine");
    864  1.1  christos 	break;
    865  1.1  christos       }
    866  1.1  christos     }
    867  1.1  christos }
    868  1.1  christos 
    869  1.1  christos 
    870  1.1  christos /****************************************************************/
    871  1.1  christos 
    872  1.1  christos 
    873  1.1  christos static void
    874  1.1  christos gen_run_c (lf *file, gen_table *gen)
    875  1.1  christos {
    876  1.1  christos   gen_list *entry;
    877  1.1  christos   lf_printf (file, "#include \"sim-main.h\"\n");
    878  1.1  christos   lf_printf (file, "#include \"engine.h\"\n");
    879  1.1  christos   lf_printf (file, "#include \"idecode.h\"\n");
    880  1.1  christos   lf_printf (file, "#include \"bfd.h\"\n");
    881  1.1  christos   lf_printf (file, "\n");
    882  1.1  christos 
    883  1.1  christos   if (options.gen.multi_sim)
    884  1.1  christos     {
    885  1.1  christos       print_idecode_issue_function_header (file, NULL, is_function_variable,
    886  1.1  christos 					   1);
    887  1.1  christos       lf_printf (file, "\n");
    888  1.1  christos       print_engine_run_function_header (file, NULL, is_function_variable);
    889  1.1  christos       lf_printf (file, "\n");
    890  1.1  christos     }
    891  1.1  christos 
    892  1.1  christos   lf_printf (file, "void\n");
    893  1.1  christos   lf_printf (file, "sim_engine_run (SIM_DESC sd,\n");
    894  1.1  christos   lf_printf (file, "                int next_cpu_nr,\n");
    895  1.1  christos   lf_printf (file, "                int nr_cpus,\n");
    896  1.1  christos   lf_printf (file, "                int siggnal)\n");
    897  1.1  christos   lf_printf (file, "{\n");
    898  1.1  christos   lf_indent (file, +2);
    899  1.1  christos   if (options.gen.multi_sim)
    900  1.1  christos     {
    901  1.1  christos       lf_printf (file, "int mach;\n");
    902  1.1  christos       lf_printf (file, "if (STATE_ARCHITECTURE (sd) == NULL)\n");
    903  1.1  christos       lf_printf (file, "  mach = 0;\n");
    904  1.1  christos       lf_printf (file, "else\n");
    905  1.1  christos       lf_printf (file, "  mach = STATE_ARCHITECTURE (sd)->mach;\n");
    906  1.1  christos       lf_printf (file, "switch (mach)\n");
    907  1.1  christos       lf_printf (file, "  {\n");
    908  1.1  christos       lf_indent (file, +2);
    909  1.1  christos       for (entry = gen->tables; entry != NULL; entry = entry->next)
    910  1.1  christos 	{
    911  1.1  christos 	  if (options.gen.default_model != NULL
    912  1.1  christos 	      && (strcmp (entry->model->name, options.gen.default_model) == 0
    913  1.1  christos 		  || strcmp (entry->model->full_name,
    914  1.1  christos 			     options.gen.default_model) == 0))
    915  1.1  christos 	    lf_printf (file, "default:\n");
    916  1.1  christos 	  lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name);
    917  1.1  christos 	  lf_indent (file, +2);
    918  1.1  christos 	  print_function_name (file, "issue", NULL,	/* format name */
    919  1.1  christos 			       NULL,	/* NO processor */
    920  1.1  christos 			       NULL,	/* expanded bits */
    921  1.1  christos 			       function_name_prefix_idecode);
    922  1.1  christos 	  lf_printf (file, " = ");
    923  1.1  christos 	  print_function_name (file, "issue", NULL,	/* format name */
    924  1.1  christos 			       entry->model->name, NULL,	/* expanded bits */
    925  1.1  christos 			       function_name_prefix_idecode);
    926  1.1  christos 	  lf_printf (file, ";\n");
    927  1.1  christos 	  print_function_name (file, "run", NULL,	/* format name */
    928  1.1  christos 			       NULL,	/* NO processor */
    929  1.1  christos 			       NULL,	/* expanded bits */
    930  1.1  christos 			       function_name_prefix_engine);
    931  1.1  christos 	  lf_printf (file, " = ");
    932  1.1  christos 	  print_function_name (file, "run", NULL,	/* format name */
    933  1.1  christos 			       entry->model->name, NULL,	/* expanded bits */
    934  1.1  christos 			       function_name_prefix_engine);
    935  1.1  christos 	  lf_printf (file, ";\n");
    936  1.1  christos 	  lf_printf (file, "break;\n");
    937  1.1  christos 	  lf_indent (file, -2);
    938  1.1  christos 	}
    939  1.1  christos       if (options.gen.default_model == NULL)
    940  1.1  christos 	{
    941  1.1  christos 	  lf_printf (file, "default:\n");
    942  1.1  christos 	  lf_indent (file, +2);
    943  1.1  christos 	  lf_printf (file, "sim_engine_abort (sd, NULL, NULL_CIA,\n");
    944  1.1  christos 	  lf_printf (file,
    945  1.1  christos 		     "                  \"sim_engine_run - unknown machine\");\n");
    946  1.1  christos 	  lf_printf (file, "break;\n");
    947  1.1  christos 	  lf_indent (file, -2);
    948  1.1  christos 	}
    949  1.1  christos       lf_indent (file, -2);
    950  1.1  christos       lf_printf (file, "  }\n");
    951  1.1  christos     }
    952  1.1  christos   print_function_name (file, "run", NULL,	/* format name */
    953  1.1  christos 		       NULL,	/* NO processor */
    954  1.1  christos 		       NULL,	/* expanded bits */
    955  1.1  christos 		       function_name_prefix_engine);
    956  1.1  christos   lf_printf (file, " (sd, next_cpu_nr, nr_cpus, siggnal);\n");
    957  1.1  christos   lf_indent (file, -2);
    958  1.1  christos   lf_printf (file, "}\n");
    959  1.1  christos }
    960  1.1  christos 
    961  1.1  christos /****************************************************************/
    962  1.1  christos 
    963  1.1  christos static gen_table *
    964  1.1  christos do_gen (insn_table *isa, decode_table *decode_rules)
    965  1.1  christos {
    966  1.1  christos   gen_table *gen;
    967  1.1  christos   if (decode_rules == NULL)
    968  1.1  christos     error (NULL, "Must specify a decode table\n");
    969  1.1  christos   if (isa == NULL)
    970  1.1  christos     error (NULL, "Must specify an instruction table\n");
    971  1.1  christos   if (decode_table_max_word_nr (decode_rules) > 0)
    972  1.1  christos     options.gen.multi_word = decode_table_max_word_nr (decode_rules);
    973  1.1  christos   gen = make_gen_tables (isa, decode_rules);
    974  1.1  christos   gen_tables_expand_insns (gen);
    975  1.1  christos   gen_tables_expand_semantics (gen);
    976  1.1  christos   return gen;
    977  1.1  christos }
    978  1.1  christos 
    979  1.1  christos /****************************************************************/
    980  1.1  christos 
    981  1.1  christos igen_options options;
    982  1.1  christos 
    983  1.1  christos int
    984  1.1  christos main (int argc, char **argv, char **envp)
    985  1.1  christos {
    986  1.1  christos   cache_entry *cache_rules = NULL;
    987  1.1  christos   lf_file_references file_references = lf_include_references;
    988  1.1  christos   decode_table *decode_rules = NULL;
    989  1.1  christos   insn_table *isa = NULL;
    990  1.1  christos   gen_table *gen = NULL;
    991  1.1  christos   char *real_file_name = NULL;
    992  1.1  christos   int is_header = 0;
    993  1.1  christos   int ch;
    994  1.1  christos   lf *standard_out =
    995  1.1  christos     lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen");
    996  1.1  christos 
    997  1.1  christos   INIT_OPTIONS ();
    998  1.1  christos 
    999  1.1  christos   if (argc == 1)
   1000  1.1  christos     {
   1001  1.1  christos       printf ("Usage:\n");
   1002  1.1  christos       printf ("\n");
   1003  1.1  christos       printf ("  igen <config-opts> ... <input-opts>... <output-opts>...\n");
   1004  1.1  christos       printf ("\n");
   1005  1.1  christos       printf ("Config options:\n");
   1006  1.1  christos       printf ("\n");
   1007  1.1  christos       printf ("  -B <bit-size>\n");
   1008  1.1  christos       printf ("\t Set the number of bits in an instruction (deprecated).\n");
   1009  1.1  christos       printf
   1010  1.1  christos 	("\t This option can now be set directly in the instruction table.\n");
   1011  1.1  christos       printf ("\n");
   1012  1.1  christos       printf ("  -D <data-structure>\n");
   1013  1.1  christos       printf
   1014  1.1  christos 	("\t Dump the specified data structure to stdout. Valid structures include:\n");
   1015  1.1  christos       printf
   1016  1.1  christos 	("\t processor-names - list the names of all the processors (models)\n");
   1017  1.1  christos       printf ("\n");
   1018  1.1  christos       printf ("  -F <filter-list>\n");
   1019  1.1  christos       printf
   1020  1.1  christos 	("\t Filter out any instructions with a non-empty flags field that contains\n");
   1021  1.1  christos       printf ("\t a flag not listed in the <filter-list>.\n");
   1022  1.1  christos       printf ("\n");
   1023  1.1  christos       printf ("  -H <high-bit>\n");
   1024  1.1  christos       printf
   1025  1.1  christos 	("\t Set the number of the high (most significant) instruction bit (deprecated).\n");
   1026  1.1  christos       printf
   1027  1.1  christos 	("\t This option can now be set directly in the instruction table.\n");
   1028  1.1  christos       printf ("\n");
   1029  1.1  christos       printf ("  -I <directory>\n");
   1030  1.1  christos       printf
   1031  1.1  christos 	("\t Add <directory> to the list of directories searched when opening a file\n");
   1032  1.1  christos       printf ("\n");
   1033  1.1  christos       printf ("  -M <model-list>\n");
   1034  1.1  christos       printf
   1035  1.1  christos 	("\t Filter out any instructions that do not support at least one of the listed\n");
   1036  1.1  christos       printf
   1037  1.1  christos 	("\t models (An instructions with no model information is considered to support\n");
   1038  1.1  christos       printf ("\t all models.).\n");
   1039  1.1  christos       printf ("\n");
   1040  1.1  christos       printf ("  -N <nr-cpus>\n");
   1041  1.1  christos       printf ("\t Generate a simulator supporting <nr-cpus>\n");
   1042  1.1  christos       printf
   1043  1.1  christos 	("\t Specify `-N 0' to disable generation of the SMP. Specifying `-N 1' will\n");
   1044  1.1  christos       printf
   1045  1.1  christos 	("\t still generate an SMP enabled simulator but will only support one CPU.\n");
   1046  1.1  christos       printf ("\n");
   1047  1.1  christos       printf ("  -T <mechanism>\n");
   1048  1.1  christos       printf
   1049  1.1  christos 	("\t Override the decode mechanism specified by the decode rules\n");
   1050  1.1  christos       printf ("\n");
   1051  1.1  christos       printf ("  -P <prefix>\n");
   1052  1.1  christos       printf
   1053  1.1  christos 	("\t Prepend global names (except itable) with the string <prefix>.\n");
   1054  1.1  christos       printf
   1055  1.1  christos 	("\t Specify -P <module>=<prefix> to set a specific <module>'s prefix.\n");
   1056  1.1  christos       printf ("\n");
   1057  1.1  christos       printf ("  -S <suffix>\n");
   1058  1.1  christos       printf
   1059  1.1  christos 	("\t Replace a global name (suffix) (except itable) with the string <suffix>.\n");
   1060  1.1  christos       printf
   1061  1.1  christos 	("\t Specify -S <module>=<suffix> to change a specific <module>'s name (suffix).\n");
   1062  1.1  christos       printf ("\n");
   1063  1.1  christos       printf ("  -Werror\n");
   1064  1.1  christos       printf ("\t Make warnings errors\n");
   1065  1.1  christos       printf ("  -Wnodiscard\n");
   1066  1.1  christos       printf
   1067  1.1  christos 	("\t Suppress warnings about discarded functions and instructions\n");
   1068  1.1  christos       printf ("  -Wnowidth\n");
   1069  1.1  christos       printf
   1070  1.1  christos 	("\t Suppress warnings about instructions with invalid widths\n");
   1071  1.1  christos       printf ("  -Wnounimplemented\n");
   1072  1.1  christos       printf ("\t Suppress warnings about unimplemented instructions\n");
   1073  1.1  christos       printf ("\n");
   1074  1.1  christos       printf ("  -G [!]<gen-option>\n");
   1075  1.1  christos       printf ("\t Any of the following options:\n");
   1076  1.1  christos       printf ("\n");
   1077  1.1  christos       printf
   1078  1.1  christos 	("\t decode-duplicate       - Override the decode rules, forcing the duplication of\n");
   1079  1.1  christos       printf ("\t                          semantic functions\n");
   1080  1.1  christos       printf
   1081  1.1  christos 	("\t decode-combine         - Combine any duplicated entries within a table\n");
   1082  1.1  christos       printf
   1083  1.1  christos 	("\t decode-zero-reserved   - Override the decode rules, forcing reserved bits to be\n");
   1084  1.1  christos       printf ("\t                          treated as zero.\n");
   1085  1.1  christos       printf
   1086  1.1  christos 	("\t decode-switch-is-goto  - Overfide the padded-switch code type as a goto-switch\n");
   1087  1.1  christos       printf ("\n");
   1088  1.1  christos       printf
   1089  1.1  christos 	("\t gen-conditional-issue  - conditionally issue each instruction\n");
   1090  1.1  christos       printf
   1091  1.1  christos 	("\t gen-delayed-branch     - need both cia and nia passed around\n");
   1092  1.1  christos       printf
   1093  1.1  christos 	("\t gen-direct-access      - use #defines to directly access values\n");
   1094  1.1  christos       printf
   1095  1.1  christos 	("\t gen-zero-r<N>          - arch assumes GPR(<N>) == 0, keep it that way\n");
   1096  1.1  christos       printf
   1097  1.1  christos 	("\t gen-icache[=<N>        - generate an instruction cracking cache of size <N>\n");
   1098  1.1  christos       printf ("\t                          Default size is %d\n",
   1099  1.1  christos 	      options.gen.icache_size);
   1100  1.1  christos       printf
   1101  1.1  christos 	("\t gen-insn-in-icache     - save original instruction when cracking\n");
   1102  1.1  christos       printf
   1103  1.1  christos 	("\t gen-multi-sim[=MODEL]  - generate multiple simulators - one per model\n");
   1104  1.1  christos       printf
   1105  1.1  christos 	("\t                          If specified MODEL is made the default architecture.\n");
   1106  1.1  christos       printf
   1107  1.1  christos 	("\t                          By default, a single simulator that will\n");
   1108  1.1  christos       printf
   1109  1.1  christos 	("\t                          execute any instruction is generated\n");
   1110  1.1  christos       printf
   1111  1.1  christos 	("\t gen-multi-word         - generate code allowing for multi-word insns\n");
   1112  1.1  christos       printf
   1113  1.1  christos 	("\t gen-semantic-icache    - include semantic code in cracking functions\n");
   1114  1.1  christos       printf
   1115  1.1  christos 	("\t gen-slot-verification  - perform slot verification as part of decode\n");
   1116  1.1  christos       printf ("\t gen-nia-invalid        - NIA defaults to nia_invalid\n");
   1117  1.1  christos       printf ("\t gen-nia-void           - do not compute/return NIA\n");
   1118  1.1  christos       printf ("\n");
   1119  1.1  christos       printf
   1120  1.1  christos 	("\t trace-combine          - report combined entries a rule application\n");
   1121  1.1  christos       printf
   1122  1.1  christos 	("\t trace-entries          - report entries after a rules application\n");
   1123  1.1  christos       printf ("\t trace-rule-rejection   - report each rule as rejected\n");
   1124  1.1  christos       printf ("\t trace-rule-selection   - report each rule as selected\n");
   1125  1.1  christos       printf
   1126  1.1  christos 	("\t trace-insn-insertion   - report each instruction as it is inserted into a decode table\n");
   1127  1.1  christos       printf
   1128  1.1  christos 	("\t trace-rule-expansion   - report each instruction as it is expanded (before insertion into a decode table)\n");
   1129  1.1  christos       printf ("\t trace-all              - enable all trace options\n");
   1130  1.1  christos       printf ("\n");
   1131  1.1  christos       printf
   1132  1.1  christos 	("\t field-widths           - instruction formats specify widths (deprecated)\n");
   1133  1.1  christos       printf
   1134  1.1  christos 	("\t                          By default, an instruction format specifies bit\n");
   1135  1.1  christos       printf ("\t                          positions\n");
   1136  1.1  christos       printf
   1137  1.1  christos 	("\t                          This option can now be set directly in the\n");
   1138  1.1  christos       printf ("\t                          instruction table\n");
   1139  1.1  christos       printf
   1140  1.1  christos 	("\t jumps                  - use jumps instead of function calls\n");
   1141  1.1  christos       printf
   1142  1.1  christos 	("\t omit-line-numbers      - do not include line number information in the output\n");
   1143  1.1  christos       printf ("\n");
   1144  1.1  christos       printf ("Input options:\n");
   1145  1.1  christos       printf ("\n");
   1146  1.1  christos       printf ("  -k <cache-rules> (deprecated)\n");
   1147  1.1  christos       printf ("  -o <decode-rules>\n");
   1148  1.1  christos       printf ("  -i <instruction-table>\n");
   1149  1.1  christos       printf ("\n");
   1150  1.1  christos       printf ("Output options:\n");
   1151  1.1  christos       printf ("\n");
   1152  1.1  christos       printf ("  -x                    Perform expansion (required)\n");
   1153  1.1  christos       printf
   1154  1.1  christos 	("  -n <real-name>        Specify the real name of the next output file\n");
   1155  1.1  christos       printf
   1156  1.1  christos 	("  -h 		       Generate the header (.h) file rather than the body (.c)\n");
   1157  1.1  christos       printf ("  -c <output-file>      output icache\n");
   1158  1.1  christos       printf ("  -d <output-file>      output idecode\n");
   1159  1.1  christos       printf ("  -e <output-file>      output engine\n");
   1160  1.1  christos       printf ("  -f <output-file>      output support functions\n");
   1161  1.1  christos       printf ("  -m <output-file>      output model\n");
   1162  1.1  christos       printf ("  -r <output-file>      output multi-sim run\n");
   1163  1.1  christos       printf ("  -s <output-file>      output schematic\n");
   1164  1.1  christos       printf ("  -t <output-file>      output itable\n");
   1165  1.1  christos     }
   1166  1.1  christos 
   1167  1.1  christos   while ((ch = getopt (argc, argv,
   1168  1.1  christos 		       "B:D:F:G:H:I:M:N:P:T:W:o:k:i:n:hc:d:e:m:r:s:t:f:x"))
   1169  1.1  christos 	 != -1)
   1170  1.1  christos     {
   1171  1.1  christos       fprintf (stderr, "  -%c ", ch);
   1172  1.1  christos       if (optarg)
   1173  1.1  christos 	fprintf (stderr, "%s ", optarg);
   1174  1.1  christos       fprintf (stderr, "\\\n");
   1175  1.1  christos 
   1176  1.1  christos       switch (ch)
   1177  1.1  christos 	{
   1178  1.1  christos 
   1179  1.1  christos 	case 'M':
   1180  1.1  christos 	  filter_parse (&options.model_filter, optarg);
   1181  1.1  christos 	  break;
   1182  1.1  christos 
   1183  1.1  christos 	case 'D':
   1184  1.1  christos 	  if (strcmp (optarg, "processor-names"))
   1185  1.1  christos 	    {
   1186  1.1  christos 	      char *processor;
   1187  1.1  christos 	      for (processor = filter_next (options.model_filter, "");
   1188  1.1  christos 		   processor != NULL;
   1189  1.1  christos 		   processor = filter_next (options.model_filter, processor))
   1190  1.1  christos 		lf_printf (standard_out, "%s\n", processor);
   1191  1.1  christos 	    }
   1192  1.1  christos 	  else
   1193  1.1  christos 	    error (NULL, "Unknown data structure %s, not dumped\n", optarg);
   1194  1.1  christos 	  break;
   1195  1.1  christos 
   1196  1.1  christos 	case 'F':
   1197  1.1  christos 	  filter_parse (&options.flags_filter, optarg);
   1198  1.1  christos 	  break;
   1199  1.1  christos 
   1200  1.1  christos 	case 'I':
   1201  1.1  christos 	  {
   1202  1.1  christos 	    table_include **dir = &options.include;
   1203  1.1  christos 	    while ((*dir) != NULL)
   1204  1.1  christos 	      dir = &(*dir)->next;
   1205  1.1  christos 	    (*dir) = ZALLOC (table_include);
   1206  1.1  christos 	    (*dir)->dir = strdup (optarg);
   1207  1.1  christos 	  }
   1208  1.1  christos 	  break;
   1209  1.1  christos 
   1210  1.1  christos 	case 'B':
   1211  1.1  christos 	  options.insn_bit_size = a2i (optarg);
   1212  1.1  christos 	  if (options.insn_bit_size <= 0
   1213  1.1  christos 	      || options.insn_bit_size > max_insn_bit_size)
   1214  1.1  christos 	    {
   1215  1.1  christos 	      error (NULL, "Instruction bitsize must be in range 1..%d\n",
   1216  1.1  christos 		     max_insn_bit_size);
   1217  1.1  christos 	    }
   1218  1.1  christos 	  if (options.hi_bit_nr != options.insn_bit_size - 1
   1219  1.1  christos 	      && options.hi_bit_nr != 0)
   1220  1.1  christos 	    {
   1221  1.1  christos 	      error (NULL, "Conflict betweem hi-bit-nr and insn-bit-size\n");
   1222  1.1  christos 	    }
   1223  1.1  christos 	  break;
   1224  1.1  christos 
   1225  1.1  christos 	case 'H':
   1226  1.1  christos 	  options.hi_bit_nr = a2i (optarg);
   1227  1.1  christos 	  if (options.hi_bit_nr != options.insn_bit_size - 1
   1228  1.1  christos 	      && options.hi_bit_nr != 0)
   1229  1.1  christos 	    {
   1230  1.1  christos 	      error (NULL, "Conflict between hi-bit-nr and insn-bit-size\n");
   1231  1.1  christos 	    }
   1232  1.1  christos 	  break;
   1233  1.1  christos 
   1234  1.1  christos 	case 'N':
   1235  1.1  christos 	  options.gen.smp = a2i (optarg);
   1236  1.1  christos 	  break;
   1237  1.1  christos 
   1238  1.1  christos 	case 'P':
   1239  1.1  christos 	case 'S':
   1240  1.1  christos 	  {
   1241  1.1  christos 	    igen_module *names;
   1242  1.1  christos 	    igen_name *name;
   1243  1.1  christos 	    char *chp;
   1244  1.1  christos 	    chp = strchr (optarg, '=');
   1245  1.1  christos 	    if (chp == NULL)
   1246  1.1  christos 	      {
   1247  1.1  christos 		names = &options.module.global;
   1248  1.1  christos 		chp = optarg;
   1249  1.1  christos 	      }
   1250  1.1  christos 	    else
   1251  1.1  christos 	      {
   1252  1.1  christos 		chp = chp + 1;	/* skip `=' */
   1253  1.1  christos 		names = NULL;
   1254  1.1  christos 		if (strncmp (optarg, "global=", chp - optarg) == 0)
   1255  1.1  christos 		  {
   1256  1.1  christos 		    names = &options.module.global;
   1257  1.1  christos 		  }
   1258  1.1  christos 		if (strncmp (optarg, "engine=", chp - optarg) == 0)
   1259  1.1  christos 		  {
   1260  1.1  christos 		    names = &options.module.engine;
   1261  1.1  christos 		  }
   1262  1.1  christos 		if (strncmp (optarg, "icache=", chp - optarg) == 0)
   1263  1.1  christos 		  {
   1264  1.1  christos 		    names = &options.module.icache;
   1265  1.1  christos 		  }
   1266  1.1  christos 		if (strncmp (optarg, "idecode=", chp - optarg) == 0)
   1267  1.1  christos 		  {
   1268  1.1  christos 		    names = &options.module.idecode;
   1269  1.1  christos 		  }
   1270  1.1  christos 		if (strncmp (optarg, "itable=", chp - optarg) == 0)
   1271  1.1  christos 		  {
   1272  1.1  christos 		    names = &options.module.itable;
   1273  1.1  christos 		  }
   1274  1.1  christos 		if (strncmp (optarg, "semantics=", chp - optarg) == 0)
   1275  1.1  christos 		  {
   1276  1.1  christos 		    names = &options.module.semantics;
   1277  1.1  christos 		  }
   1278  1.1  christos 		if (strncmp (optarg, "support=", chp - optarg) == 0)
   1279  1.1  christos 		  {
   1280  1.1  christos 		    names = &options.module.support;
   1281  1.1  christos 		  }
   1282  1.1  christos 		if (names == NULL)
   1283  1.1  christos 		  {
   1284  1.1  christos 		    error (NULL, "Prefix `%s' unreconized\n", optarg);
   1285  1.1  christos 		  }
   1286  1.1  christos 	      }
   1287  1.1  christos 	    switch (ch)
   1288  1.1  christos 	      {
   1289  1.1  christos 	      case 'P':
   1290  1.1  christos 		name = &names->prefix;
   1291  1.1  christos 		break;
   1292  1.1  christos 	      case 'S':
   1293  1.1  christos 		name = &names->suffix;
   1294  1.1  christos 		break;
   1295  1.1  christos 	      default:
   1296  1.1  christos 		abort ();	/* Bad switch.  */
   1297  1.1  christos 	      }
   1298  1.1  christos 	    name->u = strdup (chp);
   1299  1.1  christos 	    name->l = strdup (chp);
   1300  1.1  christos 	    chp = name->u;
   1301  1.1  christos 	    while (*chp)
   1302  1.1  christos 	      {
   1303  1.1  christos 		if (islower (*chp))
   1304  1.1  christos 		  *chp = toupper (*chp);
   1305  1.1  christos 		chp++;
   1306  1.1  christos 	      }
   1307  1.1  christos 	    if (name == &options.module.global.prefix)
   1308  1.1  christos 	      {
   1309  1.1  christos 		options.module.engine.prefix = options.module.global.prefix;
   1310  1.1  christos 		options.module.icache.prefix = options.module.global.prefix;
   1311  1.1  christos 		options.module.idecode.prefix = options.module.global.prefix;
   1312  1.1  christos 		/* options.module.itable.prefix = options.module.global.prefix; */
   1313  1.1  christos 		options.module.semantics.prefix =
   1314  1.1  christos 		  options.module.global.prefix;
   1315  1.1  christos 		options.module.support.prefix = options.module.global.prefix;
   1316  1.1  christos 	      }
   1317  1.1  christos 	    if (name == &options.module.global.suffix)
   1318  1.1  christos 	      {
   1319  1.1  christos 		options.module.engine.suffix = options.module.global.suffix;
   1320  1.1  christos 		options.module.icache.suffix = options.module.global.suffix;
   1321  1.1  christos 		options.module.idecode.suffix = options.module.global.suffix;
   1322  1.1  christos 		/* options.module.itable.suffix = options.module.global.suffix; */
   1323  1.1  christos 		options.module.semantics.suffix =
   1324  1.1  christos 		  options.module.global.suffix;
   1325  1.1  christos 		options.module.support.suffix = options.module.global.suffix;
   1326  1.1  christos 	      }
   1327  1.1  christos 	    break;
   1328  1.1  christos 	  }
   1329  1.1  christos 
   1330  1.1  christos 	case 'W':
   1331  1.1  christos 	  {
   1332  1.1  christos 	    if (strcmp (optarg, "error") == 0)
   1333  1.1  christos 	      options.warning = error;
   1334  1.1  christos 	    else if (strcmp (optarg, "nodiscard") == 0)
   1335  1.1  christos 	      options.warn.discard = 0;
   1336  1.1  christos 	    else if (strcmp (optarg, "discard") == 0)
   1337  1.1  christos 	      options.warn.discard = 1;
   1338  1.1  christos 	    else if (strcmp (optarg, "nowidth") == 0)
   1339  1.1  christos 	      options.warn.width = 0;
   1340  1.1  christos 	    else if (strcmp (optarg, "width") == 0)
   1341  1.1  christos 	      options.warn.width = 1;
   1342  1.1  christos 	    else if (strcmp (optarg, "nounimplemented") == 0)
   1343  1.1  christos 	      options.warn.unimplemented = 0;
   1344  1.1  christos 	    else if (strcmp (optarg, "unimplemented") == 0)
   1345  1.1  christos 	      options.warn.unimplemented = 1;
   1346  1.1  christos 	    else
   1347  1.1  christos 	      error (NULL, "Unknown -W argument `%s'\n", optarg);
   1348  1.1  christos 	    break;
   1349  1.1  christos 	  }
   1350  1.1  christos 
   1351  1.1  christos 
   1352  1.1  christos 	case 'G':
   1353  1.1  christos 	  {
   1354  1.1  christos 	    int enable_p;
   1355  1.1  christos 	    char *argp;
   1356  1.1  christos 	    if (strncmp (optarg, "no-", strlen ("no-")) == 0)
   1357  1.1  christos 	      {
   1358  1.1  christos 		argp = optarg + strlen ("no-");
   1359  1.1  christos 		enable_p = 0;
   1360  1.1  christos 	      }
   1361  1.1  christos 	    else if (strncmp (optarg, "!", strlen ("!")) == 0)
   1362  1.1  christos 	      {
   1363  1.1  christos 		argp = optarg + strlen ("no-");
   1364  1.1  christos 		enable_p = 0;
   1365  1.1  christos 	      }
   1366  1.1  christos 	    else
   1367  1.1  christos 	      {
   1368  1.1  christos 		argp = optarg;
   1369  1.1  christos 		enable_p = 1;
   1370  1.1  christos 	      }
   1371  1.1  christos 	    if (strcmp (argp, "decode-duplicate") == 0)
   1372  1.1  christos 	      {
   1373  1.1  christos 		options.decode.duplicate = enable_p;
   1374  1.1  christos 	      }
   1375  1.1  christos 	    else if (strcmp (argp, "decode-combine") == 0)
   1376  1.1  christos 	      {
   1377  1.1  christos 		options.decode.combine = enable_p;
   1378  1.1  christos 	      }
   1379  1.1  christos 	    else if (strcmp (argp, "decode-zero-reserved") == 0)
   1380  1.1  christos 	      {
   1381  1.1  christos 		options.decode.zero_reserved = enable_p;
   1382  1.1  christos 	      }
   1383  1.1  christos 
   1384  1.1  christos 	    else if (strcmp (argp, "gen-conditional-issue") == 0)
   1385  1.1  christos 	      {
   1386  1.1  christos 		options.gen.conditional_issue = enable_p;
   1387  1.1  christos 	      }
   1388  1.1  christos 	    else if (strcmp (argp, "conditional-issue") == 0)
   1389  1.1  christos 	      {
   1390  1.1  christos 		options.gen.conditional_issue = enable_p;
   1391  1.1  christos 		options.warning (NULL,
   1392  1.1  christos 				 "Option conditional-issue replaced by gen-conditional-issue\n");
   1393  1.1  christos 	      }
   1394  1.1  christos 	    else if (strcmp (argp, "gen-delayed-branch") == 0)
   1395  1.1  christos 	      {
   1396  1.1  christos 		options.gen.delayed_branch = enable_p;
   1397  1.1  christos 	      }
   1398  1.1  christos 	    else if (strcmp (argp, "delayed-branch") == 0)
   1399  1.1  christos 	      {
   1400  1.1  christos 		options.gen.delayed_branch = enable_p;
   1401  1.1  christos 		options.warning (NULL,
   1402  1.1  christos 				 "Option delayed-branch replaced by gen-delayed-branch\n");
   1403  1.1  christos 	      }
   1404  1.1  christos 	    else if (strcmp (argp, "gen-direct-access") == 0)
   1405  1.1  christos 	      {
   1406  1.1  christos 		options.gen.direct_access = enable_p;
   1407  1.1  christos 	      }
   1408  1.1  christos 	    else if (strcmp (argp, "direct-access") == 0)
   1409  1.1  christos 	      {
   1410  1.1  christos 		options.gen.direct_access = enable_p;
   1411  1.1  christos 		options.warning (NULL,
   1412  1.1  christos 				 "Option direct-access replaced by gen-direct-access\n");
   1413  1.1  christos 	      }
   1414  1.1  christos 	    else if (strncmp (argp, "gen-zero-r", strlen ("gen-zero-r")) == 0)
   1415  1.1  christos 	      {
   1416  1.1  christos 		options.gen.zero_reg = enable_p;
   1417  1.1  christos 		options.gen.zero_reg_nr = atoi (argp + strlen ("gen-zero-r"));
   1418  1.1  christos 	      }
   1419  1.1  christos 	    else if (strncmp (argp, "zero-r", strlen ("zero-r")) == 0)
   1420  1.1  christos 	      {
   1421  1.1  christos 		options.gen.zero_reg = enable_p;
   1422  1.1  christos 		options.gen.zero_reg_nr = atoi (argp + strlen ("zero-r"));
   1423  1.1  christos 		options.warning (NULL,
   1424  1.1  christos 				 "Option zero-r<N> replaced by gen-zero-r<N>\n");
   1425  1.1  christos 	      }
   1426  1.1  christos 	    else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0)
   1427  1.1  christos 	      {
   1428  1.1  christos 		switch (argp[strlen ("gen-icache")])
   1429  1.1  christos 		  {
   1430  1.1  christos 		  case '=':
   1431  1.1  christos 		    options.gen.icache_size =
   1432  1.1  christos 		      atoi (argp + strlen ("gen-icache") + 1);
   1433  1.1  christos 		    options.gen.icache = enable_p;
   1434  1.1  christos 		    break;
   1435  1.1  christos 		  case '\0':
   1436  1.1  christos 		    options.gen.icache = enable_p;
   1437  1.1  christos 		    break;
   1438  1.1  christos 		  default:
   1439  1.1  christos 		    error (NULL,
   1440  1.1  christos 			   "Expecting -Ggen-icache or -Ggen-icache=<N>\n");
   1441  1.1  christos 		  }
   1442  1.1  christos 	      }
   1443  1.1  christos 	    else if (strcmp (argp, "gen-insn-in-icache") == 0)
   1444  1.1  christos 	      {
   1445  1.1  christos 		options.gen.insn_in_icache = enable_p;
   1446  1.1  christos 	      }
   1447  1.1  christos 	    else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim"))
   1448  1.1  christos 		     == 0)
   1449  1.1  christos 	      {
   1450  1.1  christos 		char *arg = &argp[strlen ("gen-multi-sim")];
   1451  1.1  christos 		switch (arg[0])
   1452  1.1  christos 		  {
   1453  1.1  christos 		  case '=':
   1454  1.1  christos 		    options.gen.multi_sim = enable_p;
   1455  1.1  christos 		    options.gen.default_model = arg + 1;
   1456  1.1  christos 		    if (!filter_is_member
   1457  1.1  christos 			(options.model_filter, options.gen.default_model))
   1458  1.1  christos 		      error (NULL, "multi-sim model %s unknown\n",
   1459  1.1  christos 			     options.gen.default_model);
   1460  1.1  christos 		    break;
   1461  1.1  christos 		  case '\0':
   1462  1.1  christos 		    options.gen.multi_sim = enable_p;
   1463  1.1  christos 		    options.gen.default_model = NULL;
   1464  1.1  christos 		    break;
   1465  1.1  christos 		  default:
   1466  1.1  christos 		    error (NULL,
   1467  1.1  christos 			   "Expecting -Ggen-multi-sim or -Ggen-multi-sim=<MODEL>\n");
   1468  1.1  christos 		    break;
   1469  1.1  christos 		  }
   1470  1.1  christos 	      }
   1471  1.1  christos 	    else if (strcmp (argp, "gen-multi-word") == 0)
   1472  1.1  christos 	      {
   1473  1.1  christos 		options.gen.multi_word = enable_p;
   1474  1.1  christos 	      }
   1475  1.1  christos 	    else if (strcmp (argp, "gen-semantic-icache") == 0)
   1476  1.1  christos 	      {
   1477  1.1  christos 		options.gen.semantic_icache = enable_p;
   1478  1.1  christos 	      }
   1479  1.1  christos 	    else if (strcmp (argp, "gen-slot-verification") == 0)
   1480  1.1  christos 	      {
   1481  1.1  christos 		options.gen.slot_verification = enable_p;
   1482  1.1  christos 	      }
   1483  1.1  christos 	    else if (strcmp (argp, "verify-slot") == 0)
   1484  1.1  christos 	      {
   1485  1.1  christos 		options.gen.slot_verification = enable_p;
   1486  1.1  christos 		options.warning (NULL,
   1487  1.1  christos 				 "Option verify-slot replaced by gen-slot-verification\n");
   1488  1.1  christos 	      }
   1489  1.1  christos 	    else if (strcmp (argp, "gen-nia-invalid") == 0)
   1490  1.1  christos 	      {
   1491  1.1  christos 		options.gen.nia = nia_is_invalid;
   1492  1.1  christos 	      }
   1493  1.1  christos 	    else if (strcmp (argp, "default-nia-minus-one") == 0)
   1494  1.1  christos 	      {
   1495  1.1  christos 		options.gen.nia = nia_is_invalid;
   1496  1.1  christos 		options.warning (NULL,
   1497  1.1  christos 				 "Option default-nia-minus-one replaced by gen-nia-invalid\n");
   1498  1.1  christos 	      }
   1499  1.1  christos 	    else if (strcmp (argp, "gen-nia-void") == 0)
   1500  1.1  christos 	      {
   1501  1.1  christos 		options.gen.nia = nia_is_void;
   1502  1.1  christos 	      }
   1503  1.1  christos 	    else if (strcmp (argp, "trace-all") == 0)
   1504  1.1  christos 	      {
   1505  1.1  christos 		memset (&options.trace, enable_p, sizeof (options.trace));
   1506  1.1  christos 	      }
   1507  1.1  christos 	    else if (strcmp (argp, "trace-combine") == 0)
   1508  1.1  christos 	      {
   1509  1.1  christos 		options.trace.combine = enable_p;
   1510  1.1  christos 	      }
   1511  1.1  christos 	    else if (strcmp (argp, "trace-entries") == 0)
   1512  1.1  christos 	      {
   1513  1.1  christos 		options.trace.entries = enable_p;
   1514  1.1  christos 	      }
   1515  1.1  christos 	    else if (strcmp (argp, "trace-rule-rejection") == 0)
   1516  1.1  christos 	      {
   1517  1.1  christos 		options.trace.rule_rejection = enable_p;
   1518  1.1  christos 	      }
   1519  1.1  christos 	    else if (strcmp (argp, "trace-rule-selection") == 0)
   1520  1.1  christos 	      {
   1521  1.1  christos 		options.trace.rule_selection = enable_p;
   1522  1.1  christos 	      }
   1523  1.1  christos 	    else if (strcmp (argp, "trace-insn-insertion") == 0)
   1524  1.1  christos 	      {
   1525  1.1  christos 		options.trace.insn_insertion = enable_p;
   1526  1.1  christos 	      }
   1527  1.1  christos 	    else if (strcmp (argp, "trace-insn-expansion") == 0)
   1528  1.1  christos 	      {
   1529  1.1  christos 		options.trace.insn_expansion = enable_p;
   1530  1.1  christos 	      }
   1531  1.1  christos 	    else if (strcmp (argp, "jumps") == 0)
   1532  1.1  christos 	      {
   1533  1.1  christos 		options.gen.code = generate_jumps;
   1534  1.1  christos 	      }
   1535  1.1  christos 	    else if (strcmp (argp, "field-widths") == 0)
   1536  1.1  christos 	      {
   1537  1.1  christos 		options.insn_specifying_widths = enable_p;
   1538  1.1  christos 	      }
   1539  1.1  christos 	    else if (strcmp (argp, "omit-line-numbers") == 0)
   1540  1.1  christos 	      {
   1541  1.1  christos 		file_references = lf_omit_references;
   1542  1.1  christos 	      }
   1543  1.1  christos 	    else
   1544  1.1  christos 	      {
   1545  1.1  christos 		error (NULL, "Unknown option %s\n", optarg);
   1546  1.1  christos 	      }
   1547  1.1  christos 	    break;
   1548  1.1  christos 	  }
   1549  1.1  christos 
   1550  1.1  christos 	case 'i':
   1551  1.1  christos 	  isa = load_insn_table (optarg, cache_rules);
   1552  1.1  christos 	  if (isa->illegal_insn == NULL)
   1553  1.1  christos 	    error (NULL, "illegal-instruction missing from insn table\n");
   1554  1.1  christos 	  break;
   1555  1.1  christos 
   1556  1.1  christos 	case 'x':
   1557  1.1  christos 	  gen = do_gen (isa, decode_rules);
   1558  1.1  christos 	  break;
   1559  1.1  christos 
   1560  1.1  christos 	case 'o':
   1561  1.1  christos 	  decode_rules = load_decode_table (optarg);
   1562  1.1  christos 	  break;
   1563  1.1  christos 
   1564  1.1  christos 	case 'k':
   1565  1.1  christos 	  if (isa != NULL)
   1566  1.1  christos 	    error (NULL, "Cache file must appear before the insn file\n");
   1567  1.1  christos 	  cache_rules = load_cache_table (optarg);
   1568  1.1  christos 	  break;
   1569  1.1  christos 
   1570  1.1  christos 	case 'n':
   1571  1.1  christos 	  real_file_name = strdup (optarg);
   1572  1.1  christos 	  break;
   1573  1.1  christos 
   1574  1.1  christos 	case 'h':
   1575  1.1  christos 	  is_header = 1;
   1576  1.1  christos 	  break;
   1577  1.1  christos 
   1578  1.1  christos 	case 'c':
   1579  1.1  christos 	case 'd':
   1580  1.1  christos 	case 'e':
   1581  1.1  christos 	case 'f':
   1582  1.1  christos 	case 'm':
   1583  1.1  christos 	case 'r':
   1584  1.1  christos 	case 's':
   1585  1.1  christos 	case 't':
   1586  1.1  christos 	  {
   1587  1.1  christos 	    lf *file = lf_open (optarg, real_file_name, file_references,
   1588  1.1  christos 				(is_header ? lf_is_h : lf_is_c),
   1589  1.1  christos 				argv[0]);
   1590  1.1  christos 	    if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f')
   1591  1.1  christos 	      {
   1592  1.1  christos 		options.warning (NULL,
   1593  1.1  christos 				 "Explicitly generate tables with -x option\n");
   1594  1.1  christos 		gen = do_gen (isa, decode_rules);
   1595  1.1  christos 	      }
   1596  1.1  christos 	    lf_print__file_start (file);
   1597  1.1  christos 	    switch (ch)
   1598  1.1  christos 	      {
   1599  1.1  christos 	      case 'm':
   1600  1.1  christos 		if (is_header)
   1601  1.1  christos 		  gen_model_h (file, isa);
   1602  1.1  christos 		else
   1603  1.1  christos 		  gen_model_c (file, isa);
   1604  1.1  christos 		break;
   1605  1.1  christos 	      case 't':
   1606  1.1  christos 		if (is_header)
   1607  1.1  christos 		  gen_itable_h (file, isa);
   1608  1.1  christos 		else
   1609  1.1  christos 		  gen_itable_c (file, isa);
   1610  1.1  christos 		break;
   1611  1.1  christos 	      case 'f':
   1612  1.1  christos 		if (is_header)
   1613  1.1  christos 		  gen_support_h (file, isa);
   1614  1.1  christos 		else
   1615  1.1  christos 		  gen_support_c (file, isa);
   1616  1.1  christos 		break;
   1617  1.1  christos 	      case 'r':
   1618  1.1  christos 		if (is_header)
   1619  1.1  christos 		  options.warning (NULL, "-hr option ignored\n");
   1620  1.1  christos 		else
   1621  1.1  christos 		  gen_run_c (file, gen);
   1622  1.1  christos 		break;
   1623  1.1  christos 	      case 's':
   1624  1.1  christos 		if (is_header)
   1625  1.1  christos 		  gen_semantics_h (file, gen->semantics, isa->max_nr_words);
   1626  1.1  christos 		else
   1627  1.1  christos 		  gen_semantics_c (file, gen->semantics, isa->caches);
   1628  1.1  christos 		break;
   1629  1.1  christos 	      case 'd':
   1630  1.1  christos 		if (is_header)
   1631  1.1  christos 		  gen_idecode_h (file, gen, isa, cache_rules);
   1632  1.1  christos 		else
   1633  1.1  christos 		  gen_idecode_c (file, gen, isa, cache_rules);
   1634  1.1  christos 		break;
   1635  1.1  christos 	      case 'e':
   1636  1.1  christos 		if (is_header)
   1637  1.1  christos 		  gen_engine_h (file, gen, isa, cache_rules);
   1638  1.1  christos 		else
   1639  1.1  christos 		  gen_engine_c (file, gen, isa, cache_rules);
   1640  1.1  christos 		break;
   1641  1.1  christos 	      case 'c':
   1642  1.1  christos 		if (is_header)
   1643  1.1  christos 		  gen_icache_h (file,
   1644  1.1  christos 				gen->semantics,
   1645  1.1  christos 				isa->functions, isa->max_nr_words);
   1646  1.1  christos 		else
   1647  1.1  christos 		  gen_icache_c (file,
   1648  1.1  christos 				gen->semantics, isa->functions, cache_rules);
   1649  1.1  christos 		break;
   1650  1.1  christos 	      }
   1651  1.1  christos 	    lf_print__file_finish (file);
   1652  1.1  christos 	    lf_close (file);
   1653  1.1  christos 	    is_header = 0;
   1654  1.1  christos 	  }
   1655  1.1  christos 	  real_file_name = NULL;
   1656  1.1  christos 	  break;
   1657  1.1  christos 	default:
   1658  1.1  christos 	  ERROR ("Bad switch");
   1659  1.1  christos 	}
   1660  1.1  christos     }
   1661  1.1  christos   return (0);
   1662  1.1  christos }
   1663