xref: /netbsd-src/external/gpl3/gdb/dist/sim/igen/igen.c (revision 71f621822dbfd5073a314948bec169b7bb05f7be)
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2 
3    Copyright 2002-2024 Free Software Foundation, Inc.
4 
5    Contributed by Andrew Cagney.
6 
7    This file is part of GDB.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21 
22 #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 
53 int
54 print_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 
91 int
92 print_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 
113 int
114 print_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 
125 int
126 print_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 
144 int
145 print_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 
159 int
160 print_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 
178 static int
179 print_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 
201 static int
202 print_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 
225 extern int
226 print_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 
282 void
283 print_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 
325 static int
326 print_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 
342 static void
343 print_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 
479 void
480 print_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 
566 void
567 print_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 
575 void
576 print_include (lf *file, igen_module module)
577 {
578   lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l);
579 }
580 
581 void
582 print_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 
592 void
593 print_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 
607 static void
608 gen_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 
648 static void
649 gen_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 
681 static void
682 gen_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 
718 static void
719 gen_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 
759 static void
760 gen_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 
820 static void
821 gen_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 
876 static void
877 gen_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 
966 static gen_table *
967 do_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 
984 igen_options options;
985 
986 int
987 main (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