]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/igen.c
sim: igen: constify various func arguments
[thirdparty/binutils-gdb.git] / sim / igen / igen.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
4a94e368 3 Copyright 2002-2022 Free Software Foundation, Inc.
feaee4bd
AC
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
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
feaee4bd
AC
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
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 21
c906108c 22#include <getopt.h>
3d52735b 23#include <stdlib.h>
c906108c
SS
24
25#include "misc.h"
26#include "lf.h"
27#include "table.h"
c906108c
SS
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
4e0bf4c4 54print_semantic_function_formal (lf *file, int nr_prefetched_words)
c906108c
SS
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",
4e0bf4c4 72 options.module.global.prefix.l, word_nr);
c906108c
SS
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",
4e0bf4c4 83 options.module.global.prefix.l, word_nr);
c906108c
SS
84 }
85 nr += lf_printf (file, "%sinstruction_address cia",
86 options.module.global.prefix.l);
87 }
88 return nr;
89}
90
91int
4e0bf4c4 92print_semantic_function_actual (lf *file, int nr_prefetched_words)
c906108c
SS
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
4e0bf4c4 126print_icache_function_formal (lf *file, int nr_prefetched_words)
c906108c
SS
127{
128 int nr = 0;
129 int word_nr;
130 if (options.gen.smp)
4e0bf4c4 131 nr += lf_printf (file, "sim_cpu *cpu,\n");
c906108c 132 else
4e0bf4c4 133 nr += lf_printf (file, "SIM_DESC sd,\n");
c906108c
SS
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
4e0bf4c4 145print_icache_function_actual (lf *file, int nr_prefetched_words)
c906108c
SS
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
fa654e74 179print_opcode_bits (lf *file, const opcode_bits *bits)
c906108c
SS
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);
4e0bf4c4
AC
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 }
c906108c
SS
197 nr += print_opcode_bits (file, bits->next);
198 return nr;
199}
200
201static int
4e0bf4c4 202print_c_name (lf *file, const char *name)
c906108c
SS
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,
fa654e74 230 const opcode_bits *expanded_bits,
c906108c
SS
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 }
4e0bf4c4 258
c906108c
SS
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);
4e0bf4c4 267
c906108c
SS
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,
fa654e74
MF
285 const char *format_name,
286 const opcode_bits *expanded_bits)
c906108c
SS
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,
4e0bf4c4 295 NULL, function_name_prefix_itable);
c906108c
SS
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,
4e0bf4c4 302 expanded_bits, function_name_prefix_none);
c906108c
SS
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,
4e0bf4c4 310 expanded_bits, function_name_prefix_none);
c906108c
SS
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,
4e0bf4c4 320 expanded_bits, function_name_prefix_none);
c906108c
SS
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);
4e0bf4c4
AC
330 lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n",
331 prefix);
c906108c 332 lf_indent (file, +indent);
4e0bf4c4
AC
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);
c906108c
SS
337 lf_printf (file, "\"");
338 return indent;
339}
340
341
342static void
fa654e74 343print_itrace_format (lf *file, const insn_mnemonic_entry *assembler)
c906108c
SS
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;
4e0bf4c4 351 chp++; /* skip the leading quote */
c906108c
SS
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] != '>')
4e0bf4c4
AC
391 error (assembler->line,
392 "Missing closing `>' in assembler string\n");
c906108c
SS
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 {
4e0bf4c4
AC
423 lf_printf (file, "%sstr_",
424 options.module.global.prefix.l);
c906108c
SS
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 }
6225b4b7 442 else if (strncmp (fmt, "%#lx<", 5) == 0)
4e0bf4c4 443 /* simple hex with 0x prefix */
6225b4b7
CD
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 }
c906108c
SS
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
fa654e74 480print_itrace (lf *file, const insn_entry *insn, int idecode)
c906108c
SS
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",
4e0bf4c4 505 is_first ? "" : "else ", assembler->condition);
c906108c
SS
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)
4e0bf4c4
AC
514 error (assembler->line,
515 "Missing final unconditional assembler\n");
c906108c
SS
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)
4e0bf4c4
AC
533 error (assembler->line,
534 "Unconditional assembler is not last\n");
c906108c
SS
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);
4e0bf4c4
AC
555 lf_printf (file,
556 " trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n",
557 phase);
c906108c
SS
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
4e0bf4c4 567print_sim_engine_abort (lf *file, const char *message)
c906108c
SS
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
4e0bf4c4 576print_include (lf *file, igen_module module)
c906108c
SS
577{
578 lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l);
579}
580
581void
4e0bf4c4 582print_include_inline (lf *file, igen_module module)
c906108c
SS
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
fa654e74 608gen_semantics_h (lf *file, const insn_list *semantics, int max_nr_words)
c906108c
SS
609{
610 int word_nr;
fa654e74 611 const insn_list *semantic;
c906108c
SS
612 for (word_nr = -1; word_nr <= max_nr_words; word_nr++)
613 {
614 lf_printf (file, "typedef ");
615 print_semantic_function_type (file);
4e0bf4c4 616 lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l);
c906108c
SS
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
fa654e74 649gen_semantics_c (lf *file, const insn_list *semantics, cache_entry *cache_rules)
c906108c
SS
650{
651 if (options.gen.code == generate_calls)
652 {
fa654e74 653 const insn_list *semantic;
c906108c
SS
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,
fa654e74
MF
683 const insn_list *semantic,
684 const function_entry *functions, int max_nr_words)
c906108c
SS
685{
686 int word_nr;
687 for (word_nr = 0; word_nr <= max_nr_words; word_nr++)
688 {
689 lf_printf (file, "typedef ");
4e0bf4c4 690 print_icache_function_type (file);
c906108c 691 lf_printf (file, " %sidecode_icache_%d\n(",
4e0bf4c4
AC
692 options.module.global.prefix.l, word_nr);
693 print_icache_function_formal (file, word_nr);
c906108c
SS
694 lf_printf (file, ");\n");
695 lf_printf (file, "\n");
696 }
4e0bf4c4 697 if (options.gen.code == generate_calls && options.gen.icache)
c906108c
SS
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,
fa654e74
MF
720 const insn_list *semantic,
721 const function_entry *functions, cache_entry *cache_rules)
c906108c
SS
722{
723 /* output `internal' invalid/floating-point unavailable functions
724 where needed */
4e0bf4c4 725 if (options.gen.code == generate_calls && options.gen.icache)
c906108c
SS
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,
fa654e74
MF
761 const gen_table *gen,
762 const insn_table *insns,
763 cache_entry *cache_rules)
c906108c 764{
9850d2d8 765 lf_printf (file, "typedef uint%d_t %sinstruction_word;\n",
c906108c
SS
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");
4e0bf4c4
AC
773 lf_printf (file, "} %sinstruction_address;\n",
774 options.module.global.prefix.l);
c906108c
SS
775 }
776 else
777 {
778 lf_printf (file, "typedef address_word %sinstruction_address;\n",
779 options.module.global.prefix.l);
4e0bf4c4 780
c906108c
SS
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,
4e0bf4c4 807 1 /*ALWAYS ONE WORD */ );
c906108c
SS
808 }
809 if (options.gen.multi_sim)
810 {
811 print_idecode_issue_function_header (file,
812 NULL,
813 is_function_variable,
4e0bf4c4 814 1 /*ALWAYS ONE WORD */ );
c906108c
SS
815 }
816 }
817}
818
819
820static void
821gen_idecode_c (lf *file,
fa654e74
MF
822 const gen_table *gen,
823 const insn_table *isa,
824 cache_entry *cache_rules)
c906108c
SS
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");
4e0bf4c4 833
c906108c
SS
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);
4e0bf4c4 842
c906108c
SS
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),
4e0bf4c4
AC
850 1 /*is definition */ ,
851 1 /*ALWAYS ONE WORD */ );
c906108c
SS
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
fa654e74 877gen_run_c (lf *file, const gen_table *gen)
c906108c
SS
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 {
4e0bf4c4
AC
888 print_idecode_issue_function_header (file, NULL, is_function_variable,
889 1);
c906108c
SS
890 lf_printf (file, "\n");
891 print_engine_run_function_header (file, NULL, is_function_variable);
892 lf_printf (file, "\n");
893 }
4e0bf4c4 894
c906108c
SS
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
4e0bf4c4
AC
916 || strcmp (entry->model->full_name,
917 options.gen.default_model) == 0))
c906108c
SS
918 lf_printf (file, "default:\n");
919 lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name);
920 lf_indent (file, +2);
4e0bf4c4
AC
921 print_function_name (file, "issue", NULL, /* format name */
922 NULL, /* NO processor */
923 NULL, /* expanded bits */
c906108c
SS
924 function_name_prefix_idecode);
925 lf_printf (file, " = ");
4e0bf4c4
AC
926 print_function_name (file, "issue", NULL, /* format name */
927 entry->model->name, NULL, /* expanded bits */
c906108c
SS
928 function_name_prefix_idecode);
929 lf_printf (file, ";\n");
4e0bf4c4
AC
930 print_function_name (file, "run", NULL, /* format name */
931 NULL, /* NO processor */
932 NULL, /* expanded bits */
c906108c
SS
933 function_name_prefix_engine);
934 lf_printf (file, " = ");
4e0bf4c4
AC
935 print_function_name (file, "run", NULL, /* format name */
936 entry->model->name, NULL, /* expanded bits */
c906108c
SS
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");
4e0bf4c4
AC
947 lf_printf (file,
948 " \"sim_engine_run - unknown machine\");\n");
c906108c
SS
949 lf_printf (file, "break;\n");
950 lf_indent (file, -2);
951 }
952 lf_indent (file, -2);
953 lf_printf (file, " }\n");
954 }
4e0bf4c4
AC
955 print_function_name (file, "run", NULL, /* format name */
956 NULL, /* NO processor */
957 NULL, /* expanded bits */
c906108c
SS
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 *
fa654e74 967do_gen (const insn_table *isa, const decode_table *decode_rules)
c906108c
SS
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
4e0bf4c4 987main (int argc, char **argv, char **envp)
c906108c
SS
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;
dd6c5a92 997 static const struct option longopts[] = { { 0 } };
4e0bf4c4
AC
998 lf *standard_out =
999 lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen");
c906108c
SS
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");
5accf1ff 1012 printf ("\t Set the number of bits in an instruction (deprecated).\n");
4e0bf4c4
AC
1013 printf
1014 ("\t This option can now be set directly in the instruction table.\n");
c906108c
SS
1015 printf ("\n");
1016 printf (" -D <data-structure>\n");
4e0bf4c4
AC
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");
c906108c
SS
1021 printf ("\n");
1022 printf (" -F <filter-list>\n");
4e0bf4c4
AC
1023 printf
1024 ("\t Filter out any instructions with a non-empty flags field that contains\n");
c906108c
SS
1025 printf ("\t a flag not listed in the <filter-list>.\n");
1026 printf ("\n");
1027 printf (" -H <high-bit>\n");
4e0bf4c4
AC
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");
c906108c
SS
1032 printf ("\n");
1033 printf (" -I <directory>\n");
4e0bf4c4
AC
1034 printf
1035 ("\t Add <directory> to the list of directories searched when opening a file\n");
c906108c
SS
1036 printf ("\n");
1037 printf (" -M <model-list>\n");
4e0bf4c4
AC
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");
c906108c
SS
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");
4e0bf4c4
AC
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");
c906108c
SS
1050 printf ("\n");
1051 printf (" -T <mechanism>\n");
4e0bf4c4
AC
1052 printf
1053 ("\t Override the decode mechanism specified by the decode rules\n");
c906108c
SS
1054 printf ("\n");
1055 printf (" -P <prefix>\n");
4e0bf4c4
AC
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");
c906108c
SS
1060 printf ("\n");
1061 printf (" -S <suffix>\n");
4e0bf4c4
AC
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");
c906108c
SS
1066 printf ("\n");
1067 printf (" -Werror\n");
1068 printf ("\t Make warnings errors\n");
1069 printf (" -Wnodiscard\n");
4e0bf4c4
AC
1070 printf
1071 ("\t Suppress warnings about discarded functions and instructions\n");
c906108c 1072 printf (" -Wnowidth\n");
4e0bf4c4
AC
1073 printf
1074 ("\t Suppress warnings about instructions with invalid widths\n");
c906108c
SS
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");
4e0bf4c4
AC
1081 printf
1082 ("\t decode-duplicate - Override the decode rules, forcing the duplication of\n");
c906108c 1083 printf ("\t semantic functions\n");
4e0bf4c4
AC
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");
c906108c 1088 printf ("\t treated as zero.\n");
4e0bf4c4
AC
1089 printf
1090 ("\t decode-switch-is-goto - Overfide the padded-switch code type as a goto-switch\n");
c906108c 1091 printf ("\n");
4e0bf4c4
AC
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");
c906108c
SS
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");
4e0bf4c4
AC
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");
c906108c
SS
1127 printf ("\t trace-rule-rejection - report each rule as rejected\n");
1128 printf ("\t trace-rule-selection - report each rule as selected\n");
4e0bf4c4
AC
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");
c906108c
SS
1133 printf ("\t trace-all - enable all trace options\n");
1134 printf ("\n");
4e0bf4c4
AC
1135 printf
1136 ("\t field-widths - instruction formats specify widths (deprecated)\n");
1137 printf
1138 ("\t By default, an instruction format specifies bit\n");
c906108c 1139 printf ("\t positions\n");
4e0bf4c4
AC
1140 printf
1141 ("\t This option can now be set directly in the\n");
c906108c 1142 printf ("\t instruction table\n");
4e0bf4c4
AC
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");
c906108c
SS
1147 printf ("\n");
1148 printf ("Input options:\n");
1149 printf ("\n");
5accf1ff 1150 printf (" -k <cache-rules> (deprecated)\n");
c906108c
SS
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");
4e0bf4c4
AC
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");
c906108c
SS
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 }
4e0bf4c4 1170
dd6c5a92
TO
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))
c906108c
SS
1174 != -1)
1175 {
ac9b6df2 1176#if 0 /* For debugging. */
c906108c
SS
1177 fprintf (stderr, " -%c ", ch);
1178 if (optarg)
1179 fprintf (stderr, "%s ", optarg);
1180 fprintf (stderr, "\\\n");
ac9b6df2 1181#endif
4e0bf4c4
AC
1182
1183 switch (ch)
c906108c 1184 {
4e0bf4c4 1185
c906108c
SS
1186 case 'M':
1187 filter_parse (&options.model_filter, optarg);
1188 break;
1189
1190 case 'D':
1191 if (strcmp (optarg, "processor-names"))
1192 {
fa654e74 1193 const char *processor;
c906108c
SS
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;
4e0bf4c4 1206
c906108c
SS
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;
4e0bf4c4 1216
c906108c
SS
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;
4e0bf4c4 1231
c906108c
SS
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;
4e0bf4c4 1240
c906108c
SS
1241 case 'N':
1242 options.gen.smp = a2i (optarg);
1243 break;
4e0bf4c4 1244
c906108c
SS
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 {
4e0bf4c4 1259 chp = chp + 1; /* skip `=' */
c906108c
SS
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;
78e731cd 1302 default:
4e0bf4c4 1303 abort (); /* Bad switch. */
c906108c
SS
1304 }
1305 name->u = strdup (chp);
1306 name->l = strdup (chp);
1307 chp = name->u;
4e0bf4c4
AC
1308 while (*chp)
1309 {
1310 if (islower (*chp))
1311 *chp = toupper (*chp);
1312 chp++;
1313 }
c906108c
SS
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; */
4e0bf4c4
AC
1320 options.module.semantics.prefix =
1321 options.module.global.prefix;
c906108c
SS
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; */
4e0bf4c4
AC
1330 options.module.semantics.suffix =
1331 options.module.global.suffix;
c906108c
SS
1332 options.module.support.suffix = options.module.global.suffix;
1333 }
1334 break;
1335 }
4e0bf4c4 1336
c906108c
SS
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 }
4e0bf4c4 1390
c906108c
SS
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;
4e0bf4c4
AC
1398 options.warning (NULL,
1399 "Option conditional-issue replaced by gen-conditional-issue\n");
c906108c
SS
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;
4e0bf4c4
AC
1408 options.warning (NULL,
1409 "Option delayed-branch replaced by gen-delayed-branch\n");
c906108c
SS
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;
4e0bf4c4
AC
1418 options.warning (NULL,
1419 "Option direct-access replaced by gen-direct-access\n");
c906108c
SS
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"));
4e0bf4c4
AC
1430 options.warning (NULL,
1431 "Option zero-r<N> replaced by gen-zero-r<N>\n");
c906108c
SS
1432 }
1433 else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0)
1434 {
1435 switch (argp[strlen ("gen-icache")])
1436 {
1437 case '=':
4e0bf4c4
AC
1438 options.gen.icache_size =
1439 atoi (argp + strlen ("gen-icache") + 1);
c906108c
SS
1440 options.gen.icache = enable_p;
1441 break;
1442 case '\0':
1443 options.gen.icache = enable_p;
1444 break;
1445 default:
4e0bf4c4
AC
1446 error (NULL,
1447 "Expecting -Ggen-icache or -Ggen-icache=<N>\n");
c906108c
SS
1448 }
1449 }
1450 else if (strcmp (argp, "gen-insn-in-icache") == 0)
1451 {
1452 options.gen.insn_in_icache = enable_p;
1453 }
4e0bf4c4
AC
1454 else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim"))
1455 == 0)
c906108c
SS
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;
4e0bf4c4
AC
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);
c906108c
SS
1467 break;
1468 case '\0':
1469 options.gen.multi_sim = enable_p;
1470 options.gen.default_model = NULL;
1471 break;
1472 default:
4e0bf4c4
AC
1473 error (NULL,
1474 "Expecting -Ggen-multi-sim or -Ggen-multi-sim=<MODEL>\n");
c906108c
SS
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;
4e0bf4c4
AC
1493 options.warning (NULL,
1494 "Option verify-slot replaced by gen-slot-verification\n");
c906108c
SS
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;
4e0bf4c4
AC
1503 options.warning (NULL,
1504 "Option default-nia-minus-one replaced by gen-nia-invalid\n");
c906108c
SS
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 }
4e0bf4c4 1556
c906108c
SS
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':
4e0bf4c4 1578 real_file_name = strdup (optarg);
c906108c
SS
1579 break;
1580
1581 case 'h':
1582 is_header = 1;
1583 break;
4e0bf4c4 1584
c906108c
SS
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 {
4e0bf4c4
AC
1594 lf *file = lf_open (optarg, real_file_name, file_references,
1595 (is_header ? lf_is_h : lf_is_c),
1596 argv[0]);
c906108c
SS
1597 if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f')
1598 {
4e0bf4c4
AC
1599 options.warning (NULL,
1600 "Explicitly generate tables with -x option\n");
c906108c
SS
1601 gen = do_gen (isa, decode_rules);
1602 }
4e0bf4c4 1603 lf_print__file_start (file);
c906108c
SS
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':
4e0bf4c4 1631 if (is_header)
c906108c
SS
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,
4e0bf4c4 1652 isa->functions, isa->max_nr_words);
c906108c
SS
1653 else
1654 gen_icache_c (file,
4e0bf4c4 1655 gen->semantics, isa->functions, cache_rules);
c906108c
SS
1656 break;
1657 }
4e0bf4c4
AC
1658 lf_print__file_finish (file);
1659 lf_close (file);
c906108c
SS
1660 is_header = 0;
1661 }
4e0bf4c4
AC
1662 real_file_name = NULL;
1663 break;
c906108c
SS
1664 default:
1665 ERROR ("Bad switch");
1666 }
1667 }
1668 return (0);
1669}