change [ -d foo ] to test -d foo
[deliverable/binutils-gdb.git] / sim / ppc / igen.c
CommitLineData
c143ef62
MM
1/* This file is part of the program psim.
2
3 Copyright (C) 1994-1995, 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#include <stdio.h>
22#include <ctype.h>
c143ef62
MM
23#include <getopt.h>
24
25#include "misc.h"
26#include "lf.h"
27#include "table.h"
c494cadd
MM
28#include "config.h"
29
30#ifdef HAVE_STRING_H
31#include <string.h>
32#else
33#ifdef HAVE_STRINGS_H
34#include <strings.h>
35#endif
36#endif
37
f2181eff
MM
38#ifdef HAVE_STDLIB_H
39#include <stdlib.h>
40#endif
41
c143ef62
MM
42
43
44/****************************************************************/
45
46enum {
a983c8f0 47 max_insn_size = 32,
c143ef62
MM
48};
49
a3114052
MM
50static int hi_bit_nr = 0;
51static int insn_size = max_insn_size;
52static int idecode_expand_semantics = 0;
53static int idecode_cache = 0;
f2181eff 54static int semantics_use_cache_struct = 0;
a3114052 55static int number_lines = 1;
c143ef62
MM
56
57
58/****************************************************************/
59
60
a3114052
MM
61static char *cache_idecode_formal =
62"cpu *processor,\n\
63 instruction_word instruction,\n\
64 unsigned_word cia,\n\
65 idecode_cache *cache_entry";
c143ef62 66
a3114052 67static char *cache_idecode_actual = "processor, instruction, cia, cache_entry";
c143ef62 68
a3114052
MM
69static char *cache_semantic_formal =
70"cpu *processor,\n\
71 idecode_cache *cache_entry,\n\
72 unsigned_word cia";
73
74static char *semantic_formal =
75"cpu *processor,\n\
76 instruction_word instruction,\n\
77 unsigned_word cia";
78
79static char *semantic_actual = "processor, instruction, cia";
c143ef62 80
c143ef62
MM
81
82
83/****************************************************************/
84
85
86typedef struct _filter filter;
87struct _filter {
88 char *flag;
89 filter *next;
90};
a3114052 91static filter *filters = NULL;
c143ef62
MM
92
93
94/****************************************************************/
95
96
97typedef struct _cache_rules cache_rules;
98struct _cache_rules {
99 int valid;
100 char *old_name;
101 char *new_name;
102 char *type;
103 char *expression;
104 cache_rules *next;
105};
a3114052 106static cache_rules *cache_table;
c143ef62
MM
107
108
109enum {
110 ca_valid,
111 ca_old_name,
112 ca_new_name,
113 ca_type,
114 ca_expression,
115 nr_cache_rule_fields,
116};
117
118static cache_rules *
119load_cache_rules(char *file_name)
120{
a3114052 121 table *file = table_open(file_name, nr_cache_rule_fields, 0);
c143ef62
MM
122 table_entry *entry;
123 cache_rules *table = NULL;
124 cache_rules **curr_rule = &table;
125 while ((entry = table_entry_read(file)) != NULL) {
126 cache_rules *new_rule = ZALLOC(cache_rules);
a983c8f0 127 new_rule->valid = target_a2i(hi_bit_nr, entry->fields[ca_valid]);
c143ef62
MM
128 new_rule->old_name = entry->fields[ca_old_name];
129 new_rule->new_name = entry->fields[ca_new_name];
130 new_rule->type = (strlen(entry->fields[ca_type])
131 ? entry->fields[ca_type]
132 : NULL);
133 new_rule->expression = (strlen(entry->fields[ca_expression]) > 0
134 ? entry->fields[ca_expression]
135 : NULL);
136 *curr_rule = new_rule;
137 curr_rule = &new_rule->next;
138 }
139 return table;
140}
141
142
143
144static void
145dump_cache_rule(cache_rules* rule,
146 int indent)
147{
148 dumpf(indent, "((cache_rules*)0x%x\n", rule);
149 dumpf(indent, " (valid %d)\n", rule->valid);
150 dumpf(indent, " (old_name \"%s\")\n", rule->old_name);
151 dumpf(indent, " (new_name \"%s\")\n", rule->new_name);
152 dumpf(indent, " (type \"%s\")\n", rule->type);
153 dumpf(indent, " (expression \"%s\")\n", rule->expression);
154 dumpf(indent, " (next 0x%x)\n", rule->next);
155 dumpf(indent, " )\n");
156}
157
158
159static void
160dump_cache_rules(cache_rules* rule, int indent)
161{
162 while (rule) {
163 dump_cache_rule(rule, indent);
164 rule = rule->next;
165 }
166}
167
168
169/****************************************************************/
170
171
172typedef struct _opcode_rules opcode_rules;
173struct _opcode_rules {
174 int first;
175 int last;
176 int force_first;
177 int force_last;
178 int force_slash;
179 char *force_expansion;
180 int use_switch;
181 unsigned special_mask;
182 unsigned special_value;
183 unsigned special_rule;
184 opcode_rules *next;
185};
a3114052 186static opcode_rules *opcode_table;
c143ef62
MM
187
188
189enum {
190 op_first,
191 op_last,
192 op_force_first,
193 op_force_last,
194 op_force_slash,
195 op_force_expansion,
196 op_use_switch,
197 op_special_mask,
198 op_special_value,
199 op_special_rule,
200 nr_opcode_fields,
201};
202
203
204static opcode_rules *
205load_opcode_rules(char *file_name)
206{
a3114052 207 table *file = table_open(file_name, nr_opcode_fields, 0);
c143ef62
MM
208 table_entry *entry;
209 opcode_rules *table = NULL;
210 opcode_rules **curr_rule = &table;
211 while ((entry = table_entry_read(file)) != NULL) {
212 opcode_rules *new_rule = ZALLOC(opcode_rules);
a983c8f0
MM
213 new_rule->first = target_a2i(hi_bit_nr, entry->fields[op_first]);
214 new_rule->last = target_a2i(hi_bit_nr, entry->fields[op_last]);
215 new_rule->force_first = target_a2i(hi_bit_nr, entry->fields[op_force_first]);
216 new_rule->force_last = target_a2i(hi_bit_nr, entry->fields[op_force_last]);
c143ef62
MM
217 new_rule->force_slash = a2i(entry->fields[op_force_slash]);
218 new_rule->force_expansion = entry->fields[op_force_expansion];
219 new_rule->use_switch = a2i(entry->fields[op_use_switch]);
220 new_rule->special_mask = a2i(entry->fields[op_special_mask]);
221 new_rule->special_value = a2i(entry->fields[op_special_value]);
222 new_rule->special_rule = a2i(entry->fields[op_special_rule]);
223 *curr_rule = new_rule;
224 curr_rule = &new_rule->next;
225 }
226 return table;
227}
228
229
230static void
231dump_opcode_rule(opcode_rules *rule,
232 int indent)
233{
234 dumpf(indent, "((opcode_rules*)%p\n", rule);
235 if (rule) {
236 dumpf(indent, " (first %d)\n", rule->first);
237 dumpf(indent, " (last %d)\n", rule->last);
238 dumpf(indent, " (force_first %d)\n", rule->force_first);
239 dumpf(indent, " (force_last %d)\n", rule->force_last);
240 dumpf(indent, " (force_slash %d)\n", rule->force_slash);
241 dumpf(indent, " (force_expansion \"%s\")\n", rule->force_expansion);
242 dumpf(indent, " (use_switch %d)\n", rule->use_switch);
243 dumpf(indent, " (special_mask 0x%x)\n", rule->special_mask);
244 dumpf(indent, " (special_value 0x%x)\n", rule->special_value);
245 dumpf(indent, " (special_rule 0x%x)\n", rule->special_rule);
246 dumpf(indent, " (next 0x%x)\n", rule->next);
247 }
248 dumpf(indent, " )\n");
249}
250
251
252static void
253dump_opcode_rules(opcode_rules *rule,
254 int indent)
255{
256 while (rule) {
257 dump_opcode_rule(rule, indent);
258 rule = rule->next;
259 }
260}
261
262
263/****************************************************************/
264
265typedef struct _insn_field insn_field;
266struct _insn_field {
267 int first;
268 int last;
269 int width;
270 int is_int;
271 int is_slash;
272 int is_string;
273 int val_int;
274 char *pos_string;
275 char *val_string;
276 insn_field *next;
277 insn_field *prev;
278};
279
280typedef struct _insn_fields insn_fields;
281struct _insn_fields {
a983c8f0 282 insn_field *bits[max_insn_size];
c143ef62
MM
283 insn_field *first;
284 insn_field *last;
285 unsigned value;
286};
287
288static insn_fields *
289parse_insn_format(table_entry *entry,
290 char *format)
291{
292 char *chp;
293 insn_fields *fields = ZALLOC(insn_fields);
294
295 /* create a leading sentinal */
296 fields->first = ZALLOC(insn_field);
297 fields->first->first = -1;
298 fields->first->last = -1;
299 fields->first->width = 0;
300
301 /* and a trailing sentinal */
302 fields->last = ZALLOC(insn_field);
303 fields->last->first = insn_size;
304 fields->last->last = insn_size;
305 fields->last->width = 0;
306
307 /* link them together */
308 fields->first->next = fields->last;
309 fields->last->prev = fields->first;
310
311 /* now work through the formats */
312 chp = format;
313
314 while (*chp != '\0') {
315 char *start_pos;
316 char *start_val;
317 int strlen_val;
318 int strlen_pos;
319 insn_field *new_field;
320
321 /* sanity check */
322 if (!isdigit(*chp)) {
323 error("%s:%d: missing position field at `%s'\n",
324 entry->file_name, entry->line_nr, chp);
325 }
326
327 /* break out the bit position */
328 start_pos = chp;
329 while (isdigit(*chp))
330 chp++;
331 strlen_pos = chp - start_pos;
332 if (*chp == '.' && strlen_pos > 0)
333 chp++;
334 else {
335 error("%s:%d: missing field value at %s\n",
336 entry->file_name, entry->line_nr, chp);
337 break;
338 }
339
340 /* break out the value */
341 start_val = chp;
342 while ((*start_val == '/' && *chp == '/')
343 || (isdigit(*start_val) && isdigit(*chp))
344 || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_')))
345 chp++;
346 strlen_val = chp - start_val;
347 if (*chp == ',')
348 chp++;
349 else if (*chp != '\0' || strlen_val == 0) {
350 error("%s:%d: missing field terminator at %s\n",
351 entry->file_name, entry->line_nr, chp);
352 break;
353 }
354
355 /* create a new field and insert it */
356 new_field = ZALLOC(insn_field);
357 new_field->next = fields->last;
358 new_field->prev = fields->last->prev;
359 new_field->next->prev = new_field;
360 new_field->prev->next = new_field;
361
362 /* the value */
363 new_field->val_string = (char*)zalloc(strlen_val+1);
364 strncpy(new_field->val_string, start_val, strlen_val);
365 if (isdigit(*new_field->val_string)) {
366 new_field->val_int = a2i(new_field->val_string);
367 new_field->is_int = 1;
368 }
369 else if (new_field->val_string[0] == '/') {
370 new_field->is_slash = 1;
371 }
372 else {
373 new_field->is_string = 1;
374 }
375
376 /* the pos */
377 new_field->pos_string = (char*)zalloc(strlen_pos+1);
378 strncpy(new_field->pos_string, start_pos, strlen_pos);
a983c8f0 379 new_field->first = target_a2i(hi_bit_nr, new_field->pos_string);
c143ef62
MM
380 new_field->last = new_field->next->first - 1; /* guess */
381 new_field->width = new_field->last - new_field->first + 1; /* guess */
382 new_field->prev->last = new_field->first-1; /*fix*/
383 new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
384 }
385
386 /* fiddle first/last so that the sentinals `disapear' */
387 ASSERT(fields->first->last < 0);
388 ASSERT(fields->last->first >= insn_size);
389 fields->first = fields->first->next;
390 fields->last = fields->last->prev;
391
392 /* now go over this again, pointing each bit position at a field
393 record */
394 {
395 int i;
396 insn_field *field;
397 field = fields->first;
398 for (i = 0; i < insn_size; i++) {
399 while (field->last < i)
400 field = field->next;
401 fields->bits[i] = field;
402 }
403 }
404
405 /* go over each of the fields, and compute a `value' for the insn */
406 {
407 insn_field *field;
408 fields->value = 0;
409 for (field = fields->first;
410 field->last < insn_size;
411 field = field->next) {
412 fields->value <<= field->width;
413 if (field->is_int)
414 fields->value |= field->val_int;
415 }
416 }
417 return fields;
418}
419
420
421typedef enum {
422 field_constant_int = 1,
423 field_constant_slash = 2,
424 field_constant_string = 3
425} constant_field_types;
426
427
428static int
429insn_field_is_constant(insn_field *field,
430 opcode_rules *rule)
431{
432 /* field is an integer */
433 if (field->is_int)
434 return field_constant_int;
435 /* field is `/' and treating that as a constant */
436 if (field->is_slash && rule->force_slash)
437 return field_constant_slash;
438 /* field, though variable is on the list */
439 if (field->is_string && rule->force_expansion != NULL) {
440 char *forced_fields = rule->force_expansion;
441 while (*forced_fields != '\0') {
442 int field_len;
443 char *end = strchr(forced_fields, ',');
444 if (end == NULL)
445 field_len = strlen(forced_fields);
446 else
447 field_len = end-forced_fields;
448 if (strncmp(forced_fields, field->val_string, field_len) == 0
449 && field->val_string[field_len] == '\0')
450 return field_constant_string;
451 forced_fields += field_len;
452 if (*forced_fields == ',')
453 forced_fields++;
454 }
455 }
456 return 0;
457}
458
459
460static void
461dump_insn_field(insn_field *field,
462 int indent)
463{
464
465 printf("(insn_field*)0x%x\n", (unsigned)field);
466
467 dumpf(indent, "(first %d)\n", field->first);
468
469 dumpf(indent, "(last %d)\n", field->last);
470
471 dumpf(indent, "(width %d)\n", field->width);
472
473 if (field->is_int)
474 dumpf(indent, "(is_int %d)\n", field->val_int);
475
476 if (field->is_slash)
477 dumpf(indent, "(is_slash)\n");
478
479 if (field->is_string)
480 dumpf(indent, "(is_string `%s')\n", field->val_string);
481
482 dumpf(indent, "(next 0x%x)\n", field->next);
483
484 dumpf(indent, "(prev 0x%x)\n", field->prev);
485
486
487}
488
489static void
490dump_insn_fields(insn_fields *fields,
491 int indent)
492{
493 int i;
494
495 printf("(insn_fields*)%p\n", fields);
496
497 dumpf(indent, "(first 0x%x)\n", fields->first);
498 dumpf(indent, "(last 0x%x)\n", fields->last);
499
500 dumpf(indent, "(value 0x%x)\n", fields->value);
501
502 for (i = 0; i < insn_size; i++) {
503 dumpf(indent, "(bits[%d] ", i, fields->bits[i]);
504 dump_insn_field(fields->bits[i], indent+1);
505 dumpf(indent, " )\n");
506 }
507
508}
509
510
511/****************************************************************/
512
513typedef struct _opcode_field opcode_field;
514struct _opcode_field {
515 int first;
516 int last;
517 int is_boolean;
518 opcode_field *parent;
519};
520
c143ef62
MM
521static void
522dump_opcode_field(opcode_field *field, int indent, int levels)
523{
524 printf("(opcode_field*)%p\n", field);
525 if (levels && field != NULL) {
526 dumpf(indent, "(first %d)\n", field->first);
527 dumpf(indent, "(last %d)\n", field->last);
528 dumpf(indent, "(is_boolean %d)\n", field->is_boolean);
529 dumpf(indent, "(parent ");
530 dump_opcode_field(field->parent, indent, levels-1);
531 }
532}
533
534
535/****************************************************************/
536
537typedef struct _insn_bits insn_bits;
538struct _insn_bits {
539 int is_expanded;
540 int value;
541 insn_field *field;
542 opcode_field *opcode;
543 insn_bits *last;
544};
545
546
547static void
548dump_insn_bits(insn_bits *bits, int indent, int levels)
549{
550 printf("(insn_bits*)%p\n", bits);
551
552 if (levels && bits != NULL) {
553 dumpf(indent, "(value %d)\n", bits->value);
554 dumpf(indent, "(opcode ");
555 dump_opcode_field(bits->opcode, indent+1, 0);
556 dumpf(indent, " )\n");
557 dumpf(indent, "(field ");
558 dump_insn_field(bits->field, indent+1);
559 dumpf(indent, " )\n");
560 dumpf(indent, "(last ");
561 dump_insn_bits(bits->last, indent+1, levels-1);
562 }
563}
564
565
566/****************************************************************/
567
568
569typedef enum {
570 insn_format,
571 insn_form,
572 insn_flags,
1dc7c0ed 573 insn_mnemonic,
c143ef62
MM
574 insn_name,
575 insn_comment,
a3114052 576 nr_insn_table_fields
c143ef62 577} insn_table_fields;
c143ef62
MM
578
579typedef enum {
580 function_type = insn_format,
581 function_name = insn_name,
a3114052 582 function_param = insn_comment
c143ef62
MM
583} function_table_fields;
584
a3114052 585typedef enum {
1dc7c0ed 586 model_name = insn_mnemonic,
28816f45 587 model_identifer = insn_name,
80948f39 588 model_default = insn_comment,
a3114052 589} model_table_fields;
c143ef62
MM
590
591typedef struct _insn insn;
592struct _insn {
593 table_entry *file_entry;
594 insn_fields *fields;
595 insn *next;
596};
597
f2181eff
MM
598typedef struct _insn_undef insn_undef;
599struct _insn_undef {
600 insn_undef *next;
601 char *name;
602};
603
604static insn_undef *first_undef, *last_undef;
605
a3114052
MM
606typedef struct _model model;
607struct _model {
608 model *next;
609 char *name;
28816f45 610 char *printable_name;
80948f39
MM
611 char *insn_default;
612 table_model_entry *func_unit_start;
613 table_model_entry *func_unit_end;
a3114052
MM
614};
615
c143ef62
MM
616typedef struct _insn_table insn_table;
617struct _insn_table {
618 int opcode_nr;
619 insn_bits *expanded_bits;
620 int nr_insn;
621 insn *insns;
622 insn *functions;
a3114052 623 insn *last_function;
c143ef62
MM
624 opcode_rules *opcode_rule;
625 opcode_field *opcode;
626 int nr_entries;
627 insn_table *entries;
628 insn_table *sibling;
629 insn_table *parent;
630};
631
a3114052
MM
632typedef enum {
633 insn_model_name,
80948f39 634 insn_model_fields,
a3114052
MM
635 nr_insn_model_table_fields
636} insn_model_table_fields;
637
638static model *models;
639static model *last_model;
c143ef62 640
28816f45
MM
641static insn *model_macros;
642static insn *last_model_macro;
c143ef62 643
eb4ef197
MM
644static insn *model_functions;
645static insn *last_model_function;
646
1dc7c0ed
MM
647static insn *model_internal;
648static insn *last_model_internal;
649
4a0351ab
MM
650static insn *model_static;
651static insn *last_model_static;
652
1dc7c0ed
MM
653static insn *model_data;
654static insn *last_model_data;
655
845ff5a4
MM
656static int max_model_fields_len;
657
c143ef62
MM
658static void
659insn_table_insert_function(insn_table *table,
660 table_entry *file_entry)
661{
c143ef62
MM
662 /* create a new function */
663 insn *new_function = ZALLOC(insn);
664 new_function->file_entry = file_entry;
665
666 /* append it to the end of the function list */
a3114052
MM
667 if (table->last_function)
668 table->last_function->next = new_function;
669 else
670 table->functions = new_function;
671 table->last_function = new_function;
672}
673
c143ef62
MM
674static void
675insn_table_insert_insn(insn_table *table,
676 table_entry *file_entry,
677 insn_fields *fields)
678{
679 insn **ptr_to_cur_insn = &table->insns;
680 insn *cur_insn = *ptr_to_cur_insn;
a3114052
MM
681 table_model_entry *insn_model_ptr;
682 model *model_ptr;
c143ef62
MM
683
684 /* create a new instruction */
685 insn *new_insn = ZALLOC(insn);
686 new_insn->file_entry = file_entry;
687 new_insn->fields = fields;
688
a3114052
MM
689 /* Check out any model information returned to make sure the model
690 is correct. */
691 for(insn_model_ptr = file_entry->model_first; insn_model_ptr; insn_model_ptr = insn_model_ptr->next) {
692 char *name = insn_model_ptr->fields[insn_model_name];
845ff5a4
MM
693 int len = strlen (insn_model_ptr->fields[insn_model_fields]);
694
695 while (len > 0 && isspace(*insn_model_ptr->fields[insn_model_fields])) {
696 len--;
697 insn_model_ptr->fields[insn_model_fields]++;
698 }
699
700 if (max_model_fields_len < len)
701 max_model_fields_len = len;
a3114052
MM
702
703 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
80948f39 704 if (strcmp(name, model_ptr->printable_name) == 0) {
a3114052
MM
705
706 /* Replace the name field with that of the global model, so that when we
707 want to print it out, we can just compare pointers. */
80948f39 708 insn_model_ptr->fields[insn_model_name] = model_ptr->printable_name;
a3114052
MM
709 break;
710 }
711 }
712
713 if (!model_ptr)
714 error("%s:%d: machine model `%s' was not known about\n",
715 file_entry->file_name, file_entry->line_nr, name);
716 }
717
c143ef62
MM
718 /* insert it according to the order of the fields */
719 while (cur_insn != NULL
720 && new_insn->fields->value >= cur_insn->fields->value) {
721 ptr_to_cur_insn = &cur_insn->next;
722 cur_insn = *ptr_to_cur_insn;
723 }
724
725 new_insn->next = cur_insn;
726 *ptr_to_cur_insn = new_insn;
727
728 table->nr_insn++;
729}
730
731
732static opcode_field *
733insn_table_find_opcode_field(insn *insns,
734 opcode_rules *rule,
735 int string_only)
736{
1dc7c0ed 737 opcode_field *curr_opcode = ZALLOC(opcode_field);
c143ef62 738 insn *entry;
c143ef62
MM
739 ASSERT(rule);
740
1dc7c0ed
MM
741 curr_opcode->first = insn_size;
742 curr_opcode->last = -1;
c143ef62
MM
743 for (entry = insns; entry != NULL; entry = entry->next) {
744 insn_fields *fields = entry->fields;
745 opcode_field new_opcode;
746
747 /* find a start point for the opcode field */
748 new_opcode.first = rule->first;
749 while (new_opcode.first <= rule->last
750 && (!string_only
751 || insn_field_is_constant(fields->bits[new_opcode.first],
752 rule) != field_constant_string)
753 && (string_only
754 || !insn_field_is_constant(fields->bits[new_opcode.first],
755 rule)))
756 new_opcode.first = fields->bits[new_opcode.first]->last + 1;
757 ASSERT(new_opcode.first > rule->last
758 || (string_only
759 && insn_field_is_constant(fields->bits[new_opcode.first],
760 rule) == field_constant_string)
761 || (!string_only
762 && insn_field_is_constant(fields->bits[new_opcode.first],
763 rule)));
764
765 /* find the end point for the opcode field */
766 new_opcode.last = rule->last;
767 while (new_opcode.last >= rule->first
768 && (!string_only
769 || insn_field_is_constant(fields->bits[new_opcode.last],
770 rule) != field_constant_string)
771 && (string_only
772 || !insn_field_is_constant(fields->bits[new_opcode.last],
773 rule)))
774 new_opcode.last = fields->bits[new_opcode.last]->first - 1;
775 ASSERT(new_opcode.last < rule->first
776 || (string_only
777 && insn_field_is_constant(fields->bits[new_opcode.last],
778 rule) == field_constant_string)
779 || (!string_only
780 && insn_field_is_constant(fields->bits[new_opcode.last],
781 rule)));
782
783 /* now see if our current opcode needs expanding */
784 if (new_opcode.first <= rule->last
785 && curr_opcode->first > new_opcode.first)
786 curr_opcode->first = new_opcode.first;
787 if (new_opcode.last >= rule->first
788 && curr_opcode->last < new_opcode.last)
789 curr_opcode->last = new_opcode.last;
790
791 }
792
793 /* was any thing interesting found? */
794 if (curr_opcode->first > rule->last) {
795 ASSERT(curr_opcode->last < rule->first);
796 return NULL;
797 }
798 ASSERT(curr_opcode->last >= rule->first);
799 ASSERT(curr_opcode->first <= rule->last);
800
801 /* if something was found, check it includes the forced field range */
802 if (!string_only
803 && curr_opcode->first > rule->force_first) {
804 curr_opcode->first = rule->force_first;
805 }
806 if (!string_only
807 && curr_opcode->last < rule->force_last) {
808 curr_opcode->last = rule->force_last;
809 }
810 /* handle special case elminating any need to do shift after mask */
811 if (string_only
812 && rule->force_last == insn_size-1) {
813 curr_opcode->last = insn_size-1;
814 }
815
816 /* handle any special cases */
817 switch (rule->special_rule) {
818 case 0: /* let the above apply */
819 break;
820 case 1: /* expand a limited nr of bits, ignoring the rest */
821 curr_opcode->first = rule->force_first;
822 curr_opcode->last = rule->force_last;
823 break;
824 case 2: /* boolean field */
825 curr_opcode->is_boolean = 1;
826 break;
827 }
828
829 return curr_opcode;
830}
831
832
833static void
834insn_table_insert_expanded(insn_table *table,
835 insn *old_insn,
836 int new_opcode_nr,
837 insn_bits *new_bits)
838{
839 insn_table **ptr_to_cur_entry = &table->entries;
840 insn_table *cur_entry = *ptr_to_cur_entry;
841
842 /* find the new table for this entry */
843 while (cur_entry != NULL
844 && cur_entry->opcode_nr < new_opcode_nr) {
845 ptr_to_cur_entry = &cur_entry->sibling;
846 cur_entry = *ptr_to_cur_entry;
847 }
848
849 if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {
850 insn_table *new_entry = ZALLOC(insn_table);
851 new_entry->opcode_nr = new_opcode_nr;
852 new_entry->expanded_bits = new_bits;
853 new_entry->opcode_rule = table->opcode_rule->next;
854 new_entry->sibling = cur_entry;
855 new_entry->parent = table;
856 *ptr_to_cur_entry = new_entry;
857 cur_entry = new_entry;
858 table->nr_entries++;
859 }
860 /* ASSERT new_bits == cur_entry bits */
861 ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);
862 insn_table_insert_insn(cur_entry,
863 old_insn->file_entry,
864 old_insn->fields);
865}
866
867static void
868insn_table_expand_opcode(insn_table *table,
869 insn *instruction,
870 int field_nr,
871 int opcode_nr,
872 insn_bits *bits)
873{
874
875 if (field_nr > table->opcode->last) {
876 insn_table_insert_expanded(table, instruction, opcode_nr, bits);
877 }
878 else {
879 insn_field *field = instruction->fields->bits[field_nr];
880 if (field->is_int || field->is_slash) {
881 ASSERT(field->first >= table->opcode->first
882 && field->last <= table->opcode->last);
883 insn_table_expand_opcode(table, instruction, field->last+1,
884 ((opcode_nr << field->width) + field->val_int),
885 bits);
886 }
887 else {
888 int val;
889 int last_pos = ((field->last < table->opcode->last)
890 ? field->last : table->opcode->last);
891 int first_pos = ((field->first > table->opcode->first)
892 ? field->first : table->opcode->first);
893 int width = last_pos - first_pos + 1;
894 int last_val = (table->opcode->is_boolean
895 ? 2 : (1 << width));
896 for (val = 0; val < last_val; val++) {
897 insn_bits *new_bits = ZALLOC(insn_bits);
898 new_bits->field = field;
899 new_bits->value = val;
900 new_bits->last = bits;
901 new_bits->opcode = table->opcode;
902 insn_table_expand_opcode(table, instruction, last_pos+1,
903 ((opcode_nr << width) | val),
904 new_bits);
905 }
906 }
907 }
908}
909
910static void
911insn_table_insert_expanding(insn_table *table,
912 insn *entry)
913{
914 insn_table_expand_opcode(table,
915 entry,
916 table->opcode->first,
917 0,
918 table->expanded_bits);
919}
920
921
922static void
923insn_table_expand_insns(insn_table *table)
924{
925
926 ASSERT(table->nr_insn >= 1);
927
928 /* determine a valid opcode */
929 while (table->opcode_rule) {
930 /* specials only for single instructions */
931 if ((table->nr_insn > 1
932 && table->opcode_rule->special_mask == 0
933 && table->opcode_rule->special_rule == 0)
934 || (table->nr_insn == 1
935 && table->opcode_rule->special_mask != 0
936 && ((table->insns->fields->value
937 & table->opcode_rule->special_mask)
938 == table->opcode_rule->special_value))
939 || (idecode_expand_semantics
940 && table->opcode_rule->special_mask == 0
941 && table->opcode_rule->special_rule == 0))
942 table->opcode =
943 insn_table_find_opcode_field(table->insns,
944 table->opcode_rule,
945 table->nr_insn == 1/*string*/
946 );
947 if (table->opcode != NULL)
948 break;
949 table->opcode_rule = table->opcode_rule->next;
950 }
951
952 /* did we find anything */
953 if (table->opcode == NULL) {
954 return;
955 }
956 ASSERT(table->opcode != NULL);
957
958 /* back link what we found to its parent */
959 if (table->parent != NULL) {
960 ASSERT(table->parent->opcode != NULL);
961 table->opcode->parent = table->parent->opcode;
962 }
963
964 /* expand the raw instructions according to the opcode */
965 {
966 insn *entry;
967 for (entry = table->insns; entry != NULL; entry = entry->next) {
968 insn_table_insert_expanding(table, entry);
969 }
970 }
971
972 /* and do the same for the sub entries */
973 {
974 insn_table *entry;
975 for (entry = table->entries; entry != NULL; entry = entry->sibling) {
976 insn_table_expand_insns(entry);
977 }
978 }
979}
980
981
1dc7c0ed
MM
982static void
983model_table_insert(insn_table *table,
984 table_entry *file_entry)
985{
845ff5a4
MM
986 int len;
987
1dc7c0ed
MM
988 /* create a new model */
989 model *new_model = ZALLOC(model);
1dc7c0ed
MM
990
991 new_model->name = file_entry->fields[model_identifer];
992 new_model->printable_name = file_entry->fields[model_name];
80948f39 993 new_model->insn_default = file_entry->fields[model_default];
1dc7c0ed 994
845ff5a4
MM
995 while (*new_model->insn_default && isspace(*new_model->insn_default))
996 new_model->insn_default++;
997
998 len = strlen(new_model->insn_default);
999 if (max_model_fields_len < len)
1000 max_model_fields_len = len;
1001
1dc7c0ed
MM
1002 /* append it to the end of the model list */
1003 if (last_model)
1004 last_model->next = new_model;
1005 else
1006 models = new_model;
1007 last_model = new_model;
1dc7c0ed
MM
1008}
1009
1010static void
1011model_table_insert_specific(insn_table *table,
1012 table_entry *file_entry,
1013 insn **start_ptr,
1014 insn **end_ptr)
1015{
1016 insn *ptr = ZALLOC(insn);
1017 ptr->file_entry = file_entry;
1018 if (*end_ptr)
1019 (*end_ptr)->next = ptr;
1020 else
1021 (*start_ptr) = ptr;
1022 (*end_ptr) = ptr;
1023}
1024
1025
c143ef62
MM
1026
1027static insn_table *
1028insn_table_load_insns(char *file_name)
1029{
a3114052 1030 table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
c143ef62
MM
1031 insn_table *table = ZALLOC(insn_table);
1032 table_entry *file_entry;
1033 table->opcode_rule = opcode_table;
1034
1035 while ((file_entry = table_entry_read(file)) != NULL) {
1036 if (it_is("function", file_entry->fields[insn_flags])
1037 || it_is("internal", file_entry->fields[insn_flags])) {
1038 insn_table_insert_function(table, file_entry);
1039 }
a3114052
MM
1040 else if (it_is("model", file_entry->fields[insn_flags])) {
1041 model_table_insert(table, file_entry);
1042 }
28816f45 1043 else if (it_is("model-macro", file_entry->fields[insn_flags])) {
1dc7c0ed 1044 model_table_insert_specific(table, file_entry, &model_macros, &last_model_macro);
eb4ef197
MM
1045 }
1046 else if (it_is("model-function", file_entry->fields[insn_flags])) {
1dc7c0ed
MM
1047 model_table_insert_specific(table, file_entry, &model_functions, &last_model_function);
1048 }
1049 else if (it_is("model-internal", file_entry->fields[insn_flags])) {
1050 model_table_insert_specific(table, file_entry, &model_internal, &last_model_internal);
1051 }
4a0351ab
MM
1052 else if (it_is("model-static", file_entry->fields[insn_flags])) {
1053 model_table_insert_specific(table, file_entry, &model_static, &last_model_static);
1054 }
1dc7c0ed
MM
1055 else if (it_is("model-data", file_entry->fields[insn_flags])) {
1056 model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
28816f45 1057 }
c143ef62
MM
1058 else {
1059 insn_fields *fields;
1060 /* skip instructions that aren't relevant to the mode */
1061 filter *filt = filters;
1062 while (filt != NULL) {
1063 if (it_is(filt->flag, file_entry->fields[insn_flags]))
1064 break;
1065 filt = filt->next;
1066 }
1067 if (filt == NULL) {
1068 /* create/insert the new instruction */
1069 fields = parse_insn_format(file_entry,
1070 file_entry->fields[insn_format]);
1071 insn_table_insert_insn(table, file_entry, fields);
1072 }
1073 }
1074 }
1075 return table;
1076}
1077
1078
1079static void
1080dump_insn(insn *entry, int indent, int levels)
1081{
1082 printf("(insn*)%p\n", entry);
1083
1084 if (levels && entry != NULL) {
1085
1086 dumpf(indent, "(file_entry ");
1087 dump_table_entry(entry->file_entry, indent+1);
1088 dumpf(indent, " )\n");
1089
1090 dumpf(indent, "(fields ");
1091 dump_insn_fields(entry->fields, indent+1);
1092 dumpf(indent, " )\n");
1093
1094 dumpf(indent, "(next ");
1095 dump_insn(entry->next, indent+1, levels-1);
1096 dumpf(indent, " )\n");
1097
1098 }
1099
1100}
1101
1102
1103static void
1104dump_insn_table(insn_table *table,
1105 int indent, int levels)
1106{
1107
1108 printf("(insn_table*)%p\n", table);
1109
1110 if (levels && table != NULL) {
1111
1112 dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);
1113
1114 dumpf(indent, "(expanded_bits ");
1115 dump_insn_bits(table->expanded_bits, indent+1, -1);
1116 dumpf(indent, " )\n");
1117
1118 dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);
1119
1120 dumpf(indent, "(insns ");
1121 dump_insn(table->insns, indent+1, table->nr_insn);
1122 dumpf(indent, " )\n");
1123
1124 dumpf(indent, "(opcode_rule ");
1125 dump_opcode_rule(table->opcode_rule, indent+1);
1126 dumpf(indent, " )\n");
1127
1128 dumpf(indent, "(opcode ");
1129 dump_opcode_field(table->opcode, indent+1, 1);
1130 dumpf(indent, " )\n");
1131
1132 dumpf(indent, "(nr_entries %d)\n", table->entries);
1133 dumpf(indent, "(entries ");
1134 dump_insn_table(table->entries, indent+1, table->nr_entries);
1135 dumpf(indent, " )\n");
1136
1137 dumpf(indent, "(sibling ", table->sibling);
1138 dump_insn_table(table->sibling, indent+1, levels-1);
1139 dumpf(indent, " )\n");
1140
1141 dumpf(indent, "(parent ", table->parent);
1142 dump_insn_table(table->parent, indent+1, 0);
1143 dumpf(indent, " )\n");
1144
1145 }
1146}
1147
1148
1149/****************************************************************/
1150
1151
1152static void
1153lf_print_insn_bits(lf *file, insn_bits *bits)
1154{
1155 if (bits == NULL)
1156 return;
1157 lf_print_insn_bits(file, bits->last);
1158 lf_putchr(file, '_');
1159 lf_putstr(file, bits->field->val_string);
1160 if (!bits->opcode->is_boolean || bits->value == 0) {
1161 if (bits->opcode->last < bits->field->last)
1162 lf_putint(file, bits->value << (bits->field->last - bits->opcode->last));
1163 else
1164 lf_putint(file, bits->value);
1165 }
1166}
1167
1168static void
1169lf_print_opcodes(lf *file,
1170 insn_table *table)
1171{
1172 if (table != NULL) {
1173 while (1) {
1174 lf_printf(file, "_%d_%d",
1175 table->opcode->first,
1176 table->opcode->last);
1177 if (table->parent == NULL) break;
1178 lf_printf(file, "__%d", table->opcode_nr);
1179 table = table->parent;
1180 }
1181 }
1182}
1183
1184static void
1185lf_print_table_name(lf *file,
1186 insn_table *table)
1187{
1188 lf_printf(file, "idecode_table");
1189 lf_print_opcodes(file, table);
1190}
1191
1192
1193
1194typedef enum {
1195 function_name_prefix_semantics,
1196 function_name_prefix_idecode,
1197 function_name_prefix_itable,
1198 function_name_prefix_none
1199} lf_function_name_prefixes;
1200
1201static void
1202lf_print_function_name(lf *file,
1203 char *basename,
1204 insn_bits *expanded_bits,
1205 lf_function_name_prefixes prefix)
1206{
1207
1208 /* the prefix */
1209 switch (prefix) {
1210 case function_name_prefix_semantics:
1211 lf_putstr(file, "semantic_");
1212 break;
1213 case function_name_prefix_idecode:
1214 lf_printf(file, "idecode_");
1215 break;
1216 case function_name_prefix_itable:
1217 lf_putstr(file, "itable_");
1218 break;
1219 default:
1220 break;
1221 }
1222
1223 /* the function name */
1224 {
1225 char *pos;
1226 for (pos = basename;
1227 *pos != '\0';
1228 pos++) {
1229 switch (*pos) {
1230 case '/':
1231 case '-':
1232 break;
1233 case ' ':
1234 lf_putchr(file, '_');
1235 break;
1236 default:
1237 lf_putchr(file, *pos);
1238 break;
1239 }
1240 }
1241 }
1242
1243 /* the suffix */
1244 if (idecode_expand_semantics)
1245 lf_print_insn_bits(file, expanded_bits);
1246}
1247
1248
1249static void
1250lf_print_idecode_table(lf *file,
1251 insn_table *entry)
1252{
1253 int can_assume_leaf;
1254 opcode_rules *opcode_rule;
1255
1256 /* have a look at the rule table, if all table rules follow all
1257 switch rules, I can assume that all end points are leaves */
1258 opcode_rule = opcode_table;
1259 while (opcode_rule != NULL
1260 && opcode_rule->use_switch)
1261 opcode_rule = opcode_rule->next;
1262 while (opcode_rule != NULL
1263 && opcode_rule->use_switch
1264 && opcode_rule->special_rule)
1265 opcode_rule = opcode_rule->next;
1266 can_assume_leaf = opcode_rule == NULL;
1267
1268 lf_printf(file, "{\n");
1269 lf_indent(file, +2);
1270 {
1271 lf_printf(file, "idecode_table_entry *table = ");
1272 lf_print_table_name(file, entry);
1273 lf_printf(file, ";\n");
1274 lf_printf(file, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
a983c8f0
MM
1275 i2target(hi_bit_nr, entry->opcode->first),
1276 i2target(hi_bit_nr, entry->opcode->last));
c143ef62
MM
1277 lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
1278 lf_printf(file, "while (1) {\n");
1279 lf_indent(file, +2);
1280 {
1dc7c0ed 1281 lf_printf(file, "/* nonzero mask -> another table */\n");
c143ef62
MM
1282 lf_printf(file, "while (table_entry->mask != 0) {\n");
1283 lf_indent(file, +2);
1284 {
1285 lf_printf(file, "table = ((idecode_table_entry*)\n");
1286 lf_printf(file, " table_entry->function_or_table);\n");
1287 lf_printf(file, "opcode = ((instruction & table_entry->mask)\n");
1288 lf_printf(file, " >> table_entry->shift);\n");
1289 lf_printf(file, "table_entry = table + opcode;\n");
1290 }
1291 lf_indent(file, -2);
1292 lf_printf(file, "}\n");
1dc7c0ed
MM
1293 lf_printf(file, "ASSERT(table_entry->mask == 0);\n");
1294 if (can_assume_leaf)
1295 lf_printf(file, "ASSERT(table_entry->shift == 0);\n");
1296 else {
1297 lf_printf(file, "if (table_entry->shift == 0)\n");
1298 lf_indent(file, +2);
c143ef62 1299 }
1dc7c0ed
MM
1300 if (idecode_cache) {
1301 lf_printf(file, "return (((idecode_crack*)\n");
1302 lf_printf(file, " table_entry->function_or_table)\n");
1303 lf_printf(file, " (%s));\n", cache_idecode_actual);
c143ef62
MM
1304 }
1305 else {
1dc7c0ed
MM
1306 lf_printf(file, "return (((idecode_semantic*)\n");
1307 lf_printf(file, " table_entry->function_or_table)\n");
1308 lf_printf(file, " (%s));\n", semantic_actual);
c143ef62
MM
1309 }
1310 if (!can_assume_leaf) {
1dc7c0ed
MM
1311 lf_indent(file, -2);
1312 lf_printf(file, "/* must be a boolean */\n");
c143ef62
MM
1313 lf_printf(file, "opcode = (instruction & table_entry->shift) != 0;\n");
1314 lf_printf(file, "table = ((idecode_table_entry*)\n");
1315 lf_printf(file, " table_entry->function_or_table);\n");
1316 lf_printf(file, "table_entry = table + opcode;\n");
1317 }
1318 }
1319 lf_indent(file, -2);
1320 lf_printf(file, "}\n");
1321 }
1322 lf_indent(file, -2);
1323 lf_printf(file, "}\n");
1324}
1325
1326
1327static void
1328lf_print_my_prefix(lf *file,
1329 table_entry *file_entry,
1330 int idecode)
1331{
45525d8d 1332 lf_printf(file, "const char *const my_prefix __attribute__((__unused__)) = \n");
c143ef62
MM
1333 lf_printf(file, " \"%s:%s:%s:%d\";\n",
1334 filter_filename (file_entry->file_name),
1335 (idecode ? "idecode" : "semantics"),
1336 file_entry->fields[insn_name],
1337 file_entry->line_nr);
45525d8d 1338 lf_printf(file, "const itable_index my_index __attribute__((__unused__)) = ");
4a0351ab
MM
1339 lf_print_function_name(file,
1340 file_entry->fields[insn_name],
1341 NULL,
1342 function_name_prefix_itable);
1343 lf_printf(file, ";\n");
c143ef62
MM
1344}
1345
1346
1347static void
1348lf_print_ptrace(lf *file,
1349 int idecode)
1350{
1351 lf_printf(file, "\n");
1352 lf_printf(file, "ITRACE(trace_%s, (\"\\n\"));\n",
1353 (idecode ? "idecode" : "semantics"));
1354}
1355
1356
1357/****************************************************************/
1358
1359typedef void leaf_handler
1360(insn_table *entry,
1361 void *data,
1362 int depth);
1363typedef void padding_handler
1364(insn_table *table,
1365 void *data,
1366 int depth,
1367 int opcode_nr);
1368
1369
1370static void
1371insn_table_traverse_tree(insn_table *table,
1372 void *data,
1373 int depth,
1374 leaf_handler *start,
1375 leaf_handler *leaf,
1376 leaf_handler *end,
1377 padding_handler *padding)
1378{
1379 insn_table *entry;
1380 int entry_nr;
1381
1382 ASSERT(table != NULL
1383 && table->opcode != NULL
1384 && table->nr_entries > 0
1385 && table->entries != 0);
1386
1387 if (start != NULL && depth >= 0)
1388 start(table, data, depth);
1389
1390 for (entry_nr = 0, entry = table->entries;
1391 entry_nr < (table->opcode->is_boolean
1392 ? 2
1393 : (1 << (table->opcode->last - table->opcode->first + 1)));
1394 entry_nr ++) {
1395 if (entry == NULL
1396 || (!table->opcode->is_boolean
1397 && entry_nr < entry->opcode_nr)) {
1398 if (padding != NULL && depth >= 0)
1399 padding(table, data, depth, entry_nr);
1400 }
1401 else {
1402 ASSERT(entry != NULL && (entry->opcode_nr == entry_nr
1403 || table->opcode->is_boolean));
1404 if (entry->opcode != NULL && depth != 0) {
1405 insn_table_traverse_tree(entry, data, depth+1,
1406 start, leaf, end, padding);
1407 }
1408 else if (depth >= 0) {
1409 if (leaf != NULL)
1410 leaf(entry, data, depth);
1411 }
1412 entry = entry->sibling;
1413 }
1414 }
1415 if (end != NULL && depth >= 0)
1416 end(table, data, depth);
1417}
1418
1419
1420typedef void function_handler
1421(insn_table *table,
1422 void *data,
1423 table_entry *function);
1424
1425static void
1426insn_table_traverse_function(insn_table *table,
1427 void *data,
1428 function_handler *leaf)
1429{
1430 insn *function;
1431 for (function = table->functions;
1432 function != NULL;
1433 function = function->next) {
1434 leaf(table, data, function->file_entry);
1435 }
1436}
1437
1438
1439typedef void insn_handler
1440(insn_table *table,
1441 void *data,
1442 insn *instruction);
1443
1444static void
1445insn_table_traverse_insn(insn_table *table,
1446 void *data,
1447 insn_handler *leaf)
1448{
1449 insn *instruction;
1450 for (instruction = table->insns;
1451 instruction != NULL;
1452 instruction = instruction->next) {
1453 leaf(table, data, instruction);
1454 }
1455}
1456
1457
1458static void
1459update_depth(insn_table *entry,
1460 void *data,
1461 int depth)
1462{
1463 int *max_depth = (int*)data;
1464 if (*max_depth < depth)
1465 *max_depth = depth;
1466}
1467
1468
1469static int
1470insn_table_depth(insn_table *table)
1471{
1472 int depth = 0;
1473 insn_table_traverse_tree(table,
1474 &depth,
1475 1,
1476 NULL, /*start*/
1477 update_depth,
1478 NULL, /*end*/
1479 NULL); /*padding*/
1480 return depth;
1481}
1482
1483
1484/****************************************************************/
1485
1486static void
1487dump_traverse_start(insn_table *table,
1488 void *data,
1489 int depth)
1490{
1491 dumpf(depth*2, "(%d\n", table->opcode_nr);
1492}
1493
1494static void
1495dump_traverse_leaf(insn_table *entry,
1496 void *data,
1497 int depth)
1498{
1499 ASSERT(entry->nr_entries == 0
1500 && entry->nr_insn == 1
1501 && entry->opcode == NULL);
1502 dumpf(depth*2, ".%d %s\n", entry->opcode_nr,
1503 entry->insns->file_entry->fields[insn_format]);
1504}
1505
1506static void
1507dump_traverse_end(insn_table *table,
1508 void *data,
1509 int depth)
1510{
1511 dumpf(depth*2, ")\n");
1512}
1513
1514static void
1515dump_traverse_padding(insn_table *table,
1516 void *data,
1517 int depth,
1518 int opcode_nr)
1519{
1520 dumpf(depth*2, ".<%d>\n", opcode_nr);
1521}
1522
1523
1524static void
1525dump_traverse(insn_table *table)
1526{
1527 insn_table_traverse_tree(table, NULL, 1,
1528 dump_traverse_start,
1529 dump_traverse_leaf,
1530 dump_traverse_end,
1531 dump_traverse_padding);
1532}
1533
1534
1535/****************************************************************/
1536
1537
1538static void
1dc7c0ed
MM
1539lf_print_semantic_function_header(lf *file,
1540 char *basename,
1541 insn_bits *expanded_bits,
1542 int is_function_definition,
1543 int is_inline_function)
c143ef62
MM
1544{
1545 lf_printf(file, "\n");
28816f45 1546 lf_printf(file, "STATIC_SEMANTICS unsigned_word ");
c143ef62
MM
1547 lf_print_function_name(file,
1548 basename,
1549 expanded_bits,
1550 function_name_prefix_semantics);
1dc7c0ed 1551 lf_printf(file, "\n(%s)",
c143ef62 1552 (idecode_cache ? cache_semantic_formal : semantic_formal));
1dc7c0ed
MM
1553 if (!is_function_definition)
1554 lf_printf(file, ";");
1555 lf_printf(file, "\n");
c143ef62
MM
1556}
1557
1558
1559static void
1560semantics_h_leaf(insn_table *entry,
1561 void *data,
1562 int depth)
1563{
1564 lf *file = (lf*)data;
1565 ASSERT(entry->nr_insn == 1);
1dc7c0ed
MM
1566 lf_print_semantic_function_header(file,
1567 entry->insns->file_entry->fields[insn_name],
1568 entry->expanded_bits,
1569 0/* isnt function definition*/,
1570 !idecode_cache && entry->parent->opcode_rule->use_switch);
c143ef62
MM
1571}
1572
1573static void
1574semantics_h_insn(insn_table *entry,
1575 void *data,
1576 insn *instruction)
1577{
1578 lf *file = (lf*)data;
1dc7c0ed
MM
1579 lf_print_semantic_function_header(file,
1580 instruction->file_entry->fields[insn_name],
1581 NULL,
1582 0/*isnt function definition*/,
1583 0/*isnt inline function*/);
c143ef62
MM
1584}
1585
1586static void
1587semantics_h_function(insn_table *entry,
1588 void *data,
1589 table_entry *function)
1590{
1591 lf *file = (lf*)data;
1592 if (function->fields[function_type] == NULL
1593 || function->fields[function_type][0] == '\0') {
1dc7c0ed
MM
1594 lf_print_semantic_function_header(file,
1595 function->fields[function_name],
1596 NULL,
1597 0/*isnt function definition*/,
1598 1/*is inline function*/);
c143ef62
MM
1599 }
1600 else {
1601 lf_printf(file, "\n");
1602 lf_printf(file, "INLINE_SEMANTICS %s %s\n(%s);\n",
1603 function->fields[function_type],
1604 function->fields[function_name],
1605 function->fields[function_param]);
1606 }
1607}
1608
1609
1610static void
1611gen_semantics_h(insn_table *table, lf *file)
1612{
1613
1614 lf_print_copyleft(file);
1615 lf_printf(file, "\n");
1616 lf_printf(file, "#ifndef _SEMANTICS_H_\n");
1617 lf_printf(file, "#define _SEMANTICS_H_\n");
1618 lf_printf(file, "\n");
1619 lf_printf(file, "#ifndef INLINE_SEMANTICS\n");
1620 lf_printf(file, "#define INLINE_SEMANTICS\n");
1621 lf_printf(file, "#endif\n");
1622 lf_printf(file, "\n");
28816f45
MM
1623 lf_printf(file, "#ifndef STATIC_SEMANTICS\n");
1624 lf_printf(file, "#define STATIC_SEMANTICS\n");
1625 lf_printf(file, "#endif\n");
1626 lf_printf(file, "\n");
c143ef62
MM
1627 lf_printf(file, "\n");
1628
1629 /* output a declaration for all functions */
1630 insn_table_traverse_function(table,
1631 file,
1632 semantics_h_function);
1633
1634 /* output a declaration for all instructions */
1635 if (idecode_expand_semantics)
1636 insn_table_traverse_tree(table,
1637 file,
1638 1,
1639 NULL, /* start */
1640 semantics_h_leaf, /* leaf */
1641 NULL, /* end */
1642 NULL); /* padding */
1643 else
1644 insn_table_traverse_insn(table,
1645 file,
1646 semantics_h_insn);
1647
1648 lf_printf(file, "\n");
1649 lf_printf(file, "#endif /* _SEMANTICS_H_ */\n");
1650
1651}
1652
1653/****************************************************************/
1654
1655typedef struct _icache_tree icache_tree;
1656struct _icache_tree {
1657 char *name;
1658 icache_tree *next;
1659 icache_tree *children;
1660};
1661
1662static icache_tree *
1663icache_tree_insert(icache_tree *tree,
1664 char *name)
1665{
1666 icache_tree *new_tree;
1667 /* find it */
1668 icache_tree **ptr_to_cur_tree = &tree->children;
1669 icache_tree *cur_tree = *ptr_to_cur_tree;
1670 while (cur_tree != NULL
1671 && strcmp(cur_tree->name, name) < 0) {
1672 ptr_to_cur_tree = &cur_tree->next;
1673 cur_tree = *ptr_to_cur_tree;
1674 }
1675 ASSERT(cur_tree == NULL
1676 || strcmp(cur_tree->name, name) >= 0);
1677 /* already in the tree */
1678 if (cur_tree != NULL
1679 && strcmp(cur_tree->name, name) == 0)
1680 return cur_tree;
1681 /* missing, insert it */
1682 ASSERT(cur_tree == NULL
1683 || strcmp(cur_tree->name, name) > 0);
1684 new_tree = ZALLOC(icache_tree);
1685 new_tree->name = name;
1686 new_tree->next = cur_tree;
1687 *ptr_to_cur_tree = new_tree;
1688 return new_tree;
1689}
1690
1691
1692static icache_tree *
1693insn_table_cache_fields(insn_table *table)
1694{
1695 icache_tree *tree = ZALLOC(icache_tree);
1696 insn *instruction;
1697 for (instruction = table->insns;
1698 instruction != NULL;
1699 instruction = instruction->next) {
1700 insn_field *field;
1701 icache_tree *form =
1702 icache_tree_insert(tree,
1703 instruction->file_entry->fields[insn_form]);
1704 for (field = instruction->fields->first;
1705 field != NULL;
1706 field = field->next) {
1707 if (field->is_string)
1708 icache_tree_insert(form, field->val_string);
1709 }
1710 }
1711 return tree;
1712}
1713
1714
1715
1716static void
1717gen_icache_h(icache_tree *tree,
1718 lf *file)
1719{
1720 lf_print_copyleft(file);
1721 lf_printf(file, "\n");
1722 lf_printf(file, "#ifndef _ICACHE_H_\n");
1723 lf_printf(file, "#define _ICACHE_H_\n");
1724 lf_printf(file, "\n");
1725 lf_printf(file, "#ifndef INLINE_ICACHE\n");
1726 lf_printf(file, "#define INLINE_ICACHE\n");
1727 lf_printf(file, "#endif\n");
1728 lf_printf(file, "\n");
1729
1730 lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1731 idecode_cache);
1732 lf_printf(file, "\n");
1733
1734 /* create an instruction cache if being used */
1735 if (idecode_cache) {
1736 icache_tree *form;
1737 lf_printf(file, "typedef struct _idecode_cache {\n");
1738 lf_printf(file, " unsigned_word address;\n");
1739 lf_printf(file, " void *semantic;\n");
1740 lf_printf(file, " union {\n");
1741 for (form = tree->children;
1742 form != NULL;
1743 form = form->next) {
1744 icache_tree *field;
1745 lf_printf(file, " struct {\n");
1746 for (field = form->children;
1747 field != NULL;
1748 field = field->next) {
1749 cache_rules *cache_rule;
1750 int found_rule = 0;
1751 for (cache_rule = cache_table;
1752 cache_rule != NULL;
1753 cache_rule = cache_rule->next) {
1754 if (strcmp(field->name, cache_rule->old_name) == 0) {
1755 found_rule = 1;
1756 if (cache_rule->new_name != NULL)
1757 lf_printf(file, " %s %s; /* %s */\n",
1758 (cache_rule->type == NULL
1759 ? "unsigned"
1760 : cache_rule->type),
1761 cache_rule->new_name,
1762 cache_rule->old_name);
1763 }
1764 }
1765 if (!found_rule)
1766 lf_printf(file, " unsigned %s;\n", field->name);
1767 }
1768 lf_printf(file, " } %s;\n", form->name);
1769 }
1770 lf_printf(file, " } crack;\n");
1771 lf_printf(file, "} idecode_cache;\n");
1772 }
1773 else {
1774 /* alernativly, since no cache, #define the fields to be
4220dcd6
MM
1775 extractions from the instruction variable. Emit a dummy
1776 definition for idecode_cache to allow model_issue to not
1777 be #ifdefed at the call level */
c143ef62
MM
1778 cache_rules *cache_rule;
1779 lf_printf(file, "\n");
4220dcd6
MM
1780 lf_printf(file, "typedef void idecode_cache;\n");
1781 lf_printf(file, "\n");
c143ef62
MM
1782 for (cache_rule = cache_table;
1783 cache_rule != NULL;
1784 cache_rule = cache_rule->next) {
1785 if (cache_rule->expression != NULL
1786 && strlen(cache_rule->expression) > 0)
1787 lf_printf(file, "#define %s %s\n",
1788 cache_rule->new_name, cache_rule->expression);
1789 }
1790 }
1791
1792 lf_printf(file, "\n");
1793 lf_printf(file, "#endif /* _ICACHE_H_ */\n");
1794}
1795
1796
1797
1798
1799/****************************************************************/
1800
1801
1802static void
1803lf_print_c_extraction(lf *file,
1804 insn *instruction,
1805 char *field_name,
1806 char *field_type,
1807 char *field_expression,
1808 insn_field *cur_field,
1809 insn_bits *bits,
1810 int get_value_from_cache,
1811 int put_value_in_cache)
1812{
1813 ASSERT(field_name != NULL);
1814 if (bits != NULL
1815 && (!bits->opcode->is_boolean || bits->value == 0)
1816 && strcmp(field_name, cur_field->val_string) == 0) {
1817 ASSERT(bits->field == cur_field);
1818 ASSERT(field_type == NULL);
1819 table_entry_lf_c_line_nr(file, instruction->file_entry);
45525d8d 1820 lf_printf(file, "const unsigned %s __attribute__((__unused__)) = ",
c143ef62
MM
1821 field_name);
1822 if (bits->opcode->last < bits->field->last)
1823 lf_printf(file, "%d;\n",
1824 bits->value << (bits->field->last - bits->opcode->last));
1825 else
1826 lf_printf(file, "%d;\n", bits->value);
1827 }
f2181eff
MM
1828 else if (get_value_from_cache && !put_value_in_cache
1829 && semantics_use_cache_struct) {
1830 insn_undef *undef = ZALLOC(insn_undef);
1831 /* Use #define to reference the cache struct directly, rather than putting
1832 them into local variables */
1833 lf_indent_suppress(file);
1834 lf_printf(file, "#define %s (cache_entry->crack.%s.%s)\n",
1835 field_name,
1836 instruction->file_entry->fields[insn_form],
1837 field_name);
1838
1839 if (first_undef)
1840 last_undef->next = undef;
1841 else
1842 first_undef = undef;
1843 last_undef = undef;;
1844 undef->name = field_name;
1845 }
c143ef62
MM
1846 else {
1847 /* put the field in the local variable */
1848 table_entry_lf_c_line_nr(file, instruction->file_entry);
45525d8d 1849 lf_printf(file, "%s const %s __attribute__((__unused__)) = ",
c143ef62
MM
1850 field_type == NULL ? "unsigned" : field_type,
1851 field_name);
1852 /* getting it from the cache */
1853 if (get_value_from_cache || put_value_in_cache) {
1854 lf_printf(file, "cache_entry->crack.%s.%s",
1855 instruction->file_entry->fields[insn_form],
1856 field_name);
1857 if (put_value_in_cache) /* also put it in the cache? */
1858 lf_printf(file, " = ");
1859 }
1860 if (!get_value_from_cache) {
1861 if (strcmp(field_name, cur_field->val_string) == 0)
1862 lf_printf(file, "EXTRACTED32(instruction, %d, %d)",
a983c8f0
MM
1863 i2target(hi_bit_nr, cur_field->first),
1864 i2target(hi_bit_nr, cur_field->last));
c143ef62
MM
1865 else if (field_expression != NULL)
1866 lf_printf(file, "%s", field_expression);
1867 else
1868 lf_printf(file, "eval_%s", field_name);
1869 }
1870 lf_printf(file, ";\n");
1871 }
1872}
1873
1874
1875static void
1876lf_print_c_extractions(lf *file,
1877 insn *instruction,
1878 insn_bits *expanded_bits,
1879 int get_value_from_cache,
1880 int put_value_in_cache)
1881{
1882 insn_field *cur_field;
1883
1884 /* extract instruction fields */
1885 lf_printf(file, "/* extraction: %s */\n",
1886 instruction->file_entry->fields[insn_format]);
1887
1888 for (cur_field = instruction->fields->first;
1889 cur_field->first < insn_size;
1890 cur_field = cur_field->next) {
1891 if (cur_field->is_string) {
1892 insn_bits *bits;
1893 int found_rule = 0;
1894 /* find any corresponding value */
1895 for (bits = expanded_bits;
1896 bits != NULL;
1897 bits = bits->last) {
1898 if (bits->field == cur_field)
1899 break;
1900 }
1901 /* try the cache rule table for what to do */
1902 if (get_value_from_cache || put_value_in_cache) {
1903 cache_rules *cache_rule;
1904 for (cache_rule = cache_table;
1905 cache_rule != NULL;
1906 cache_rule = cache_rule->next) {
1907 if (strcmp(cur_field->val_string, cache_rule->old_name) == 0) {
1908 found_rule = 1;
1909 if (cache_rule->valid > 1 && put_value_in_cache)
1910 lf_print_c_extraction(file,
1911 instruction,
1912 cache_rule->new_name,
1913 cache_rule->type,
1914 cache_rule->expression,
1915 cur_field,
1916 bits,
1917 0,
1918 0);
1919 else if (cache_rule->valid == 1)
1920 lf_print_c_extraction(file,
1921 instruction,
1922 cache_rule->new_name,
1923 cache_rule->type,
1924 cache_rule->expression,
1925 cur_field,
1926 bits,
1927 get_value_from_cache,
1928 put_value_in_cache);
1929 }
1930 }
1931 }
1932 if (found_rule == 0)
1933 lf_print_c_extraction(file,
1934 instruction,
1935 cur_field->val_string,
1936 0,
1937 0,
1938 cur_field,
1939 bits,
1940 get_value_from_cache,
1941 put_value_in_cache);
1942 /* if any (XXX == 0), output a corresponding test */
1943 if (instruction->file_entry->annex != NULL) {
1944 char *field_name = cur_field->val_string;
1945 char *is_0_ptr = instruction->file_entry->annex;
1946 int field_len = strlen(field_name);
1947 if (strlen(is_0_ptr) >= (strlen("_is_0") + field_len)) {
1948 is_0_ptr += field_len;
1949 while ((is_0_ptr = strstr(is_0_ptr, "_is_0")) != NULL) {
1950 if (strncmp(is_0_ptr - field_len, field_name, field_len) == 0
1951 && !isalpha(is_0_ptr[ - field_len - 1])) {
1952 table_entry_lf_c_line_nr(file, instruction->file_entry);
45525d8d 1953 lf_printf(file, "const unsigned %s_is_0 __attribute__((__unused__)) = (", field_name);
c143ef62
MM
1954 if (bits != NULL)
1955 lf_printf(file, "%d", bits->value);
1956 else
1957 lf_printf(file, "%s", field_name);
1958 lf_printf(file, " == 0);\n");
1959 break;
1960 }
1961 is_0_ptr += strlen("_is_0");
1962 }
1963 }
1964 }
1965 /* any thing else ... */
1966 }
1967 }
1968 lf_print_lf_c_line_nr(file);
1969}
1970
1971
1972static void
1973lf_print_idecode_illegal(lf *file)
1974{
1975 if (idecode_cache)
1976 lf_printf(file, "return idecode_illegal(%s);\n", cache_idecode_actual);
1977 else
1978 lf_printf(file, "return semantic_illegal(%s);\n", semantic_actual);
1979}
1980
1981
1982static void
1983lf_print_idecode_floating_point_unavailable(lf *file)
1984{
1985 if (idecode_cache)
1986 lf_printf(file, "return idecode_floating_point_unavailable(%s);\n",
1987 cache_idecode_actual);
1988 else
1989 lf_printf(file, "return semantic_floating_point_unavailable(%s);\n",
1990 semantic_actual);
1991}
1992
1993
1994/* Output code to do any final checks on the decoded instruction.
1995 This includes things like verifying any on decoded fields have the
1996 correct value and checking that (for floating point) floating point
1997 hardware isn't disabled */
1998
1999static void
2000lf_print_c_validate(lf *file,
2001 insn *instruction,
2002 opcode_field *opcodes)
2003{
2004 /* Validate: unchecked instruction fields
2005
2006 If any constant fields in the instruction were not checked by the
2007 idecode tables, output code to check that they have the correct
2008 value here */
2009 {
2010 unsigned check_mask = 0;
2011 unsigned check_val = 0;
2012 insn_field *field;
2013 opcode_field *opcode;
2014
2015 /* form check_mask/check_val containing what needs to be checked
2016 in the instruction */
2017 for (field = instruction->fields->first;
2018 field->first < insn_size;
2019 field = field->next) {
2020
2021 check_mask <<= field->width;
2022 check_val <<= field->width;
2023
2024 /* is it a constant that could need validating? */
2025 if (!field->is_int && !field->is_slash)
2026 continue;
2027
2028 /* has it been checked by a table? */
2029 for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
2030 if (field->first >= opcode->first
2031 && field->last <= opcode->last)
2032 break;
2033 }
2034 if (opcode != NULL)
2035 continue;
2036
2037 check_mask |= (1 << field->width)-1;
2038 check_val |= field->val_int;
2039 }
2040
2041 /* if any bits not checked by opcode tables, output code to check them */
2042 if (check_mask) {
2043 lf_printf(file, "\n");
2044 lf_printf(file, "/* validate: %s */\n",
2045 instruction->file_entry->fields[insn_format]);
a3114052 2046 lf_printf(file, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
c143ef62
MM
2047 check_mask, check_val);
2048 lf_indent(file, +2);
2049 lf_print_idecode_illegal(file);
2050 lf_indent(file, -2);
2051 }
2052 }
2053
2054 /* Validate floating point hardware
2055
2056 If the simulator is being built with out floating point hardware
2057 (different to it being disabled in the MSR) then floating point
2058 instructions are invalid */
2059 {
2060 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2061 lf_printf(file, "\n");
2062 lf_printf(file, "/* Validate: FP hardware exists */\n");
2063 lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
2064 lf_indent(file, +2);
2065 lf_print_idecode_illegal(file);
2066 lf_indent(file, -2);
2067 }
2068 }
2069
2070 /* Validate: Floating Point available
2071
2072 If floating point is not available, we enter a floating point
2073 unavailable interrupt into the cache instead of the instruction
2074 proper.
2075
2076 The PowerPC spec requires a CSI after MSR[FP] is changed and when
2077 ever a CSI occures we flush the instruction cache. */
2078
2079 {
2080 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2081 lf_printf(file, "\n");
2082 lf_printf(file, "/* Validate: FP available according to MSR[FP] */\n");
2083 lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n");
2084 lf_indent(file, +2);
2085 lf_print_idecode_floating_point_unavailable(file);
2086 lf_indent(file, -2);
2087 }
2088 }
2089}
2090
2091
2092static void
2093lf_print_c_cracker(lf *file,
2094 insn *instruction,
2095 insn_bits *expanded_bits,
2096 opcode_field *opcodes)
2097{
2098
2099 /* function header */
2100 lf_printf(file, "{\n");
2101 lf_indent(file, +2);
2102
2103 lf_print_my_prefix(file,
2104 instruction->file_entry,
2105 1/*putting-value-in-cache*/);
2106
2107 lf_print_ptrace(file,
2108 1/*putting-value-in-cache*/);
2109
2110 lf_print_c_validate(file, instruction, opcodes);
2111
2112 lf_printf(file, "\n");
2113 lf_printf(file, "{\n");
2114 lf_indent(file, +2);
2115 lf_print_c_extractions(file,
2116 instruction,
2117 expanded_bits,
2118 0/*get_value_from_cache*/,
2119 1/*put_value_in_cache*/);
2120 lf_indent(file, -2);
2121 lf_printf(file, "}\n");
2122
2123 /* return the function propper (main sorts this one out) */
2124 lf_printf(file, "\n");
2125 lf_printf(file, "/* semantic routine */\n");
2126 table_entry_lf_c_line_nr(file, instruction->file_entry);
2127 lf_printf(file, "return ");
2128 lf_print_function_name(file,
2129 instruction->file_entry->fields[insn_name],
2130 expanded_bits,
2131 function_name_prefix_semantics);
2132 lf_printf(file, ";\n");
2133
2134 lf_print_lf_c_line_nr(file);
2135 lf_indent(file, -2);
2136 lf_printf(file, "}\n");
2137}
2138
2139
2140static void
2141lf_print_c_semantic(lf *file,
2142 insn *instruction,
2143 insn_bits *expanded_bits,
2144 opcode_field *opcodes)
2145{
2146
2147 lf_printf(file, "{\n");
2148 lf_indent(file, +2);
2149
2150 lf_print_my_prefix(file,
2151 instruction->file_entry,
2152 0/*not putting value in cache*/);
a983c8f0 2153 lf_printf(file, "unsigned_word nia = cia + %d;\n", insn_size / 8);
c143ef62
MM
2154
2155 lf_printf(file, "\n");
2156 lf_print_c_extractions(file,
2157 instruction,
2158 expanded_bits,
2159 idecode_cache/*get_value_from_cache*/,
2160 0/*put_value_in_cache*/);
2161
2162 lf_print_ptrace(file,
2163 0/*put_value_in_cache*/);
2164
2165 /* validate the instruction, if a cache this has already been done */
2166 if (!idecode_cache)
2167 lf_print_c_validate(file, instruction, opcodes);
2168
84bbbc35 2169 /* generate the profiling call - this is delayed until after the
c143ef62
MM
2170 instruction has been verified */
2171 lf_printf(file, "\n");
84bbbc35 2172 lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE) {\n");
c143ef62
MM
2173 lf_printf(file, " mon_issue(");
2174 lf_print_function_name(file,
2175 instruction->file_entry->fields[insn_name],
2176 NULL,
2177 function_name_prefix_itable);
2178 lf_printf(file, ", processor, cia);\n");
84bbbc35
MM
2179 lf_printf(file, "}\n");
2180 lf_printf(file, "\n");
c143ef62
MM
2181
2182 /* generate the code (or at least something */
2183 if (instruction->file_entry->annex != NULL) {
2184 /* true code */
2185 lf_printf(file, "\n");
2186 table_entry_lf_c_line_nr(file, instruction->file_entry);
2187 lf_printf(file, "{\n");
2188 lf_indent(file, +2);
2189 lf_print_c_code(file, instruction->file_entry->annex);
2190 lf_indent(file, -2);
2191 lf_printf(file, "}\n");
2192 lf_print_lf_c_line_nr(file);
2193 }
2194 else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
2195 lf_print_lf_c_line_nr(file);
2196 }
2197 else if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2198 /* unimplemented floating point instruction - call for assistance */
2199 lf_printf(file, "\n");
2200 lf_printf(file, "/* unimplemented floating point instruction - call for assistance */\n");
2201 table_entry_lf_c_line_nr(file, instruction->file_entry);
2202 lf_putstr(file, "floating_point_assist_interrupt(processor, cia);\n");
2203 lf_print_lf_c_line_nr(file);
2204 }
2205 else {
2206 /* abort so it is implemented now */
2207 table_entry_lf_c_line_nr(file, instruction->file_entry);
2208 lf_putstr(file, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2209 lf_print_lf_c_line_nr(file);
2210 lf_printf(file, "\n");
2211 }
2212
c143ef62
MM
2213 lf_printf(file, "return nia;\n");
2214 lf_indent(file, -2);
2215 lf_printf(file, "}\n");
2216}
2217
c143ef62
MM
2218static void
2219lf_print_c_semantic_function(lf *file,
2220 insn *instruction,
2221 insn_bits *expanded_bits,
1dc7c0ed
MM
2222 opcode_field *opcodes,
2223 int is_inline_function)
c143ef62 2224{
f2181eff 2225 insn_undef *undef, *next;
c143ef62
MM
2226
2227 /* build the semantic routine to execute the instruction */
1dc7c0ed
MM
2228 lf_print_semantic_function_header(file,
2229 instruction->file_entry->fields[insn_name],
2230 expanded_bits,
2231 1/*is-function-definition*/,
2232 is_inline_function);
c143ef62
MM
2233 lf_print_c_semantic(file,
2234 instruction,
2235 expanded_bits,
2236 opcodes);
f2181eff
MM
2237
2238 /* If we are referencing the cache structure directly instead of putting the values
2239 in local variables, undef any defines we created */
2240 for(undef = first_undef; undef; undef = next) {
2241 next = undef->next;
2242 lf_indent_suppress(file);
2243 lf_printf(file, "#undef %s\n", undef->name);
2244 free((void *)undef);
2245 }
2246 first_undef = (insn_undef *)0;
2247 last_undef = (insn_undef *)0;
c143ef62
MM
2248}
2249
2250
2251static void
2252semantics_c_leaf(insn_table *entry,
2253 void *data,
2254 int depth)
2255{
2256 lf *file = (lf*)data;
2257 ASSERT(entry->nr_insn == 1
2258 && entry->opcode == NULL
2259 && entry->parent != NULL
2260 && entry->parent->opcode != NULL);
2261 lf_print_c_semantic_function(file,
2262 entry->insns,
2263 entry->expanded_bits,
1dc7c0ed
MM
2264 entry->parent->opcode,
2265 !idecode_cache && entry->parent->opcode_rule->use_switch);
c143ef62
MM
2266}
2267
2268static void
2269semantics_c_insn(insn_table *table,
2270 void *data,
2271 insn *instruction)
2272{
2273 lf *file = (lf*)data;
2274 lf_print_c_semantic_function(file, instruction,
1dc7c0ed
MM
2275 NULL, NULL,
2276 0/*isnt_inline_function*/);
c143ef62
MM
2277}
2278
2279static void
2280semantics_c_function(insn_table *table,
2281 void *data,
2282 table_entry *function)
2283{
2284 lf *file = (lf*)data;
2285 if (function->fields[function_type] == NULL
2286 || function->fields[function_type][0] == '\0') {
1dc7c0ed
MM
2287 lf_print_semantic_function_header(file,
2288 function->fields[function_name],
2289 NULL,
2290 1/*is function definition*/,
2291 1/*is inline function*/);
c143ef62
MM
2292 }
2293 else {
2294 lf_printf(file, "\n");
2295 lf_printf(file, "INLINE_SEMANTICS %s\n%s(%s)\n",
2296 function->fields[function_type],
2297 function->fields[function_name],
2298 function->fields[function_param]);
2299 }
2300 table_entry_lf_c_line_nr(file, function);
2301 lf_printf(file, "{\n");
2302 lf_indent(file, +2);
2303 lf_print_c_code(file, function->annex);
2304 lf_indent(file, -2);
2305 lf_printf(file, "}\n");
2306 lf_print_lf_c_line_nr(file);
2307}
2308
2309
2310
2311static void
2312gen_semantics_c(insn_table *table, lf *file)
2313{
2314 lf_print_copyleft(file);
2315 lf_printf(file, "\n");
2316 lf_printf(file, "#ifndef _SEMANTICS_C_\n");
2317 lf_printf(file, "#define _SEMANTICS_C_\n");
2318 lf_printf(file, "\n");
2319 lf_printf(file, "#ifndef STATIC_INLINE_SEMANTICS\n");
2320 lf_printf(file, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2321 lf_printf(file, "#endif\n");
2322 lf_printf(file, "\n");
2323 lf_printf(file, "#include \"cpu.h\"\n");
2324 lf_printf(file, "#include \"idecode.h\"\n");
2325 lf_printf(file, "#include \"semantics.h\"\n");
2326 lf_printf(file, "\n");
2327
2328 /* output a definition (c-code) for all functions */
2329 insn_table_traverse_function(table,
2330 file,
2331 semantics_c_function);
2332
2333 /* output a definition (c-code) for all instructions */
2334 if (idecode_expand_semantics)
2335 insn_table_traverse_tree(table,
2336 file,
2337 1,
2338 NULL, /* start */
2339 semantics_c_leaf,
2340 NULL, /* end */
2341 NULL); /* padding */
2342 else
2343 insn_table_traverse_insn(table,
2344 file,
2345 semantics_c_insn);
2346
2347 lf_printf(file, "\n");
2348 lf_printf(file, "#endif /* _SEMANTICS_C_ */\n");
2349}
2350
2351
2352/****************************************************************/
2353
2354static void
2355gen_idecode_h(insn_table *table, lf *file)
2356{
2357 lf_print_copyleft(file);
2358 lf_printf(file, "\n");
2359 lf_printf(file, "#ifndef _IDECODE_H_\n");
2360 lf_printf(file, "#define _IDECODE_H_\n");
2361 lf_printf(file, "\n");
2362 lf_printf(file, "#ifndef INLINE_IDECODE\n");
2363 lf_printf(file, "#define INLINE_IDECODE\n");
2364 lf_printf(file, "#endif\n");
2365 lf_printf(file, "\n");
2366 lf_printf(file, "#include \"idecode_expression.h\"\n");
2367 lf_printf(file, "#include \"idecode_fields.h\"\n");
2368 lf_printf(file, "#include \"idecode_branch.h\"\n");
2369 lf_printf(file, "\n");
2370 lf_printf(file, "#include \"icache.h\"\n");
2371 lf_printf(file, "\n");
2372 lf_printf(file, "typedef unsigned_word idecode_semantic\n(%s);\n",
2373 (idecode_cache ? cache_semantic_formal : semantic_formal));
2374 lf_printf(file, "\n");
2375 if (idecode_cache)
2376 lf_printf(file, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2377 cache_idecode_formal);
2378 else
2379 lf_printf(file, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2380 semantic_formal);
2381 lf_printf(file, "\n");
2382 lf_printf(file, "#endif /* _IDECODE_H_ */\n");
2383}
2384
2385
2386/****************************************************************/
2387
2388
2389static void
2390idecode_table_start(insn_table *table,
2391 void *data,
2392 int depth)
2393{
2394 lf *file = (lf*)data;
2395 ASSERT(depth == 0);
2396 /* start of the table */
2397 if (!table->opcode_rule->use_switch) {
2398 lf_printf(file, "\n");
2399 lf_printf(file, "static idecode_table_entry ");
2400 lf_print_table_name(file, table);
2401 lf_printf(file, "[] = {\n");
2402 }
2403}
2404
2405static void
2406idecode_table_leaf(insn_table *entry,
2407 void *data,
2408 int depth)
2409{
2410 lf *file = (lf*)data;
2411 ASSERT(entry->parent != NULL);
2412 ASSERT(depth == 0);
2413
2414 /* add an entry to the table */
2415 if (!entry->parent->opcode_rule->use_switch) {
2416 if (entry->opcode == NULL) {
2417 /* table leaf entry */
2418 lf_printf(file, " /*%d*/ { 0, 0, ", entry->opcode_nr);
2419 lf_print_function_name(file,
2420 entry->insns->file_entry->fields[insn_name],
2421 entry->expanded_bits,
2422 (idecode_cache
2423 ? function_name_prefix_idecode
2424 : function_name_prefix_semantics));
2425 lf_printf(file, " },\n");
2426 }
2427 else if (entry->opcode_rule->use_switch) {
2428 /* table calling switch statement */
1dc7c0ed 2429 lf_printf(file, " /*%d*/ { 0, 0, ",
c143ef62
MM
2430 entry->opcode_nr);
2431 lf_print_table_name(file, entry);
2432 lf_printf(file, " },\n");
2433 }
2434 else {
2435 /* table `calling' another table */
2436 lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
2437 if (entry->opcode->is_boolean)
2438 lf_printf(file, "MASK32(%d,%d), 0, ",
a983c8f0
MM
2439 i2target(hi_bit_nr, entry->opcode->first),
2440 i2target(hi_bit_nr, entry->opcode->last));
c143ef62
MM
2441 else
2442 lf_printf(file, "%d, MASK32(%d,%d), ",
2443 insn_size - entry->opcode->last - 1,
a983c8f0
MM
2444 i2target(hi_bit_nr, entry->opcode->first),
2445 i2target(hi_bit_nr, entry->opcode->last));
c143ef62
MM
2446 lf_print_table_name(file, entry);
2447 lf_printf(file, " },\n");
2448 }
2449 }
2450}
2451
2452static void
2453idecode_table_end(insn_table *table,
2454 void *data,
2455 int depth)
2456{
2457 lf *file = (lf*)data;
2458 ASSERT(depth == 0);
2459
2460 if (!table->opcode_rule->use_switch) {
2461 lf_printf(file, "};\n");
2462 }
2463}
2464
2465static void
2466idecode_table_padding(insn_table *table,
2467 void *data,
2468 int depth,
2469 int opcode_nr)
2470{
2471 lf *file = (lf*)data;
2472 ASSERT(depth == 0);
2473
2474 if (!table->opcode_rule->use_switch) {
2475 lf_printf(file, " /*%d*/ { 0, 0, %s_illegal },\n",
2476 opcode_nr, (idecode_cache ? "idecode" : "semantic"));
2477 }
2478}
2479
2480
2481/****************************************************************/
2482
2483
2484void lf_print_idecode_switch
2485(lf *file,
2486 insn_table *table);
2487
2488
2489static void
2490idecode_switch_start(insn_table *table,
2491 void *data,
2492 int depth)
2493{
2494 lf *file = (lf*)data;
2495 ASSERT(depth == 0);
2496 ASSERT(table->opcode_rule->use_switch);
2497
2498 lf_printf(file, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
a983c8f0
MM
2499 i2target(hi_bit_nr, table->opcode->first),
2500 i2target(hi_bit_nr, table->opcode->last));
c143ef62
MM
2501}
2502
2503
2504static void
2505idecode_switch_leaf(insn_table *entry,
2506 void *data,
2507 int depth)
2508{
2509 lf *file = (lf*)data;
2510 ASSERT(entry->parent != NULL);
2511 ASSERT(depth == 0);
2512 ASSERT(entry->parent->opcode_rule->use_switch);
1dc7c0ed 2513 ASSERT(entry->parent->opcode);
c143ef62 2514
1dc7c0ed
MM
2515 if (!entry->parent->opcode->is_boolean
2516 || entry->opcode_nr == 0)
2517 lf_printf(file, "case %d:\n", entry->opcode_nr);
2518 else
2519 lf_printf(file, "default:\n");
c143ef62
MM
2520 lf_indent(file, +2);
2521 {
2522 if (entry->opcode == NULL) {
2523 /* switch calling leaf */
2524 lf_printf(file, "return ");
2525 lf_print_function_name(file,
2526 entry->insns->file_entry->fields[insn_name],
2527 entry->expanded_bits,
2528 (idecode_cache
2529 ? function_name_prefix_idecode
2530 : function_name_prefix_semantics));
2531 if (idecode_cache)
2532 lf_printf(file, "(%s);\n", cache_idecode_actual);
2533 else
2534 lf_printf(file, "(%s);\n", semantic_actual);
2535 }
2536 else if (entry->opcode_rule->use_switch) {
2537 /* switch calling switch */
2538 lf_print_idecode_switch(file, entry);
2539 }
2540 else {
1dc7c0ed 2541 /* switch looking up a table */
c143ef62
MM
2542 lf_print_idecode_table(file, entry);
2543 }
2544 lf_printf(file, "break;\n");
2545 }
2546 lf_indent(file, -2);
2547}
2548
2549
2550static void
2551lf_print_idecode_switch_illegal(lf *file)
2552{
2553 lf_indent(file, +2);
2554 lf_print_idecode_illegal(file);
2555 lf_printf(file, "break;\n");
2556 lf_indent(file, -2);
2557}
2558
2559static void
2560idecode_switch_end(insn_table *table,
2561 void *data,
2562 int depth)
2563{
2564 lf *file = (lf*)data;
2565 ASSERT(depth == 0);
2566 ASSERT(table->opcode_rule->use_switch);
1dc7c0ed 2567 ASSERT(table->opcode);
c143ef62 2568
1dc7c0ed
MM
2569 if (table->opcode_rule->use_switch == 1
2570 && !table->opcode->is_boolean) {
c143ef62
MM
2571 lf_printf(file, "default:\n");
2572 lf_print_idecode_switch_illegal(file);
2573 }
2574 lf_printf(file, "}\n");
2575}
2576
2577static void
2578idecode_switch_padding(insn_table *table,
2579 void *data,
2580 int depth,
2581 int opcode_nr)
2582{
2583 lf *file = (lf*)data;
2584
2585 ASSERT(depth == 0);
2586 ASSERT(table->opcode_rule->use_switch);
2587
2588 if (table->opcode_rule->use_switch > 1) {
2589 lf_printf(file, "case %d:\n", opcode_nr);
2590 lf_print_idecode_switch_illegal(file);
2591 }
2592}
2593
2594
2595void
2596lf_print_idecode_switch(lf *file,
2597 insn_table *table)
2598{
2599 insn_table_traverse_tree(table,
2600 file,
2601 0,
2602 idecode_switch_start,
2603 idecode_switch_leaf,
2604 idecode_switch_end,
2605 idecode_switch_padding);
2606}
2607
2608
1dc7c0ed
MM
2609static void
2610lf_print_idecode_switch_function_header(lf *file,
2611 insn_table *table,
2612 int is_function_definition)
2613{
2614 lf_printf(file, "\n");
2615 lf_printf(file, "static ");
2616 if (idecode_cache)
2617 lf_printf(file, "idecode_semantic *");
2618 else
2619 lf_printf(file, "unsigned_word");
2620 if (is_function_definition)
2621 lf_printf(file, "\n");
2622 else
2623 lf_printf(file, " ");
2624 lf_print_table_name(file, table);
2625 lf_printf(file, "\n(%s)",
2626 (idecode_cache ? cache_idecode_formal : semantic_formal));
2627 if (!is_function_definition)
2628 lf_printf(file, ";");
2629 lf_printf(file, "\n");
2630}
2631
2632
2633static void
2634idecode_declare_if_switch(insn_table *table,
2635 void *data,
2636 int depth)
2637{
2638 lf *file = (lf*)data;
2639
2640 if (table->opcode_rule->use_switch
2641 && table->parent != NULL /* don't declare the top one yet */
2642 && !table->parent->opcode_rule->use_switch) {
2643 lf_print_idecode_switch_function_header(file,
2644 table,
2645 0/*isnt function definition*/);
2646 }
2647}
2648
2649
c143ef62
MM
2650static void
2651idecode_expand_if_switch(insn_table *table,
2652 void *data,
2653 int depth)
2654{
2655 lf *file = (lf*)data;
2656
2657 if (table->opcode_rule->use_switch
2658 && table->parent != NULL /* don't expand the top one yet */
2659 && !table->parent->opcode_rule->use_switch) {
1dc7c0ed
MM
2660 lf_print_idecode_switch_function_header(file,
2661 table,
2662 1/*is function definition*/);
c143ef62
MM
2663 lf_printf(file, "{\n");
2664 {
2665 lf_indent(file, +2);
2666 lf_print_idecode_switch(file, table);
2667 lf_indent(file, -2);
2668 }
2669 lf_printf(file, "}\n");
2670 }
2671}
2672
2673
2674static void
2675lf_print_c_cracker_function(lf *file,
2676 insn *instruction,
2677 insn_bits *expanded_bits,
1dc7c0ed
MM
2678 opcode_field *opcodes,
2679 int is_inline_function)
c143ef62
MM
2680{
2681 /* if needed, generate code to enter this routine into a cache */
2682 lf_printf(file, "\n");
28816f45 2683 lf_printf(file, "STATIC_IDECODE idecode_semantic *\n");
c143ef62
MM
2684 lf_print_function_name(file,
2685 instruction->file_entry->fields[insn_name],
2686 expanded_bits,
2687 function_name_prefix_idecode);
2688 lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2689
2690 lf_print_c_cracker(file,
2691 instruction,
2692 expanded_bits,
2693 opcodes);
2694}
2695
2696static void
2697idecode_crack_leaf(insn_table *entry,
2698 void *data,
2699 int depth)
2700{
2701 lf *file = (lf*)data;
2702 ASSERT(entry->nr_insn == 1
2703 && entry->opcode == NULL
2704 && entry->parent != NULL
1dc7c0ed
MM
2705 && entry->parent->opcode != NULL
2706 && entry->parent->opcode_rule != NULL);
c143ef62
MM
2707 lf_print_c_cracker_function(file,
2708 entry->insns,
2709 entry->expanded_bits,
1dc7c0ed
MM
2710 entry->opcode,
2711 entry->parent->opcode_rule->use_switch);
c143ef62
MM
2712}
2713
2714static void
2715idecode_crack_insn(insn_table *entry,
2716 void *data,
2717 insn *instruction)
2718{
2719 lf *file = (lf*)data;
2720 lf_print_c_cracker_function(file,
2721 instruction,
2722 NULL,
1dc7c0ed
MM
2723 NULL,
2724 0/*isnt inline function*/);
c143ef62
MM
2725}
2726
2727static void
2728idecode_c_internal_function(insn_table *table,
2729 void *data,
2730 table_entry *function)
2731{
2732 lf *file = (lf*)data;
2733 ASSERT(idecode_cache != 0);
2734 if (it_is("internal", function->fields[insn_flags])) {
2735 lf_printf(file, "\n");
2736 lf_printf(file, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2737 lf_print_function_name(file,
2738 function->fields[insn_name],
2739 NULL,
2740 function_name_prefix_idecode);
2741 lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2742 lf_printf(file, "{\n");
2743 lf_indent(file, +2);
2744 lf_printf(file, "/* semantic routine */\n");
2745 table_entry_lf_c_line_nr(file, function);
2746 lf_printf(file, "return ");
2747 lf_print_function_name(file,
2748 function->fields[insn_name],
2749 NULL,
2750 function_name_prefix_semantics);
2751 lf_printf(file, ";\n");
2752
2753 lf_print_lf_c_line_nr(file);
2754 lf_indent(file, -2);
2755 lf_printf(file, "}\n");
2756 }
2757}
2758
2759
2760/****************************************************************/
2761
2762static void
2763gen_idecode_c(insn_table *table, lf *file)
2764{
2765 int depth;
2766
2767 /* the intro */
2768 lf_print_copyleft(file);
2769 lf_printf(file, "\n");
2770 lf_printf(file, "\n");
2771 lf_printf(file, "#ifndef _IDECODE_C_\n");
2772 lf_printf(file, "#define _IDECODE_C_\n");
2773 lf_printf(file, "\n");
2774 lf_printf(file, "#ifndef STATIC_INLINE_IDECODE\n");
2775 lf_printf(file, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2776 lf_printf(file, "#endif\n");
2777 lf_printf(file, "\n");
28816f45
MM
2778 lf_printf(file, "#ifndef STATIC_IDECODE\n");
2779 lf_printf(file, "#define STATIC_IDECODE\n");
2780 lf_printf(file, "#endif\n");
2781 lf_printf(file, "\n");
c143ef62
MM
2782 lf_printf(file, "#include \"cpu.h\"\n");
2783 lf_printf(file, "#include \"idecode.h\"\n");
2784 lf_printf(file, "#include \"semantics.h\"\n");
2785 lf_printf(file, "\n");
2786 lf_printf(file, "\n");
2787 lf_printf(file, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2788 (idecode_cache ? cache_idecode_formal : semantic_formal));
2789 lf_printf(file, "\n");
2790 lf_printf(file, "typedef struct _idecode_table_entry {\n");
2791 lf_printf(file, " unsigned shift;\n");
2792 lf_printf(file, " unsigned mask;\n");
2793 lf_printf(file, " void *function_or_table;\n");
2794 lf_printf(file, "} idecode_table_entry;\n");
2795 lf_printf(file, "\n");
2796 lf_printf(file, "\n");
2797
2798 /* output `internal' invalid/floating-point unavailable functions
2799 where needed */
2800 if (idecode_cache) {
2801 insn_table_traverse_function(table,
2802 file,
2803 idecode_c_internal_function);
2804 }
2805
2806 /* output cracking functions where needed */
2807 if (idecode_cache) {
2808 if (idecode_expand_semantics)
2809 insn_table_traverse_tree(table,
2810 file,
2811 1,
2812 NULL,
2813 idecode_crack_leaf,
2814 NULL,
2815 NULL);
2816 else
2817 insn_table_traverse_insn(table,
2818 file,
2819 idecode_crack_insn);
2820 }
2821
1dc7c0ed
MM
2822 /* output switch function declarations where needed by tables */
2823 insn_table_traverse_tree(table,
2824 file,
2825 1,
2826 idecode_declare_if_switch, /* START */
2827 NULL, NULL, NULL);
c143ef62
MM
2828
2829 /* output tables where needed */
2830 for (depth = insn_table_depth(table);
2831 depth > 0;
2832 depth--) {
2833 insn_table_traverse_tree(table,
2834 file,
2835 1-depth,
2836 idecode_table_start,
2837 idecode_table_leaf,
2838 idecode_table_end,
2839 idecode_table_padding);
2840 }
2841
2842 /* output switch functions where needed */
2843 insn_table_traverse_tree(table,
2844 file,
2845 1,
2846 idecode_expand_if_switch, /* START */
2847 NULL, NULL, NULL);
2848
2849 /* output the main idecode routine */
2850 lf_printf(file, "\n");
2851 if (idecode_cache)
2852 lf_printf(file, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2853 cache_idecode_formal);
2854 else
2855 lf_printf(file, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2856 semantic_formal);
2857 lf_printf(file, "{\n");
2858 lf_indent(file, +2);
2859 if (table->opcode_rule->use_switch)
2860 lf_print_idecode_switch(file, table);
2861 else
2862 lf_print_idecode_table(file, table);
2863 lf_indent(file, -2);
2864 lf_printf(file, "}\n");
2865 lf_printf(file, "\n");
1dc7c0ed 2866 lf_printf(file, "#endif /* _IDECODE_C_ */\n");
c143ef62
MM
2867}
2868
2869
2870/****************************************************************/
2871
2872static void
2873itable_h_insn(insn_table *entry,
2874 void *data,
2875 insn *instruction)
2876{
2877 lf *file = (lf*)data;
2878 lf_printf(file, " ");
2879 lf_print_function_name(file,
2880 instruction->file_entry->fields[insn_name],
2881 NULL,
2882 function_name_prefix_itable);
2883 lf_printf(file, ",\n");
2884}
2885
2886
2887static void
2888gen_itable_h(insn_table *table, lf *file)
2889{
2890
2891 lf_print_copyleft(file);
2892 lf_printf(file, "\n");
2893 lf_printf(file, "#ifndef _ITABLE_H_\n");
2894 lf_printf(file, "#define _ITABLE_H_\n");
2895 lf_printf(file, "\n");
2896 lf_printf(file, "#ifndef INLINE_ITABLE\n");
2897 lf_printf(file, "#define INLINE_ITABLE\n");
2898 lf_printf(file, "#endif\n");
2899 lf_printf(file, "\n");
2900 lf_printf(file, "\n");
2901
2902 /* output an enumerated type for each instruction */
2903 lf_printf(file, "typedef enum {\n");
2904 insn_table_traverse_insn(table,
2905 file,
2906 itable_h_insn);
2907 lf_printf(file, " nr_itable_entries,\n");
2908 lf_printf(file, "} itable_index;\n");
2909 lf_printf(file, "\n");
2910
2911 /* output the table that contains the actual instruction info */
2912 lf_printf(file, "typedef struct _itable_instruction_info {\n");
2913 lf_printf(file, " itable_index nr;\n");
2914 lf_printf(file, " char *format;\n");
2915 lf_printf(file, " char *form;\n");
2916 lf_printf(file, " char *flags;\n");
1dc7c0ed 2917 lf_printf(file, " char *mnemonic;\n");
c143ef62
MM
2918 lf_printf(file, " char *name;\n");
2919 lf_printf(file, "} itable_info;\n");
2920 lf_printf(file, "\n");
2921 lf_printf(file, "extern itable_info itable[nr_itable_entries];\n");
2922
2923 lf_printf(file, "\n");
2924 lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2925
2926}
2927
2928/****************************************************************/
2929
2930static void
2931itable_c_insn(insn_table *entry,
2932 void *data,
2933 insn *instruction)
2934{
2935 lf *file = (lf*)data;
2936 char **fields = instruction->file_entry->fields;
2937 lf_printf(file, " { ");
2938 lf_print_function_name(file,
2939 instruction->file_entry->fields[insn_name],
2940 NULL,
2941 function_name_prefix_itable);
2942 lf_printf(file, ",\n");
2943 lf_printf(file, " \"%s\",\n", fields[insn_format]);
2944 lf_printf(file, " \"%s\",\n", fields[insn_form]);
2945 lf_printf(file, " \"%s\",\n", fields[insn_flags]);
1dc7c0ed 2946 lf_printf(file, " \"%s\",\n", fields[insn_mnemonic]);
c143ef62
MM
2947 lf_printf(file, " \"%s\",\n", fields[insn_name]);
2948 lf_printf(file, " },\n");
2949}
2950
2951
2952static void
2953gen_itable_c(insn_table *table, lf *file)
2954{
2955
2956 lf_print_copyleft(file);
2957 lf_printf(file, "\n");
2958 lf_printf(file, "#ifndef _ITABLE_C_\n");
2959 lf_printf(file, "#define _ITABLE_C_\n");
2960 lf_printf(file, "\n");
2961 lf_printf(file, "#ifndef STATIC_INLINE_ITABLE\n");
2962 lf_printf(file, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2963 lf_printf(file, "#endif\n");
2964 lf_printf(file, "\n");
2965 lf_printf(file, "#include \"itable.h\"\n");
2966 lf_printf(file, "\n");
2967
2968 /* output the table that contains the actual instruction info */
2969 lf_printf(file, "itable_info itable[nr_itable_entries] = {\n");
2970 insn_table_traverse_insn(table,
2971 file,
2972 itable_c_insn);
2973 lf_printf(file, "};\n");
2974 lf_printf(file, "\n");
2975
2976 lf_printf(file, "\n");
2977 lf_printf(file, "#endif /* _ITABLE_C_ */\n");
a3114052
MM
2978}
2979
2980/****************************************************************/
2981
eb4ef197 2982static void
1dc7c0ed
MM
2983model_c_or_h_data(insn_table *table,
2984 lf *file,
2985 table_entry *data)
2986{
2987 if (data->annex) {
2988 table_entry_lf_c_line_nr(file, data);
2989 lf_print_c_code(file, data->annex);
2990 lf_print_lf_c_line_nr(file);
2991 lf_printf(file, "\n");
2992 }
2993}
2994
2995static void
2996model_c_or_h_function(insn_table *entry,
2997 lf *file,
2998 table_entry *function,
2999 char *prefix)
eb4ef197
MM
3000{
3001 if (function->fields[function_type] == NULL
3002 || function->fields[function_type][0] == '\0') {
1dc7c0ed 3003 error("Model function type not specified for %s", function->fields[function_name]);
eb4ef197
MM
3004 }
3005 else {
3006 lf_printf(file, "\n");
1dc7c0ed
MM
3007 lf_printf(file, "%s %s %s\n(%s);\n",
3008 prefix,
eb4ef197
MM
3009 function->fields[function_type],
3010 function->fields[function_name],
3011 function->fields[function_param]);
3012 }
1dc7c0ed 3013 lf_printf(file, "\n");
eb4ef197
MM
3014}
3015
a3114052
MM
3016static void
3017gen_model_h(insn_table *table, lf *file)
3018{
eb4ef197 3019 insn *insn_ptr;
a3114052 3020 model *model_ptr;
28816f45 3021 insn *macro;
80948f39
MM
3022 char *name;
3023 int model_create_p = 0;
3024 int model_init_p = 0;
3025 int model_halt_p = 0;
80948f39
MM
3026 int model_mon_info_p = 0;
3027 int model_mon_info_free_p = 0;
a3114052
MM
3028
3029 lf_print_copyleft(file);
3030 lf_printf(file, "\n");
3031 lf_printf(file, "#ifndef _MODEL_H_\n");
3032 lf_printf(file, "#define _MODEL_H_\n");
3033 lf_printf(file, "\n");
eb4ef197 3034
1dc7c0ed 3035 for(macro = model_macros; macro; macro = macro->next) {
ac79ccd4 3036 model_c_or_h_data(table, file, macro->file_entry);
eb4ef197
MM
3037 }
3038
a3114052
MM
3039 lf_printf(file, "#ifndef INLINE_MODEL\n");
3040 lf_printf(file, "#define INLINE_MODEL\n");
3041 lf_printf(file, "#endif\n");
28816f45
MM
3042 lf_printf(file, "#ifndef STATIC_INLINE_MODEL\n");
3043 lf_printf(file, "#define STATIC_INLINE_MODEL STATIC_INLINE\n");
3044 lf_printf(file, "#endif\n");
3045 lf_printf(file, "\n");
f35df46c
MM
3046 lf_printf(file, "#ifndef STATIC_MODEL\n");
3047 lf_printf(file, "#define STATIC_MODEL\n");
3048 lf_printf(file, "#endif\n");
3049 lf_printf(file, "\n");
39c32461
MM
3050 lf_printf(file, "#ifndef EXTERN_MODEL\n");
3051 lf_printf(file, "#define EXTERN_MODEL extern\n");
3052 lf_printf(file, "#endif\n");
a3114052
MM
3053 lf_printf(file, "\n");
3054
a3114052
MM
3055 lf_printf(file, "typedef enum _model_enum {\n");
3056 lf_printf(file, " MODEL_NONE,\n");
3057 for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3058 lf_printf(file, " MODEL_%s,\n", model_ptr->name);
3059 }
3060 lf_printf(file, " nr_models\n");
3061 lf_printf(file, "} model_enum;\n");
3062 lf_printf(file, "\n");
3063
28816f45
MM
3064 lf_printf(file, "#define DEFAULT_MODEL MODEL_%s\n", (models) ? models->name : "NONE");
3065 lf_printf(file, "\n");
3066
80948f39
MM
3067 lf_printf(file, "typedef struct _model_data model_data;\n");
3068 lf_printf(file, "typedef struct _model_time model_time;\n");
3069 lf_printf(file, "\n");
a3114052 3070
80948f39 3071 lf_printf(file, "extern model_enum current_model;\n");
39c32461
MM
3072 lf_printf(file, "EXTERN_MODEL const char *model_name[ (int)nr_models ];\n");
3073 lf_printf(file, "EXTERN_MODEL const char *const *const model_func_unit_name[ (int)nr_models ];\n");
3074 lf_printf(file, "EXTERN_MODEL const model_time *const model_time_mapping[ (int)nr_models ];\n");
28816f45 3075 lf_printf(file, "\n");
eb4ef197
MM
3076
3077 for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
1dc7c0ed 3078 model_c_or_h_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
80948f39
MM
3079 name = insn_ptr->file_entry->fields[function_name];
3080 if (strcmp (name, "model_create") == 0)
3081 model_create_p = 1;
3082 else if (strcmp (name, "model_init") == 0)
3083 model_init_p = 1;
3084 else if (strcmp (name, "model_halt") == 0)
3085 model_halt_p = 1;
80948f39
MM
3086 else if (strcmp (name, "model_mon_info") == 0)
3087 model_mon_info_p = 1;
3088 else if (strcmp (name, "model_mon_info_free") == 0)
3089 model_mon_info_free_p = 1;
3090 }
3091
3092 if (!model_create_p) {
3093 lf_printf(file, "INLINE_MODEL model_data *model_create\n");
3094 lf_printf(file, "(cpu *processor);\n");
3095 lf_printf(file, "\n");
3096 }
3097
3098 if (!model_init_p) {
3099 lf_printf(file, "INLINE_MODEL void model_init\n");
4220dcd6 3100 lf_printf(file, "(model_data *model_ptr);\n");
eb4ef197
MM
3101 lf_printf(file, "\n");
3102 }
3103
80948f39
MM
3104 if (!model_halt_p) {
3105 lf_printf(file, "INLINE_MODEL void model_halt\n");
4220dcd6 3106 lf_printf(file, "(model_data *model_ptr);\n");
80948f39
MM
3107 lf_printf(file, "\n");
3108 }
3109
80948f39
MM
3110 if (!model_mon_info_p) {
3111 lf_printf(file, "INLINE_MODEL model_print *model_mon_info\n");
3112 lf_printf(file, "(model_data *model_ptr);\n");
3113 lf_printf(file, "\n");
3114 }
3115
3116 if (!model_mon_info_free_p) {
3117 lf_printf(file, "INLINE_MODEL void model_mon_info_free\n");
3118 lf_printf(file, "(model_data *model_ptr,\n");
3119 lf_printf(file, " model_print *info_ptr);\n");
3120 lf_printf(file, "\n");
3121 }
3122
3123 lf_printf(file, "INLINE_MODEL void model_set\n");
3124 lf_printf(file, "(const char *name);\n");
a3114052
MM
3125 lf_printf(file, "\n");
3126 lf_printf(file, "#endif /* _MODEL_H_ */\n");
3127}
3128
3129/****************************************************************/
3130
1dc7c0ed
MM
3131typedef struct _model_c_passed_data model_c_passed_data;
3132struct _model_c_passed_data {
a3114052
MM
3133 lf *file;
3134 model *model_ptr;
3135};
3136
3137static void
3138model_c_insn(insn_table *entry,
3139 void *data,
3140 insn *instruction)
3141{
1dc7c0ed 3142 model_c_passed_data *data_ptr = (model_c_passed_data *)data;
a3114052 3143 lf *file = data_ptr->file;
80948f39 3144 char *current_name = data_ptr->model_ptr->printable_name;
a3114052 3145 table_model_entry *model_ptr = instruction->file_entry->model_first;
a3114052
MM
3146
3147 while (model_ptr) {
28816f45 3148 if (model_ptr->fields[insn_model_name] == current_name) {
845ff5a4
MM
3149 lf_printf(file, " { %-*s }, /* %s */\n",
3150 max_model_fields_len,
80948f39
MM
3151 model_ptr->fields[insn_model_fields],
3152 instruction->file_entry->fields[insn_name]);
a3114052
MM
3153 return;
3154 }
3155
3156 model_ptr = model_ptr->next;
3157 }
3158
845ff5a4
MM
3159 lf_printf(file, " { %-*s }, /* %s */\n",
3160 max_model_fields_len,
80948f39
MM
3161 data_ptr->model_ptr->insn_default,
3162 instruction->file_entry->fields[insn_name]);
a3114052
MM
3163}
3164
eb4ef197
MM
3165static void
3166model_c_function(insn_table *table,
3167 lf *file,
1dc7c0ed
MM
3168 table_entry *function,
3169 const char *prefix)
eb4ef197
MM
3170{
3171 if (function->fields[function_type] == NULL
3172 || function->fields[function_type][0] == '\0') {
1dc7c0ed 3173 error("Model function return type not specified for %s", function->fields[function_name]);
eb4ef197
MM
3174 }
3175 else {
3176 lf_printf(file, "\n");
1dc7c0ed
MM
3177 lf_printf(file, "%s %s\n%s(%s)\n",
3178 prefix,
eb4ef197
MM
3179 function->fields[function_type],
3180 function->fields[function_name],
3181 function->fields[function_param]);
3182 }
3183 table_entry_lf_c_line_nr(file, function);
3184 lf_printf(file, "{\n");
3185 if (function->annex) {
3186 lf_indent(file, +2);
3187 lf_print_c_code(file, function->annex);
3188 lf_indent(file, -2);
3189 }
3190 lf_printf(file, "}\n");
3191 lf_print_lf_c_line_nr(file);
1dc7c0ed 3192 lf_printf(file, "\n");
eb4ef197
MM
3193}
3194
a3114052
MM
3195static void
3196gen_model_c(insn_table *table, lf *file)
3197{
eb4ef197 3198 insn *insn_ptr;
a3114052 3199 model *model_ptr;
80948f39
MM
3200 char *name;
3201 int model_create_p = 0;
3202 int model_init_p = 0;
3203 int model_halt_p = 0;
80948f39
MM
3204 int model_mon_info_p = 0;
3205 int model_mon_info_free_p = 0;
a3114052
MM
3206
3207 lf_print_copyleft(file);
3208 lf_printf(file, "\n");
3209 lf_printf(file, "#ifndef _MODEL_C_\n");
3210 lf_printf(file, "#define _MODEL_C_\n");
3211 lf_printf(file, "\n");
a3114052 3212 lf_printf(file, "#include \"cpu.h\"\n");
80948f39
MM
3213 lf_printf(file, "#include \"mon.h\"\n");
3214 lf_printf(file, "\n");
3215 lf_printf(file, "#ifdef HAVE_STDLIB_H\n");
3216 lf_printf(file, "#include <stdlib.h>\n");
3217 lf_printf(file, "#endif\n");
a3114052
MM
3218 lf_printf(file, "\n");
3219
1dc7c0ed
MM
3220 for(insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) {
3221 model_c_or_h_data(table, file, insn_ptr->file_entry);
3222 }
3223
4a0351ab
MM
3224 for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
3225 model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_MODEL");
3226 }
3227
1dc7c0ed
MM
3228 for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
3229 model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
3230 }
3231
4a0351ab
MM
3232 for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
3233 model_c_function(table, file, insn_ptr->file_entry, "STATIC_MODEL");
3234 }
3235
1dc7c0ed
MM
3236 for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
3237 model_c_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
3238 }
3239
eb4ef197 3240 for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
1dc7c0ed 3241 model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
80948f39
MM
3242 name = insn_ptr->file_entry->fields[function_name];
3243 if (strcmp (name, "model_create") == 0)
3244 model_create_p = 1;
3245 else if (strcmp (name, "model_init") == 0)
3246 model_init_p = 1;
3247 else if (strcmp (name, "model_halt") == 0)
3248 model_halt_p = 1;
80948f39
MM
3249 else if (strcmp (name, "model_mon_info") == 0)
3250 model_mon_info_p = 1;
3251 else if (strcmp (name, "model_mon_info_free") == 0)
3252 model_mon_info_free_p = 1;
3253 }
3254
3255 if (!model_create_p) {
3256 lf_printf(file, "INLINE_MODEL model_data *model_create(cpu *processor)\n");
3257 lf_printf(file, "{\n");
3258 lf_printf(file, " return (model_data *)0;\n");
3259 lf_printf(file, "}\n");
3260 lf_printf(file, "\n");
eb4ef197
MM
3261 }
3262
80948f39 3263 if (!model_init_p) {
4220dcd6 3264 lf_printf(file, "INLINE_MODEL void model_init(model_data *model_ptr)\n");
80948f39
MM
3265 lf_printf(file, "{\n");
3266 lf_printf(file, "}\n");
3267 lf_printf(file, "\n");
3268 }
3269
3270 if (!model_halt_p) {
4220dcd6 3271 lf_printf(file, "INLINE_MODEL void model_halt(model_data *model_ptr)\n");
80948f39
MM
3272 lf_printf(file, "{\n");
3273 lf_printf(file, "}\n");
3274 lf_printf(file, "\n");
3275 }
3276
80948f39
MM
3277 if (!model_mon_info_p) {
3278 lf_printf(file, "INLINE_MODEL model_print *model_mon_info(model_data *model_ptr)\n");
3279 lf_printf(file, "{\n");
3280 lf_printf(file, " return (model_print *)0;\n");
3281 lf_printf(file, "}\n");
3282 lf_printf(file, "\n");
3283 }
3284
3285 if (!model_mon_info_free_p) {
3286 lf_printf(file, "INLINE_MODEL void model_mon_info_free(model_data *model_ptr,\n");
3287 lf_printf(file, " model_print *info_ptr)\n");
3288 lf_printf(file, "{\n");
3289 lf_printf(file, "}\n");
3290 lf_printf(file, "\n");
3291 }
3292
845ff5a4
MM
3293 lf_printf(file, "/* Insn functional unit info */\n");
3294 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3295 model_c_passed_data data;
3296
3297 lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
3298 data.file = file;
3299 data.model_ptr = model_ptr;
3300 insn_table_traverse_insn(table,
3301 (void *)&data,
3302 model_c_insn);
3303
3304 lf_printf(file, "};\n");
3305 lf_printf(file, "\n");
3306 lf_printf(file, "\f\n");
3307 }
3308
3309 lf_printf(file, "STATIC_MODEL const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3310 lf_printf(file, " (const model_time *const)0,\n");
3311 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3312 lf_printf(file, " model_time_%s,\n", model_ptr->name);
3313 }
3314 lf_printf(file, "};\n");
3315 lf_printf(file, "\n");
3316
80948f39
MM
3317 lf_printf(file, "\f\n");
3318 lf_printf(file, "/* map model enumeration into printable string */\n");
3319 lf_printf(file, "STATIC_MODEL const char *model_name[ (int)nr_models ] = {\n");
3320 lf_printf(file, " \"NONE\",\n");
3321 for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3322 lf_printf(file, " \"%s\",\n", model_ptr->printable_name);
3323 }
3324 lf_printf(file, "};\n");
3325 lf_printf(file, "\n");
3326
28816f45
MM
3327 lf_printf(file, "INLINE_MODEL void\n");
3328 lf_printf(file, "model_set(const char *name)\n");
3329 lf_printf(file, "{\n");
3330 if (models) {
3331 lf_printf(file, " model_enum model;\n");
3332 lf_printf(file, " for(model = MODEL_%s; model < nr_models; model++) {\n", models->name);
fe439e0f 3333 lf_printf(file, " if(strcmp(name, model_name[model]) == 0) {\n");
28816f45
MM
3334 lf_printf(file, " current_model = model;\n");
3335 lf_printf(file, " return;\n");
3336 lf_printf(file, " }\n");
3337 lf_printf(file, " }\n");
3338 lf_printf(file, "\n");
3339 lf_printf(file, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3340 lf_printf(file, " name,\n");
3341 lf_printf(file, " \"");
3342 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3343 lf_printf(file, "\\n\\t%s", model_ptr->printable_name);
3344 }
3345 lf_printf(file, "\");\n");
3346 } else {
3347 lf_printf(file, " error(\"No models are currently known about\");\n");
3348 }
3349
3350 lf_printf(file, "}\n");
3351 lf_printf(file, "\n");
3352
a3114052 3353 lf_printf(file, "#endif /* _MODEL_C_ */\n");
c143ef62
MM
3354
3355}
3356
3357/****************************************************************/
3358
3359
3360int
3361main(int argc,
3362 char **argv,
3363 char **envp)
3364{
3365 insn_table *instructions = NULL;
3366 icache_tree *cache_fields = NULL;
3367 char *real_file_name = NULL;
3368 int ch;
3369
3370 if (argc == 1) {
3371 printf("Usage:\n");
a983c8f0
MM
3372 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
3373 printf("Config options:\n");
3374 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
f2181eff
MM
3375 printf(" -e Expand (duplicate) semantic functions\n");
3376 printf(" -r <icache-size> Generate cracking cache version\n");
3377 printf(" -R Use defines to reference cache vars\n");
3378 printf(" -l Supress line numbering in output files\n");
3379 printf(" -b <bit-size> Set the number of bits in an instruction\n");
3380 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
3381 printf("\n");
a983c8f0
MM
3382 printf("Input options (ucase version also dumps loaded table):\n");
3383 printf(" -[Oo] <opcode-rules>\n");
3384 printf(" -[Kk] <cache-rules>\n");
3385 printf(" -[Ii] <instruction-table>\n");
f2181eff 3386 printf("\n");
a983c8f0
MM
3387 printf("Output options:\n");
3388 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
3389 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
a3114052 3390 printf(" -[Mm] <output-file> output model.h(M) model.c(M)\n");
a983c8f0 3391 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
f2181eff 3392 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
c143ef62
MM
3393 }
3394
3395 while ((ch = getopt(argc, argv,
f2181eff 3396 "leb:h:r:Rf:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
c143ef62
MM
3397 fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : ""));
3398 switch(ch) {
3399 case 'l':
3400 number_lines = 0;
3401 break;
3402 case 'e':
3403 idecode_expand_semantics = 1;
3404 break;
3405 case 'r':
3406 idecode_cache = a2i(optarg);
3407 break;
f2181eff
MM
3408 case 'R':
3409 semantics_use_cache_struct = 1;
3410 break;
a983c8f0
MM
3411 case 'b':
3412 insn_size = a2i(optarg);
3413 ASSERT(insn_size > 0 && insn_size <= max_insn_size
3414 && (hi_bit_nr == insn_size-1 || hi_bit_nr == 0));
3415 break;
3416 case 'h':
3417 hi_bit_nr = a2i(optarg);
3418 ASSERT(hi_bit_nr == insn_size-1 || hi_bit_nr == 0);
3419 break;
c143ef62
MM
3420 case 'f':
3421 {
3422 filter *new_filter = ZALLOC(filter);
3423 new_filter->flag = strdup(optarg);
3424 new_filter->next = filters;
3425 filters = new_filter;
3426 break;
3427 }
3428 case 'I':
3429 case 'i':
3430 ASSERT(opcode_table != NULL);
3431 ASSERT(cache_table != NULL);
3432 instructions = insn_table_load_insns(optarg);
3433 fprintf(stderr, "\texpanding ...\n");
3434 insn_table_expand_insns(instructions);
3435 fprintf(stderr, "\tcache fields ...\n");
3436 cache_fields = insn_table_cache_fields(instructions);
3437 if (ch == 'I') {
3438 dump_traverse(instructions);
3439 dump_insn_table(instructions, 0, 1);
3440 }
3441 break;
3442 case 'O':
3443 case 'o':
3444 opcode_table = load_opcode_rules(optarg);
3445 if (ch == 'O')
3446 dump_opcode_rules(opcode_table, 0);
3447 break;
3448 case 'K':
3449 case 'k':
3450 cache_table = load_cache_rules(optarg);
3451 if (ch == 'K')
3452 dump_cache_rules(cache_table, 0);
3453 break;
3454 case 'n':
3455 real_file_name = strdup(optarg);
3456 break;
3457 case 'S':
3458 case 's':
3459 case 'D':
3460 case 'd':
a3114052
MM
3461 case 'M':
3462 case 'm':
c143ef62
MM
3463 case 'T':
3464 case 't':
3465 case 'C':
3466 {
3467 lf *file = lf_open(optarg, real_file_name, number_lines);
3468 ASSERT(instructions != NULL);
3469 switch (ch) {
3470 case 'S':
3471 gen_semantics_h(instructions, file);
3472 break;
3473 case 's':
3474 gen_semantics_c(instructions, file);
3475 break;
3476 case 'D':
3477 gen_idecode_h(instructions, file);
3478 break;
3479 case 'd':
3480 gen_idecode_c(instructions, file);
3481 break;
a3114052
MM
3482 case 'M':
3483 gen_model_h(instructions, file);
3484 break;
3485 case 'm':
3486 gen_model_c(instructions, file);
3487 break;
c143ef62
MM
3488 case 'T':
3489 gen_itable_h(instructions, file);
3490 break;
3491 case 't':
3492 gen_itable_c(instructions, file);
3493 break;
3494 case 'C':
3495 gen_icache_h(cache_fields, file);
3496 break;
3497 }
3498 lf_close(file);
3499 }
3500 real_file_name = NULL;
3501 break;
3502 default:
3503 error("unknown option\n");
3504 }
3505 }
3506 return 0;
3507}
This page took 0.332781 seconds and 4 git commands to generate.