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