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