Add a simple dissasembler to igen
[binutils-gdb.git] / sim / igen / igen.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22
23 #include <getopt.h>
24
25 #include "misc.h"
26 #include "lf.h"
27 #include "table.h"
28 #include "config.h"
29
30 #include "filter.h"
31
32 #include "ld-decode.h"
33 #include "ld-cache.h"
34 #include "ld-insn.h"
35
36 #include "igen.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-support.h"
44
45 int hi_bit_nr = 0;
46 int insn_bit_size = default_insn_bit_size;
47 int insn_specifying_widths = 0;
48 const char *global_name_prefix = "";
49 const char *global_uname_prefix = "";
50 int semantic_zero_reg_nr = 0;
51
52 int code = generate_calls;
53
54 int generate_expanded_instructions;
55 int icache_size = 1024;
56 int generate_smp;
57
58 /****************************************************************/
59
60
61 /* Semantic functions */
62
63 int
64 print_semantic_function_formal(lf *file)
65 {
66 int nr;
67 if ((code & generate_with_icache))
68 nr = lf_printf(file, "SIM_DESC sd,\n %sidecode_cache *cache_entry,\n %sinstruction_address cia",
69 global_name_prefix, global_name_prefix);
70 else if (generate_smp)
71 nr = lf_printf(file, "sim_cpu *cpu,\n %sinstruction_word instruction,\n %sinstruction_address cia",
72 global_name_prefix, global_name_prefix);
73 else
74 nr = lf_printf(file, "SIM_DESC sd,\n %sinstruction_word instruction,\n %sinstruction_address cia",
75 global_name_prefix, global_name_prefix);
76 return nr;
77 }
78
79 int
80 print_semantic_function_actual(lf *file)
81 {
82 int nr;
83 if ((code & generate_with_icache))
84 nr = lf_printf(file, "sd, cache_entry, cia");
85 else if (generate_smp)
86 nr = lf_printf(file, "cpu, instruction, cia");
87 else
88 nr = lf_printf(file, "sd, instruction, cia");
89 return nr;
90 }
91
92 int
93 print_semantic_function_type(lf *file)
94 {
95 int nr;
96 nr = lf_printf(file, "%sinstruction_address", global_name_prefix);
97 return nr;
98 }
99
100
101 /* Idecode functions */
102
103 int
104 print_icache_function_formal(lf *file)
105 {
106 int nr = 0;
107 if (generate_smp)
108 nr += lf_printf(file, "sim_cpu *cpu,\n");
109 else
110 nr += lf_printf(file, "SIM_DESC sd,\n");
111 nr += lf_printf(file, " %sinstruction_word instruction,\n", global_name_prefix);
112 nr += lf_printf(file, " %sinstruction_address cia,\n", global_name_prefix);
113 nr += lf_printf(file, " %sidecode_cache *cache_entry", global_name_prefix);
114 return nr;
115 }
116
117 int
118 print_icache_function_actual(lf *file)
119 {
120 int nr;
121 if (generate_smp)
122 nr = lf_printf(file, "cpu, instruction, cia, cache_entry");
123 else
124 nr = lf_printf(file, "sd, instruction, cia, cache_entry");
125 return nr;
126 }
127
128 int
129 print_icache_function_type(lf *file)
130 {
131 int nr;
132 if ((code & generate_with_semantic_icache))
133 nr = print_semantic_function_type(file);
134 else
135 nr = lf_printf(file, "%sidecode_semantic *", global_name_prefix);
136 return nr;
137 }
138
139
140 /* Function names */
141
142 static int
143 print_insn_bits(lf *file, insn_bits *bits)
144 {
145 int nr = 0;
146 if (bits == NULL)
147 return nr;
148 nr += print_insn_bits(file, bits->last);
149 nr += lf_putchr(file, '_');
150 nr += lf_putstr(file, bits->field->val_string);
151 if (bits->opcode->is_boolean && bits->value == 0)
152 nr += lf_putint(file, bits->opcode->boolean_constant);
153 else if (!bits->opcode->is_boolean) {
154 if (bits->opcode->last < bits->field->last)
155 nr += lf_putint(file, bits->value << (bits->field->last - bits->opcode->last));
156 else
157 nr += lf_putint(file, bits->value);
158 }
159 return nr;
160 }
161
162 extern int
163 print_function_name(lf *file,
164 const char *basename,
165 insn_bits *expanded_bits,
166 lf_function_name_prefixes prefix)
167 {
168 int nr = 0;
169 /* the prefix */
170 switch (prefix) {
171 case function_name_prefix_semantics:
172 nr += lf_putstr(file, global_name_prefix);
173 nr += lf_putstr(file, "semantic_");
174 break;
175 case function_name_prefix_idecode:
176 nr += lf_putstr(file, global_name_prefix);
177 nr += lf_printf(file, "idecode_");
178 break;
179 case function_name_prefix_itable:
180 nr += lf_putstr(file, "itable_");
181 break;
182 case function_name_prefix_icache:
183 nr += lf_putstr(file, global_name_prefix);
184 nr += lf_putstr(file, "icache_");
185 break;
186 default:
187 break;
188 }
189
190 /* the function name */
191 {
192 const char *pos;
193 for (pos = basename;
194 *pos != '\0';
195 pos++) {
196 switch (*pos) {
197 case '/':
198 case '-':
199 break;
200 case ' ':
201 case '.':
202 nr += lf_putchr(file, '_');
203 break;
204 default:
205 nr += lf_putchr(file, *pos);
206 break;
207 }
208 }
209 }
210
211 /* the suffix */
212 if (generate_expanded_instructions)
213 nr += print_insn_bits(file, expanded_bits);
214
215 return nr;
216 }
217
218
219 void
220 print_my_defines (lf *file,
221 insn_bits *expanded_bits,
222 table_entry *file_entry)
223 {
224 /* #define MY_INDEX xxxxx */
225 lf_indent_suppress (file);
226 lf_printf (file, "#undef MY_INDEX\n");
227 lf_indent_suppress (file);
228 lf_printf (file, "#define MY_INDEX ");
229 print_function_name (file,
230 file_entry->fields[insn_name],
231 NULL,
232 function_name_prefix_itable);
233 lf_printf (file, "\n");
234 /* #define MY_PREFIX xxxxxx */
235 lf_indent_suppress (file);
236 lf_printf (file, "#undef MY_PREFIX\n");
237 lf_indent_suppress (file);
238 lf_printf (file, "#define MY_PREFIX ");
239 print_function_name (file,
240 file_entry->fields[insn_name],
241 expanded_bits,
242 function_name_prefix_none);
243 lf_printf (file, "\n");
244 }
245
246
247 static int
248 print_itrace_prefix (lf *file,
249 table_entry *file_entry,
250 const char *phase_lc)
251 {
252 const char *prefix = "trace_one_insn (";
253 int indent = strlen (prefix);
254 lf_printf (file, "%sSD, CPU, %s, TRACE_LINENUM_P (CPU),\n",
255 prefix, (code & generate_with_semantic_delayed_branch) ? "cia.ip" : "cia");
256 lf_indent (file, +indent);
257 lf_printf (file, "itable[MY_INDEX].file,\n");
258 lf_printf (file, "itable[MY_INDEX].line_nr,\n");
259 lf_printf (file, "\"%s\",\n", phase_lc);
260 return indent;
261 }
262
263
264 static void
265 print_itrace_format (lf *file,
266 table_assembler_entry *assembler)
267 {
268 /* pass=1 is fmt string; pass=2 is is arguments */
269 int pass;
270 const char *chp;
271 /* print the format string */
272 for (pass = 1; pass <= 2; pass++)
273 {
274 const char *chp = assembler->format;
275 chp++; /* skip the leading quote */
276 /* prefix the format with the insn `name' */
277 if (pass == 1)
278 {
279 lf_printf (file, "\"%%s - %%s - ");
280 }
281 else
282 {
283 lf_printf (file, ",\n");
284 lf_printf (file, "itable[MY_INDEX].name");
285 lf_printf (file, ",\n");
286 lf_printf (file, "XSTRING(MY_PREFIX)");
287 }
288 /* write out the format/args */
289 while (*chp != '\0')
290 {
291 if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>'))
292 {
293 if (pass == 1)
294 lf_putchr (file, chp[1]);
295 chp += 2;
296 }
297 else if (chp[0] == '<' || chp[0] == '%')
298 {
299 /* parse [ "%" ... ] "<" [ func "#" ] param ">" */
300 const char *fmt;
301 const char *func;
302 int strlen_func;
303 const char *param;
304 int strlen_param;
305 /* the "%" ... "<" format */
306 fmt = chp;
307 while (chp[0] != '<' && chp[0] != '\0')
308 chp++;
309 if (chp[0] != '<')
310 error ("%s:%d: Missing `<' after `%%'",
311 assembler->file_name,
312 assembler->line_nr);
313 chp++;
314 /* [ "func" # ] OR "param" */
315 func = chp;
316 param = chp;
317 while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0')
318 chp++;
319 strlen_func = chp - func;
320 if (chp[0] == '#')
321 {
322 chp++;
323 param = chp;
324 while (chp[0] != '>' && chp[0] != '\0')
325 chp++;
326 }
327 strlen_param = chp - param;
328 if (chp[0] != '>')
329 error ("%s:%d: Missing closing `>' in assembler string",
330 assembler->file_name,
331 assembler->line_nr);
332 chp++;
333 /* now process it */
334 if (pass == 2)
335 lf_printf (file, ",\n");
336 if (strncmp (fmt, "<", 1) == 0)
337 /* implicit long int format */
338 {
339 if (pass == 1)
340 lf_printf (file, "%%ld");
341 else
342 {
343 lf_printf (file, "(long) ");
344 lf_write (file, param, strlen_param);
345 }
346 }
347 else if (strncmp (fmt, "%<", 2) == 0)
348 /* explicit format */
349 {
350 if (pass == 1)
351 lf_printf (file, "%%");
352 else
353 lf_write (file, param, strlen_param);
354 }
355 else if (strncmp (fmt, "%s<", 3) == 0)
356 /* string format */
357 {
358 if (pass == 1)
359 lf_printf (file, "%%s");
360 else
361 {
362 lf_printf (file, "%sstr_", global_name_prefix);
363 lf_write (file, func, strlen_func);
364 lf_printf (file, " (_SD, ");
365 lf_write (file, param, strlen_param);
366 lf_printf (file, ")");
367 }
368 }
369 else if (strncmp (fmt, "%lx<", 4) == 0)
370 /* simple hex */
371 {
372 if (pass == 1)
373 lf_printf (file, "%%lx");
374 else
375 {
376 lf_printf (file, "(unsigned long) ");
377 lf_write (file, param, strlen_param);
378 }
379 }
380 else if (strncmp (fmt, "%08lx<", 6) == 0)
381 /* simple hex */
382 {
383 if (pass == 1)
384 lf_printf (file, "%%08lx");
385 else
386 {
387 lf_printf (file, "(unsigned long) ");
388 lf_write (file, param, strlen_param);
389 }
390 }
391 else
392 error ("%s:%d: Unknown assembler string format",
393 assembler->file_name,
394 assembler->line_nr);
395 }
396 else
397 {
398 if (pass == 1)
399 lf_putchr (file, chp[0]);
400 chp += 1;
401 }
402 }
403 }
404 lf_printf (file, ");\n");
405 }
406
407
408 void
409 print_itrace (lf *file,
410 table_entry *file_entry,
411 int idecode)
412 {
413 const char *phase = (idecode) ? "DECODE" : "INSN";
414 const char *phase_lc = (idecode) ? "decode" : "insn";
415 lf_printf (file, "\n");
416 lf_indent_suppress (file);
417 lf_printf (file, "#if defined (WITH_TRACE)\n");
418 lf_printf (file, "/* trace the instructions execution if enabled */\n");
419 lf_printf (file, "if (TRACE_%s_P (CPU)) {\n", phase);
420 lf_indent (file, +2);
421 if (file_entry->assembler != NULL)
422 {
423 table_assembler_entry *assembler = file_entry->assembler;
424 int is_first = 1;
425 do
426 {
427 if (assembler->condition != NULL)
428 {
429 int indent;
430 lf_printf (file, "%sif (%s)\n",
431 is_first ? "" : "else ",
432 assembler->condition);
433 lf_indent (file, +2);
434 indent = print_itrace_prefix (file, file_entry, phase_lc);
435 print_itrace_format (file, assembler);
436 lf_indent (file, -indent);
437 lf_indent (file, -2);
438 if (assembler->next == NULL)
439 error ("%s:%d: Missing final unconditional assembler",
440 assembler->file_name,
441 assembler->line_nr);
442 }
443 else
444 {
445 int indent;
446 if (!is_first)
447 {
448 lf_printf (file, "else\n");
449 lf_indent (file, +2);
450 }
451 indent = print_itrace_prefix (file, file_entry, phase_lc);
452 print_itrace_format (file, assembler);
453 lf_indent (file, -indent);
454 if (!is_first)
455 lf_indent (file, -2);
456 if (assembler->next != NULL)
457 error ("%s:%d: Unconditional assembler is not last",
458 assembler->file_name,
459 assembler->line_nr);
460 }
461 is_first = 0;
462 assembler = assembler->next;
463 }
464 while (assembler != NULL);
465 }
466 else
467 {
468 int indent = print_itrace_prefix (file, file_entry, phase_lc);
469 lf_printf (file, "\"%%s - %%s - ?\",\n");
470 lf_printf (file, "itable[MY_INDEX].name,\n");
471 lf_printf (file, "XSTRING(MY_PREFIX));\n");
472 lf_indent (file, -indent);
473 }
474 lf_indent (file, -2);
475 lf_printf (file, "}\n");
476 lf_indent_suppress (file);
477 lf_printf (file, "#endif\n");
478 }
479
480
481 /****************************************************************/
482
483
484 static void
485 gen_semantics_h(insn_table *table,
486 lf *file,
487 igen_code generate)
488 {
489 lf_printf(file, "typedef ");
490 print_semantic_function_type(file);
491 lf_printf(file, " %sidecode_semantic\n(", global_name_prefix);
492 print_semantic_function_formal(file);
493 lf_printf(file, ");\n");
494 lf_printf(file, "\n");
495 if ((code & generate_calls)) {
496 if (generate_expanded_instructions)
497 insn_table_traverse_tree(table,
498 file, NULL,
499 1,
500 NULL, /* start */
501 print_semantic_declaration, /* leaf */
502 NULL, /* end */
503 NULL); /* padding */
504 else
505 insn_table_traverse_insn(table,
506 file, NULL,
507 print_semantic_declaration);
508
509 }
510 else {
511 lf_print__this_file_is_empty(file);
512 }
513 }
514
515
516 static void
517 gen_semantics_c(insn_table *table,
518 cache_table *cache_rules,
519 lf *file,
520 igen_code generate)
521 {
522 if ((code & generate_calls)) {
523 lf_printf(file, "\n");
524 lf_printf(file, "#include \"sim-main.h\"\n");
525 lf_printf(file, "#include \"%sidecode.h\"\n", global_name_prefix);
526 lf_printf(file, "#include \"%ssemantics.h\"\n", global_name_prefix);
527 lf_printf(file, "#include \"%ssupport.h\"\n", global_name_prefix);
528 lf_printf(file, "\n");
529 if (generate_expanded_instructions)
530 insn_table_traverse_tree(table,
531 file, cache_rules,
532 1,
533 NULL, /* start */
534 print_semantic_definition, /* leaf */
535 NULL, /* end */
536 NULL); /* padding */
537 else
538 insn_table_traverse_insn(table,
539 file, cache_rules,
540 print_semantic_definition);
541
542 }
543 else {
544 lf_print__this_file_is_empty(file);
545 }
546 }
547
548
549 /****************************************************************/
550
551
552 static void
553 gen_icache_h(insn_table *table,
554 lf *file,
555 igen_code generate)
556 {
557 lf_printf(file, "typedef ");
558 print_icache_function_type(file);
559 lf_printf(file, " %sidecode_icache\n(", global_name_prefix);
560 print_icache_function_formal(file);
561 lf_printf(file, ");\n");
562 lf_printf(file, "\n");
563 if ((code & generate_calls)
564 && (code & generate_with_icache)) {
565 insn_table_traverse_function(table,
566 file, NULL,
567 print_icache_internal_function_declaration);
568 if (generate_expanded_instructions)
569 insn_table_traverse_tree(table,
570 file, NULL,
571 1,
572 NULL, /* start */
573 print_icache_declaration, /* leaf */
574 NULL, /* end */
575 NULL); /* padding */
576 else
577 insn_table_traverse_insn(table,
578 file, NULL,
579 print_icache_declaration);
580
581 }
582 else {
583 lf_print__this_file_is_empty(file);
584 }
585 }
586
587 static void
588 gen_icache_c(insn_table *table,
589 cache_table *cache_rules,
590 lf *file,
591 igen_code generate)
592 {
593 /* output `internal' invalid/floating-point unavailable functions
594 where needed */
595 if ((code & generate_calls)
596 && (code & generate_with_icache)) {
597 lf_printf(file, "\n");
598 lf_printf(file, "#include \"cpu.h\"\n");
599 lf_printf(file, "#include \"idecode.h\"\n");
600 lf_printf(file, "#include \"semantics.h\"\n");
601 lf_printf(file, "#include \"icache.h\"\n");
602 lf_printf(file, "#include \"support.h\"\n");
603 lf_printf(file, "\n");
604 insn_table_traverse_function(table,
605 file, NULL,
606 print_icache_internal_function_definition);
607 lf_printf(file, "\n");
608 if (generate_expanded_instructions)
609 insn_table_traverse_tree(table,
610 file, cache_rules,
611 1,
612 NULL, /* start */
613 print_icache_definition, /* leaf */
614 NULL, /* end */
615 NULL); /* padding */
616 else
617 insn_table_traverse_insn(table,
618 file, cache_rules,
619 print_icache_definition);
620
621 }
622 else {
623 lf_print__this_file_is_empty(file);
624 }
625 }
626
627
628 /****************************************************************/
629
630
631 int
632 main(int argc,
633 char **argv,
634 char **envp)
635 {
636 cache_table *cache_rules = NULL;
637 lf_file_references file_references = lf_include_references;
638 decode_table *decode_rules = NULL;
639 filter *filters = NULL;
640 insn_table *instructions = NULL;
641 char *real_file_name = NULL;
642 int is_header = 0;
643 int ch;
644
645 if (argc == 1) {
646 printf("Usage:\n");
647 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
648 printf("Config options:\n");
649 printf(" -F <filter-flag> eg -F 32 to include 32bit instructions\n");
650 printf(" -I <icache-size> Specify size of cracking cache\n");
651 printf(" -B <bit-size> Set the number of bits in an instruction\n");
652 printf(" -H <high-bit> Set the number of the high (msb) instruction bit\n");
653 printf(" -N <nr-cpus> Specify the max number of cpus the simulation will support\n");
654 printf(" -T <mechanism> Override the decode mechanism specified by the decode rules\n");
655 printf(" -P <prefix> Prepend all functions with the specified prefix\n");
656 printf(" -G <gen-option> Any of the following options:\n");
657 printf(" field-widths - instruction table specifies widths (not ofsesets)\n");
658 printf(" jumps - use jumps instead of function calls\n");
659 printf(" duplicate - expand (duplicate) semantic functions\n");
660 printf(" omit-line-numbers - do not include line nr info in output\n");
661 printf(" direct-access - use #defines to directly access values\n");
662 printf(" icache - generate an instruction cracking cache\n");
663 printf(" semantic-icache - include semantic code in cracking functions\n");
664 printf(" insn-in-icache - save original instruction when cracking\n");
665 printf(" default-nia-minus-one - instead of cia + insn-size\n");
666 printf(" delayed-branch - instead of cia + insn-size\n");
667 printf(" zero-r<N> - arch assumes GPR(<N>) == 0, keep it that way\n");
668 printf(" conditional-issue - conditionally issue each instruction\n");
669 printf(" validate-slot - perform slot verification as part of decode\n");
670 printf("\n");
671 printf("Input options:\n");
672 printf(" -o <decode-rules>\n");
673 printf(" -k <cache-rules>\n");
674 printf(" -i <instruction-table>\n");
675 printf("\n");
676 printf("Output options:\n");
677 printf(" -n <real-name> Specify the real name of the next output file\n");
678 printf(" -h Generate header file\n");
679 printf(" -c <output-file> output icache\n");
680 printf(" -d <output-file> output idecode\n");
681 printf(" -e <output-file> output engine\n");
682 printf(" -f <output-file> output support functions\n");
683 printf(" -m <output-file> output model\n");
684 printf(" -s <output-file> output schematic\n");
685 printf(" -t <output-file> output itable\n");
686 }
687
688 while ((ch = getopt(argc, argv,
689 "F:I:B:H:N:T:P:G:o:k:i:n:hc:d:e:m:s:t:f:"))
690 != -1) {
691 fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : ""));
692
693 switch(ch) {
694
695 case 'F':
696 filters = new_filter(optarg, filters);
697 break;
698
699 case 'I':
700 icache_size = a2i(optarg);
701 code |= generate_with_icache;
702 break;
703
704 case 'B':
705 insn_bit_size = a2i(optarg);
706 ASSERT(insn_bit_size > 0 && insn_bit_size <= max_insn_bit_size
707 && (hi_bit_nr == insn_bit_size-1 || hi_bit_nr == 0));
708 break;
709
710 case 'H':
711 hi_bit_nr = a2i(optarg);
712 ASSERT(hi_bit_nr == insn_bit_size-1 || hi_bit_nr == 0);
713 break;
714
715 case 'N':
716 generate_smp = a2i(optarg);
717 break;
718
719 case 'T':
720 force_decode_gen_type(optarg);
721 break;
722
723 case 'P':
724 {
725 char *chp;
726 global_name_prefix = strdup(optarg);
727 chp = strdup(optarg);
728 global_uname_prefix = chp;
729 while (*chp) {
730 if (islower(*chp))
731 *chp = toupper(*chp);
732 chp++;
733 }
734 }
735 break;
736
737 case 'G':
738 if (strcmp(optarg, "jumps") == 0) {
739 code &= ~generate_calls;
740 code |= generate_jumps;
741 }
742 else if (strcmp(optarg, "field-widths") == 0) {
743 insn_specifying_widths = 1;
744 }
745 else if (strcmp(optarg, "duplicate") == 0) {
746 generate_expanded_instructions = 1;
747 }
748 else if (strcmp(optarg, "omit-line-numbers") == 0) {
749 file_references = lf_omit_references;
750 }
751 else if (strcmp(optarg, "direct-access") == 0) {
752 code |= generate_with_direct_access;
753 }
754 else if (strcmp(optarg, "icache") == 0) {
755 }
756 else if (strcmp(optarg, "semantic-icache") == 0) {
757 code |= generate_with_icache;
758 code |= generate_with_semantic_icache;
759 }
760 else if (strcmp(optarg, "insn-in-icache") == 0) {
761 code |= generate_with_icache;
762 code |= generate_with_insn_in_icache;
763 }
764 else if (strcmp(optarg, "default-nia-minus-one") == 0) {
765 code |= generate_with_semantic_returning_modified_nia_only;
766 code &= ~generate_with_semantic_delayed_branch;
767 }
768 else if (strcmp(optarg, "delayed-branch") == 0) {
769 code |= generate_with_semantic_delayed_branch;
770 code &= ~generate_with_semantic_returning_modified_nia_only;
771 }
772 else if (strcmp(optarg, "conditional-issue") == 0) {
773 code |= generate_with_semantic_conditional_issue;
774 }
775 else if (strncmp (optarg, "zero-r", strlen ("zero-r")) == 0) {
776 code |= generate_with_semantic_zero_reg;
777 semantic_zero_reg_nr = atoi (optarg + strlen ("zero-r"));
778 }
779 else if (strcmp(optarg, "verify-slot") == 0) {
780 code |= generate_with_idecode_slot_verification;
781 }
782 else
783 error("Unknown option %s", optarg);
784 break;
785
786 case 'i':
787 if (decode_rules == NULL || cache_rules == NULL) {
788 fprintf(stderr, "Must specify decode and cache tables\n");
789 exit (1);
790 }
791 instructions = load_insn_table(optarg, decode_rules, filters);
792 fprintf(stderr, "\texpanding ...\n");
793 insn_table_expand_insns(instructions);
794 break;
795 case 'o':
796 decode_rules = load_decode_table(optarg, hi_bit_nr);
797 break;
798 case 'k':
799 cache_rules = load_cache_table(optarg, hi_bit_nr);
800 break;
801 case 'n':
802 real_file_name = strdup(optarg);
803 break;
804 case 'h':
805 is_header = 1;
806 break;
807 case 's':
808 case 'd':
809 case 'e':
810 case 'm':
811 case 't':
812 case 'f':
813 case 'c':
814 {
815 lf *file = lf_open(optarg, real_file_name, file_references,
816 (is_header ? lf_is_h : lf_is_c),
817 argv[0]);
818 lf_print__file_start(file);
819 ASSERT(instructions != NULL);
820 switch (ch) {
821 case 's':
822 if(is_header)
823 gen_semantics_h(instructions, file, code);
824 else
825 gen_semantics_c(instructions, cache_rules, file, code);
826 break;
827 case 'd':
828 if (is_header)
829 gen_idecode_h(file, instructions, cache_rules);
830 else
831 gen_idecode_c(file, instructions, cache_rules);
832 break;
833 case 'e':
834 if (is_header)
835 gen_engine_h(file, instructions, cache_rules);
836 else
837 gen_engine_c(file, instructions, cache_rules);
838 break;
839 case 'm':
840 if (is_header)
841 gen_model_h(instructions, file);
842 else
843 gen_model_c(instructions, file);
844 break;
845 case 't':
846 if (is_header)
847 gen_itable_h(instructions, file);
848 else
849 gen_itable_c(instructions, file);
850 break;
851 case 'f':
852 if (is_header)
853 gen_support_h(instructions, file);
854 else
855 gen_support_c(instructions, file);
856 break;
857 case 'c':
858 if (is_header)
859 gen_icache_h(instructions, file, code);
860 else
861 gen_icache_c(instructions, cache_rules, file, code);
862 break;
863 }
864 lf_print__file_finish(file);
865 lf_close(file);
866 is_header = 0;
867 }
868 real_file_name = NULL;
869 break;
870 default:
871 error("unknown option\n");
872 }
873 }
874 return 0;
875 }