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