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