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