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