1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
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.
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.
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.
44 /****************************************************************/
50 static int hi_bit_nr = 0;
51 static int insn_size = max_insn_size;
52 static int idecode_expand_semantics = 0;
53 static int idecode_cache = 0;
54 static int semantics_use_cache_struct = 0;
55 static int number_lines = 1;
58 /****************************************************************/
61 static char *cache_idecode_formal =
63 instruction_word instruction,\n\
65 idecode_cache *cache_entry";
67 static char *cache_idecode_actual = "processor, instruction, cia, cache_entry";
69 static char *cache_semantic_formal =
71 idecode_cache *cache_entry,\n\
74 static char *semantic_formal =
76 instruction_word instruction,\n\
79 static char *semantic_actual = "processor, instruction, cia";
83 /****************************************************************/
86 typedef struct _filter filter;
91 static filter *filters = NULL;
94 /****************************************************************/
97 typedef struct _cache_rules cache_rules;
106 static cache_rules *cache_table;
115 nr_cache_rule_fields,
119 load_cache_rules(char *file_name)
121 table *file = table_open(file_name, nr_cache_rule_fields, 0);
123 cache_rules *table = NULL;
124 cache_rules **curr_rule = &table;
125 while ((entry = table_entry_read(file)) != NULL) {
126 cache_rules *new_rule = ZALLOC(cache_rules);
127 new_rule->valid = target_a2i(hi_bit_nr, entry->fields[ca_valid]);
128 new_rule->old_name = entry->fields[ca_old_name];
129 new_rule->new_name = entry->fields[ca_new_name];
130 new_rule->type = (strlen(entry->fields[ca_type])
131 ? entry->fields[ca_type]
133 new_rule->expression = (strlen(entry->fields[ca_expression]) > 0
134 ? entry->fields[ca_expression]
136 *curr_rule = new_rule;
137 curr_rule = &new_rule->next;
145 dump_cache_rule(cache_rules* rule,
148 dumpf(indent, "((cache_rules*)0x%x\n", rule);
149 dumpf(indent, " (valid %d)\n", rule->valid);
150 dumpf(indent, " (old_name \"%s\")\n", rule->old_name);
151 dumpf(indent, " (new_name \"%s\")\n", rule->new_name);
152 dumpf(indent, " (type \"%s\")\n", rule->type);
153 dumpf(indent, " (expression \"%s\")\n", rule->expression);
154 dumpf(indent, " (next 0x%x)\n", rule->next);
155 dumpf(indent, " )\n");
160 dump_cache_rules(cache_rules* rule, int indent)
163 dump_cache_rule(rule, indent);
169 /****************************************************************/
172 typedef struct _opcode_rules opcode_rules;
173 struct _opcode_rules {
179 char *force_expansion;
181 unsigned special_mask;
182 unsigned special_value;
183 unsigned special_rule;
186 static opcode_rules *opcode_table;
204 static opcode_rules *
205 load_opcode_rules(char *file_name)
207 table *file = table_open(file_name, nr_opcode_fields, 0);
209 opcode_rules *table = NULL;
210 opcode_rules **curr_rule = &table;
211 while ((entry = table_entry_read(file)) != NULL) {
212 opcode_rules *new_rule = ZALLOC(opcode_rules);
213 new_rule->first = target_a2i(hi_bit_nr, entry->fields[op_first]);
214 new_rule->last = target_a2i(hi_bit_nr, entry->fields[op_last]);
215 new_rule->force_first = target_a2i(hi_bit_nr, entry->fields[op_force_first]);
216 new_rule->force_last = target_a2i(hi_bit_nr, entry->fields[op_force_last]);
217 new_rule->force_slash = a2i(entry->fields[op_force_slash]);
218 new_rule->force_expansion = entry->fields[op_force_expansion];
219 new_rule->use_switch = a2i(entry->fields[op_use_switch]);
220 new_rule->special_mask = a2i(entry->fields[op_special_mask]);
221 new_rule->special_value = a2i(entry->fields[op_special_value]);
222 new_rule->special_rule = a2i(entry->fields[op_special_rule]);
223 *curr_rule = new_rule;
224 curr_rule = &new_rule->next;
231 dump_opcode_rule(opcode_rules *rule,
234 dumpf(indent, "((opcode_rules*)%p\n", rule);
236 dumpf(indent, " (first %d)\n", rule->first);
237 dumpf(indent, " (last %d)\n", rule->last);
238 dumpf(indent, " (force_first %d)\n", rule->force_first);
239 dumpf(indent, " (force_last %d)\n", rule->force_last);
240 dumpf(indent, " (force_slash %d)\n", rule->force_slash);
241 dumpf(indent, " (force_expansion \"%s\")\n", rule->force_expansion);
242 dumpf(indent, " (use_switch %d)\n", rule->use_switch);
243 dumpf(indent, " (special_mask 0x%x)\n", rule->special_mask);
244 dumpf(indent, " (special_value 0x%x)\n", rule->special_value);
245 dumpf(indent, " (special_rule 0x%x)\n", rule->special_rule);
246 dumpf(indent, " (next 0x%x)\n", rule->next);
248 dumpf(indent, " )\n");
253 dump_opcode_rules(opcode_rules *rule,
257 dump_opcode_rule(rule, indent);
263 /****************************************************************/
265 typedef struct _insn_field insn_field;
280 typedef struct _insn_fields insn_fields;
281 struct _insn_fields {
282 insn_field *bits[max_insn_size];
289 parse_insn_format(table_entry *entry,
293 insn_fields *fields = ZALLOC(insn_fields);
295 /* create a leading sentinal */
296 fields->first = ZALLOC(insn_field);
297 fields->first->first = -1;
298 fields->first->last = -1;
299 fields->first->width = 0;
301 /* and a trailing sentinal */
302 fields->last = ZALLOC(insn_field);
303 fields->last->first = insn_size;
304 fields->last->last = insn_size;
305 fields->last->width = 0;
307 /* link them together */
308 fields->first->next = fields->last;
309 fields->last->prev = fields->first;
311 /* now work through the formats */
314 while (*chp != '\0') {
319 insn_field *new_field;
322 if (!isdigit(*chp)) {
323 error("%s:%d: missing position field at `%s'\n",
324 entry->file_name, entry->line_nr, chp);
327 /* break out the bit position */
329 while (isdigit(*chp))
331 strlen_pos = chp - start_pos;
332 if (*chp == '.' && strlen_pos > 0)
335 error("%s:%d: missing field value at %s\n",
336 entry->file_name, entry->line_nr, chp);
340 /* break out the value */
342 while ((*start_val == '/' && *chp == '/')
343 || (isdigit(*start_val) && isdigit(*chp))
344 || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_')))
346 strlen_val = chp - start_val;
349 else if (*chp != '\0' || strlen_val == 0) {
350 error("%s:%d: missing field terminator at %s\n",
351 entry->file_name, entry->line_nr, chp);
355 /* create a new field and insert it */
356 new_field = ZALLOC(insn_field);
357 new_field->next = fields->last;
358 new_field->prev = fields->last->prev;
359 new_field->next->prev = new_field;
360 new_field->prev->next = new_field;
363 new_field->val_string = (char*)zalloc(strlen_val+1);
364 strncpy(new_field->val_string, start_val, strlen_val);
365 if (isdigit(*new_field->val_string)) {
366 new_field->val_int = a2i(new_field->val_string);
367 new_field->is_int = 1;
369 else if (new_field->val_string[0] == '/') {
370 new_field->is_slash = 1;
373 new_field->is_string = 1;
377 new_field->pos_string = (char*)zalloc(strlen_pos+1);
378 strncpy(new_field->pos_string, start_pos, strlen_pos);
379 new_field->first = target_a2i(hi_bit_nr, new_field->pos_string);
380 new_field->last = new_field->next->first - 1; /* guess */
381 new_field->width = new_field->last - new_field->first + 1; /* guess */
382 new_field->prev->last = new_field->first-1; /*fix*/
383 new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
386 /* fiddle first/last so that the sentinals `disapear' */
387 ASSERT(fields->first->last < 0);
388 ASSERT(fields->last->first >= insn_size);
389 fields->first = fields->first->next;
390 fields->last = fields->last->prev;
392 /* now go over this again, pointing each bit position at a field
397 field = fields->first;
398 for (i = 0; i < insn_size; i++) {
399 while (field->last < i)
401 fields->bits[i] = field;
405 /* go over each of the fields, and compute a `value' for the insn */
409 for (field = fields->first;
410 field->last < insn_size;
411 field = field->next) {
412 fields->value <<= field->width;
414 fields->value |= field->val_int;
422 field_constant_int = 1,
423 field_constant_slash = 2,
424 field_constant_string = 3
425 } constant_field_types;
429 insn_field_is_constant(insn_field *field,
432 /* field is an integer */
434 return field_constant_int;
435 /* field is `/' and treating that as a constant */
436 if (field->is_slash && rule->force_slash)
437 return field_constant_slash;
438 /* field, though variable is on the list */
439 if (field->is_string && rule->force_expansion != NULL) {
440 char *forced_fields = rule->force_expansion;
441 while (*forced_fields != '\0') {
443 char *end = strchr(forced_fields, ',');
445 field_len = strlen(forced_fields);
447 field_len = end-forced_fields;
448 if (strncmp(forced_fields, field->val_string, field_len) == 0
449 && field->val_string[field_len] == '\0')
450 return field_constant_string;
451 forced_fields += field_len;
452 if (*forced_fields == ',')
461 dump_insn_field(insn_field *field,
465 printf("(insn_field*)0x%x\n", (unsigned)field);
467 dumpf(indent, "(first %d)\n", field->first);
469 dumpf(indent, "(last %d)\n", field->last);
471 dumpf(indent, "(width %d)\n", field->width);
474 dumpf(indent, "(is_int %d)\n", field->val_int);
477 dumpf(indent, "(is_slash)\n");
479 if (field->is_string)
480 dumpf(indent, "(is_string `%s')\n", field->val_string);
482 dumpf(indent, "(next 0x%x)\n", field->next);
484 dumpf(indent, "(prev 0x%x)\n", field->prev);
490 dump_insn_fields(insn_fields *fields,
495 printf("(insn_fields*)%p\n", fields);
497 dumpf(indent, "(first 0x%x)\n", fields->first);
498 dumpf(indent, "(last 0x%x)\n", fields->last);
500 dumpf(indent, "(value 0x%x)\n", fields->value);
502 for (i = 0; i < insn_size; i++) {
503 dumpf(indent, "(bits[%d] ", i, fields->bits[i]);
504 dump_insn_field(fields->bits[i], indent+1);
505 dumpf(indent, " )\n");
511 /****************************************************************/
513 typedef struct _opcode_field opcode_field;
514 struct _opcode_field {
518 opcode_field *parent;
522 dump_opcode_field(opcode_field *field, int indent, int levels)
524 printf("(opcode_field*)%p\n", field);
525 if (levels && field != NULL) {
526 dumpf(indent, "(first %d)\n", field->first);
527 dumpf(indent, "(last %d)\n", field->last);
528 dumpf(indent, "(is_boolean %d)\n", field->is_boolean);
529 dumpf(indent, "(parent ");
530 dump_opcode_field(field->parent, indent, levels-1);
535 /****************************************************************/
537 typedef struct _insn_bits insn_bits;
542 opcode_field *opcode;
548 dump_insn_bits(insn_bits *bits, int indent, int levels)
550 printf("(insn_bits*)%p\n", bits);
552 if (levels && bits != NULL) {
553 dumpf(indent, "(value %d)\n", bits->value);
554 dumpf(indent, "(opcode ");
555 dump_opcode_field(bits->opcode, indent+1, 0);
556 dumpf(indent, " )\n");
557 dumpf(indent, "(field ");
558 dump_insn_field(bits->field, indent+1);
559 dumpf(indent, " )\n");
560 dumpf(indent, "(last ");
561 dump_insn_bits(bits->last, indent+1, levels-1);
566 /****************************************************************/
580 function_type = insn_format,
581 function_name = insn_name,
582 function_param = insn_comment
583 } function_table_fields;
586 model_name = insn_mnemonic,
587 model_identifer = insn_name,
588 model_default = insn_comment,
589 } model_table_fields;
591 typedef struct _insn insn;
593 table_entry *file_entry;
598 typedef struct _insn_undef insn_undef;
604 static insn_undef *first_undef, *last_undef;
606 typedef struct _model model;
610 char *printable_name;
612 table_model_entry *func_unit_start;
613 table_model_entry *func_unit_end;
616 typedef struct _insn_table insn_table;
619 insn_bits *expanded_bits;
624 opcode_rules *opcode_rule;
625 opcode_field *opcode;
635 nr_insn_model_table_fields
636 } insn_model_table_fields;
638 static model *models;
639 static model *last_model;
641 static insn *model_macros;
642 static insn *last_model_macro;
644 static insn *model_functions;
645 static insn *last_model_function;
647 static insn *model_internal;
648 static insn *last_model_internal;
650 static insn *model_static;
651 static insn *last_model_static;
653 static insn *model_data;
654 static insn *last_model_data;
656 static int max_model_fields_len;
659 insn_table_insert_function(insn_table *table,
660 table_entry *file_entry)
662 /* create a new function */
663 insn *new_function = ZALLOC(insn);
664 new_function->file_entry = file_entry;
666 /* append it to the end of the function list */
667 if (table->last_function)
668 table->last_function->next = new_function;
670 table->functions = new_function;
671 table->last_function = new_function;
675 insn_table_insert_insn(insn_table *table,
676 table_entry *file_entry,
679 insn **ptr_to_cur_insn = &table->insns;
680 insn *cur_insn = *ptr_to_cur_insn;
681 table_model_entry *insn_model_ptr;
684 /* create a new instruction */
685 insn *new_insn = ZALLOC(insn);
686 new_insn->file_entry = file_entry;
687 new_insn->fields = fields;
689 /* Check out any model information returned to make sure the model
691 for(insn_model_ptr = file_entry->model_first; insn_model_ptr; insn_model_ptr = insn_model_ptr->next) {
692 char *name = insn_model_ptr->fields[insn_model_name];
693 int len = strlen (insn_model_ptr->fields[insn_model_fields]);
695 while (len > 0 && isspace(*insn_model_ptr->fields[insn_model_fields])) {
697 insn_model_ptr->fields[insn_model_fields]++;
700 if (max_model_fields_len < len)
701 max_model_fields_len = len;
703 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
704 if (strcmp(name, model_ptr->printable_name) == 0) {
706 /* Replace the name field with that of the global model, so that when we
707 want to print it out, we can just compare pointers. */
708 insn_model_ptr->fields[insn_model_name] = model_ptr->printable_name;
714 error("%s:%d: machine model `%s' was not known about\n",
715 file_entry->file_name, file_entry->line_nr, name);
718 /* insert it according to the order of the fields */
719 while (cur_insn != NULL
720 && new_insn->fields->value >= cur_insn->fields->value) {
721 ptr_to_cur_insn = &cur_insn->next;
722 cur_insn = *ptr_to_cur_insn;
725 new_insn->next = cur_insn;
726 *ptr_to_cur_insn = new_insn;
732 static opcode_field *
733 insn_table_find_opcode_field(insn *insns,
737 opcode_field *curr_opcode = ZALLOC(opcode_field);
741 curr_opcode->first = insn_size;
742 curr_opcode->last = -1;
743 for (entry = insns; entry != NULL; entry = entry->next) {
744 insn_fields *fields = entry->fields;
745 opcode_field new_opcode;
747 /* find a start point for the opcode field */
748 new_opcode.first = rule->first;
749 while (new_opcode.first <= rule->last
751 || insn_field_is_constant(fields->bits[new_opcode.first],
752 rule) != field_constant_string)
754 || !insn_field_is_constant(fields->bits[new_opcode.first],
756 new_opcode.first = fields->bits[new_opcode.first]->last + 1;
757 ASSERT(new_opcode.first > rule->last
759 && insn_field_is_constant(fields->bits[new_opcode.first],
760 rule) == field_constant_string)
762 && insn_field_is_constant(fields->bits[new_opcode.first],
765 /* find the end point for the opcode field */
766 new_opcode.last = rule->last;
767 while (new_opcode.last >= rule->first
769 || insn_field_is_constant(fields->bits[new_opcode.last],
770 rule) != field_constant_string)
772 || !insn_field_is_constant(fields->bits[new_opcode.last],
774 new_opcode.last = fields->bits[new_opcode.last]->first - 1;
775 ASSERT(new_opcode.last < rule->first
777 && insn_field_is_constant(fields->bits[new_opcode.last],
778 rule) == field_constant_string)
780 && insn_field_is_constant(fields->bits[new_opcode.last],
783 /* now see if our current opcode needs expanding */
784 if (new_opcode.first <= rule->last
785 && curr_opcode->first > new_opcode.first)
786 curr_opcode->first = new_opcode.first;
787 if (new_opcode.last >= rule->first
788 && curr_opcode->last < new_opcode.last)
789 curr_opcode->last = new_opcode.last;
793 /* was any thing interesting found? */
794 if (curr_opcode->first > rule->last) {
795 ASSERT(curr_opcode->last < rule->first);
798 ASSERT(curr_opcode->last >= rule->first);
799 ASSERT(curr_opcode->first <= rule->last);
801 /* if something was found, check it includes the forced field range */
803 && curr_opcode->first > rule->force_first) {
804 curr_opcode->first = rule->force_first;
807 && curr_opcode->last < rule->force_last) {
808 curr_opcode->last = rule->force_last;
810 /* handle special case elminating any need to do shift after mask */
812 && rule->force_last == insn_size-1) {
813 curr_opcode->last = insn_size-1;
816 /* handle any special cases */
817 switch (rule->special_rule) {
818 case 0: /* let the above apply */
820 case 1: /* expand a limited nr of bits, ignoring the rest */
821 curr_opcode->first = rule->force_first;
822 curr_opcode->last = rule->force_last;
824 case 2: /* boolean field */
825 curr_opcode->is_boolean = 1;
834 insn_table_insert_expanded(insn_table *table,
839 insn_table **ptr_to_cur_entry = &table->entries;
840 insn_table *cur_entry = *ptr_to_cur_entry;
842 /* find the new table for this entry */
843 while (cur_entry != NULL
844 && cur_entry->opcode_nr < new_opcode_nr) {
845 ptr_to_cur_entry = &cur_entry->sibling;
846 cur_entry = *ptr_to_cur_entry;
849 if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {
850 insn_table *new_entry = ZALLOC(insn_table);
851 new_entry->opcode_nr = new_opcode_nr;
852 new_entry->expanded_bits = new_bits;
853 new_entry->opcode_rule = table->opcode_rule->next;
854 new_entry->sibling = cur_entry;
855 new_entry->parent = table;
856 *ptr_to_cur_entry = new_entry;
857 cur_entry = new_entry;
860 /* ASSERT new_bits == cur_entry bits */
861 ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);
862 insn_table_insert_insn(cur_entry,
863 old_insn->file_entry,
868 insn_table_expand_opcode(insn_table *table,
875 if (field_nr > table->opcode->last) {
876 insn_table_insert_expanded(table, instruction, opcode_nr, bits);
879 insn_field *field = instruction->fields->bits[field_nr];
880 if (field->is_int || field->is_slash) {
881 ASSERT(field->first >= table->opcode->first
882 && field->last <= table->opcode->last);
883 insn_table_expand_opcode(table, instruction, field->last+1,
884 ((opcode_nr << field->width) + field->val_int),
889 int last_pos = ((field->last < table->opcode->last)
890 ? field->last : table->opcode->last);
891 int first_pos = ((field->first > table->opcode->first)
892 ? field->first : table->opcode->first);
893 int width = last_pos - first_pos + 1;
894 int last_val = (table->opcode->is_boolean
896 for (val = 0; val < last_val; val++) {
897 insn_bits *new_bits = ZALLOC(insn_bits);
898 new_bits->field = field;
899 new_bits->value = val;
900 new_bits->last = bits;
901 new_bits->opcode = table->opcode;
902 insn_table_expand_opcode(table, instruction, last_pos+1,
903 ((opcode_nr << width) | val),
911 insn_table_insert_expanding(insn_table *table,
914 insn_table_expand_opcode(table,
916 table->opcode->first,
918 table->expanded_bits);
923 insn_table_expand_insns(insn_table *table)
926 ASSERT(table->nr_insn >= 1);
928 /* determine a valid opcode */
929 while (table->opcode_rule) {
930 /* specials only for single instructions */
931 if ((table->nr_insn > 1
932 && table->opcode_rule->special_mask == 0
933 && table->opcode_rule->special_rule == 0)
934 || (table->nr_insn == 1
935 && table->opcode_rule->special_mask != 0
936 && ((table->insns->fields->value
937 & table->opcode_rule->special_mask)
938 == table->opcode_rule->special_value))
939 || (idecode_expand_semantics
940 && table->opcode_rule->special_mask == 0
941 && table->opcode_rule->special_rule == 0))
943 insn_table_find_opcode_field(table->insns,
945 table->nr_insn == 1/*string*/
947 if (table->opcode != NULL)
949 table->opcode_rule = table->opcode_rule->next;
952 /* did we find anything */
953 if (table->opcode == NULL) {
956 ASSERT(table->opcode != NULL);
958 /* back link what we found to its parent */
959 if (table->parent != NULL) {
960 ASSERT(table->parent->opcode != NULL);
961 table->opcode->parent = table->parent->opcode;
964 /* expand the raw instructions according to the opcode */
967 for (entry = table->insns; entry != NULL; entry = entry->next) {
968 insn_table_insert_expanding(table, entry);
972 /* and do the same for the sub entries */
975 for (entry = table->entries; entry != NULL; entry = entry->sibling) {
976 insn_table_expand_insns(entry);
983 model_table_insert(insn_table *table,
984 table_entry *file_entry)
988 /* create a new model */
989 model *new_model = ZALLOC(model);
991 new_model->name = file_entry->fields[model_identifer];
992 new_model->printable_name = file_entry->fields[model_name];
993 new_model->insn_default = file_entry->fields[model_default];
995 while (*new_model->insn_default && isspace(*new_model->insn_default))
996 new_model->insn_default++;
998 len = strlen(new_model->insn_default);
999 if (max_model_fields_len < len)
1000 max_model_fields_len = len;
1002 /* append it to the end of the model list */
1004 last_model->next = new_model;
1007 last_model = new_model;
1011 model_table_insert_specific(insn_table *table,
1012 table_entry *file_entry,
1016 insn *ptr = ZALLOC(insn);
1017 ptr->file_entry = file_entry;
1019 (*end_ptr)->next = ptr;
1028 insn_table_load_insns(char *file_name)
1030 table *file = table_open(file_name, nr_insn_table_fields, nr_insn_model_table_fields);
1031 insn_table *table = ZALLOC(insn_table);
1032 table_entry *file_entry;
1033 table->opcode_rule = opcode_table;
1035 while ((file_entry = table_entry_read(file)) != NULL) {
1036 if (it_is("function", file_entry->fields[insn_flags])
1037 || it_is("internal", file_entry->fields[insn_flags])) {
1038 insn_table_insert_function(table, file_entry);
1040 else if (it_is("model", file_entry->fields[insn_flags])) {
1041 model_table_insert(table, file_entry);
1043 else if (it_is("model-macro", file_entry->fields[insn_flags])) {
1044 model_table_insert_specific(table, file_entry, &model_macros, &last_model_macro);
1046 else if (it_is("model-function", file_entry->fields[insn_flags])) {
1047 model_table_insert_specific(table, file_entry, &model_functions, &last_model_function);
1049 else if (it_is("model-internal", file_entry->fields[insn_flags])) {
1050 model_table_insert_specific(table, file_entry, &model_internal, &last_model_internal);
1052 else if (it_is("model-static", file_entry->fields[insn_flags])) {
1053 model_table_insert_specific(table, file_entry, &model_static, &last_model_static);
1055 else if (it_is("model-data", file_entry->fields[insn_flags])) {
1056 model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
1059 insn_fields *fields;
1060 /* skip instructions that aren't relevant to the mode */
1061 filter *filt = filters;
1062 while (filt != NULL) {
1063 if (it_is(filt->flag, file_entry->fields[insn_flags]))
1068 /* create/insert the new instruction */
1069 fields = parse_insn_format(file_entry,
1070 file_entry->fields[insn_format]);
1071 insn_table_insert_insn(table, file_entry, fields);
1080 dump_insn(insn *entry, int indent, int levels)
1082 printf("(insn*)%p\n", entry);
1084 if (levels && entry != NULL) {
1086 dumpf(indent, "(file_entry ");
1087 dump_table_entry(entry->file_entry, indent+1);
1088 dumpf(indent, " )\n");
1090 dumpf(indent, "(fields ");
1091 dump_insn_fields(entry->fields, indent+1);
1092 dumpf(indent, " )\n");
1094 dumpf(indent, "(next ");
1095 dump_insn(entry->next, indent+1, levels-1);
1096 dumpf(indent, " )\n");
1104 dump_insn_table(insn_table *table,
1105 int indent, int levels)
1108 printf("(insn_table*)%p\n", table);
1110 if (levels && table != NULL) {
1112 dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);
1114 dumpf(indent, "(expanded_bits ");
1115 dump_insn_bits(table->expanded_bits, indent+1, -1);
1116 dumpf(indent, " )\n");
1118 dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);
1120 dumpf(indent, "(insns ");
1121 dump_insn(table->insns, indent+1, table->nr_insn);
1122 dumpf(indent, " )\n");
1124 dumpf(indent, "(opcode_rule ");
1125 dump_opcode_rule(table->opcode_rule, indent+1);
1126 dumpf(indent, " )\n");
1128 dumpf(indent, "(opcode ");
1129 dump_opcode_field(table->opcode, indent+1, 1);
1130 dumpf(indent, " )\n");
1132 dumpf(indent, "(nr_entries %d)\n", table->entries);
1133 dumpf(indent, "(entries ");
1134 dump_insn_table(table->entries, indent+1, table->nr_entries);
1135 dumpf(indent, " )\n");
1137 dumpf(indent, "(sibling ", table->sibling);
1138 dump_insn_table(table->sibling, indent+1, levels-1);
1139 dumpf(indent, " )\n");
1141 dumpf(indent, "(parent ", table->parent);
1142 dump_insn_table(table->parent, indent+1, 0);
1143 dumpf(indent, " )\n");
1149 /****************************************************************/
1153 lf_print_insn_bits(lf *file, insn_bits *bits)
1157 lf_print_insn_bits(file, bits->last);
1158 lf_putchr(file, '_');
1159 lf_putstr(file, bits->field->val_string);
1160 if (!bits->opcode->is_boolean || bits->value == 0) {
1161 if (bits->opcode->last < bits->field->last)
1162 lf_putint(file, bits->value << (bits->field->last - bits->opcode->last));
1164 lf_putint(file, bits->value);
1169 lf_print_opcodes(lf *file,
1172 if (table != NULL) {
1174 lf_printf(file, "_%d_%d",
1175 table->opcode->first,
1176 table->opcode->last);
1177 if (table->parent == NULL) break;
1178 lf_printf(file, "__%d", table->opcode_nr);
1179 table = table->parent;
1185 lf_print_table_name(lf *file,
1188 lf_printf(file, "idecode_table");
1189 lf_print_opcodes(file, table);
1195 function_name_prefix_semantics,
1196 function_name_prefix_idecode,
1197 function_name_prefix_itable,
1198 function_name_prefix_none
1199 } lf_function_name_prefixes;
1202 lf_print_function_name(lf *file,
1204 insn_bits *expanded_bits,
1205 lf_function_name_prefixes prefix)
1210 case function_name_prefix_semantics:
1211 lf_putstr(file, "semantic_");
1213 case function_name_prefix_idecode:
1214 lf_printf(file, "idecode_");
1216 case function_name_prefix_itable:
1217 lf_putstr(file, "itable_");
1223 /* the function name */
1226 for (pos = basename;
1234 lf_putchr(file, '_');
1237 lf_putchr(file, *pos);
1244 if (idecode_expand_semantics)
1245 lf_print_insn_bits(file, expanded_bits);
1250 lf_print_idecode_table(lf *file,
1253 int can_assume_leaf;
1254 opcode_rules *opcode_rule;
1256 /* have a look at the rule table, if all table rules follow all
1257 switch rules, I can assume that all end points are leaves */
1258 opcode_rule = opcode_table;
1259 while (opcode_rule != NULL
1260 && opcode_rule->use_switch)
1261 opcode_rule = opcode_rule->next;
1262 while (opcode_rule != NULL
1263 && opcode_rule->use_switch
1264 && opcode_rule->special_rule)
1265 opcode_rule = opcode_rule->next;
1266 can_assume_leaf = opcode_rule == NULL;
1268 lf_printf(file, "{\n");
1269 lf_indent(file, +2);
1271 lf_printf(file, "idecode_table_entry *table = ");
1272 lf_print_table_name(file, entry);
1273 lf_printf(file, ";\n");
1274 lf_printf(file, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1275 i2target(hi_bit_nr, entry->opcode->first),
1276 i2target(hi_bit_nr, entry->opcode->last));
1277 lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
1278 lf_printf(file, "while (1) {\n");
1279 lf_indent(file, +2);
1281 lf_printf(file, "/* nonzero mask -> another table */\n");
1282 lf_printf(file, "while (table_entry->mask != 0) {\n");
1283 lf_indent(file, +2);
1285 lf_printf(file, "table = ((idecode_table_entry*)\n");
1286 lf_printf(file, " table_entry->function_or_table);\n");
1287 lf_printf(file, "opcode = ((instruction & table_entry->mask)\n");
1288 lf_printf(file, " >> table_entry->shift);\n");
1289 lf_printf(file, "table_entry = table + opcode;\n");
1291 lf_indent(file, -2);
1292 lf_printf(file, "}\n");
1293 lf_printf(file, "ASSERT(table_entry->mask == 0);\n");
1294 if (can_assume_leaf)
1295 lf_printf(file, "ASSERT(table_entry->shift == 0);\n");
1297 lf_printf(file, "if (table_entry->shift == 0)\n");
1298 lf_indent(file, +2);
1300 if (idecode_cache) {
1301 lf_printf(file, "return (((idecode_crack*)\n");
1302 lf_printf(file, " table_entry->function_or_table)\n");
1303 lf_printf(file, " (%s));\n", cache_idecode_actual);
1306 lf_printf(file, "return (((idecode_semantic*)\n");
1307 lf_printf(file, " table_entry->function_or_table)\n");
1308 lf_printf(file, " (%s));\n", semantic_actual);
1310 if (!can_assume_leaf) {
1311 lf_indent(file, -2);
1312 lf_printf(file, "/* must be a boolean */\n");
1313 lf_printf(file, "opcode = (instruction & table_entry->shift) != 0;\n");
1314 lf_printf(file, "table = ((idecode_table_entry*)\n");
1315 lf_printf(file, " table_entry->function_or_table);\n");
1316 lf_printf(file, "table_entry = table + opcode;\n");
1319 lf_indent(file, -2);
1320 lf_printf(file, "}\n");
1322 lf_indent(file, -2);
1323 lf_printf(file, "}\n");
1328 lf_print_my_prefix(lf *file,
1329 table_entry *file_entry,
1332 lf_printf(file, "const char *const my_prefix __attribute__((__unused__)) = \n");
1333 lf_printf(file, " \"%s:%s:%s:%d\";\n",
1334 filter_filename (file_entry->file_name),
1335 (idecode ? "idecode" : "semantics"),
1336 file_entry->fields[insn_name],
1337 file_entry->line_nr);
1338 lf_printf(file, "const itable_index my_index __attribute__((__unused__)) = ");
1339 lf_print_function_name(file,
1340 file_entry->fields[insn_name],
1342 function_name_prefix_itable);
1343 lf_printf(file, ";\n");
1348 lf_print_ptrace(lf *file,
1351 lf_printf(file, "\n");
1352 lf_printf(file, "ITRACE(trace_%s, (\"\\n\"));\n",
1353 (idecode ? "idecode" : "semantics"));
1357 /****************************************************************/
1359 typedef void leaf_handler
1363 typedef void padding_handler
1371 insn_table_traverse_tree(insn_table *table,
1374 leaf_handler *start,
1377 padding_handler *padding)
1382 ASSERT(table != NULL
1383 && table->opcode != NULL
1384 && table->nr_entries > 0
1385 && table->entries != 0);
1387 if (start != NULL && depth >= 0)
1388 start(table, data, depth);
1390 for (entry_nr = 0, entry = table->entries;
1391 entry_nr < (table->opcode->is_boolean
1393 : (1 << (table->opcode->last - table->opcode->first + 1)));
1396 || (!table->opcode->is_boolean
1397 && entry_nr < entry->opcode_nr)) {
1398 if (padding != NULL && depth >= 0)
1399 padding(table, data, depth, entry_nr);
1402 ASSERT(entry != NULL && (entry->opcode_nr == entry_nr
1403 || table->opcode->is_boolean));
1404 if (entry->opcode != NULL && depth != 0) {
1405 insn_table_traverse_tree(entry, data, depth+1,
1406 start, leaf, end, padding);
1408 else if (depth >= 0) {
1410 leaf(entry, data, depth);
1412 entry = entry->sibling;
1415 if (end != NULL && depth >= 0)
1416 end(table, data, depth);
1420 typedef void function_handler
1423 table_entry *function);
1426 insn_table_traverse_function(insn_table *table,
1428 function_handler *leaf)
1431 for (function = table->functions;
1433 function = function->next) {
1434 leaf(table, data, function->file_entry);
1439 typedef void insn_handler
1445 insn_table_traverse_insn(insn_table *table,
1450 for (instruction = table->insns;
1451 instruction != NULL;
1452 instruction = instruction->next) {
1453 leaf(table, data, instruction);
1459 update_depth(insn_table *entry,
1463 int *max_depth = (int*)data;
1464 if (*max_depth < depth)
1470 insn_table_depth(insn_table *table)
1473 insn_table_traverse_tree(table,
1484 /****************************************************************/
1487 dump_traverse_start(insn_table *table,
1491 dumpf(depth*2, "(%d\n", table->opcode_nr);
1495 dump_traverse_leaf(insn_table *entry,
1499 ASSERT(entry->nr_entries == 0
1500 && entry->nr_insn == 1
1501 && entry->opcode == NULL);
1502 dumpf(depth*2, ".%d %s\n", entry->opcode_nr,
1503 entry->insns->file_entry->fields[insn_format]);
1507 dump_traverse_end(insn_table *table,
1511 dumpf(depth*2, ")\n");
1515 dump_traverse_padding(insn_table *table,
1520 dumpf(depth*2, ".<%d>\n", opcode_nr);
1525 dump_traverse(insn_table *table)
1527 insn_table_traverse_tree(table, NULL, 1,
1528 dump_traverse_start,
1531 dump_traverse_padding);
1535 /****************************************************************/
1539 lf_print_semantic_function_header(lf *file,
1541 insn_bits *expanded_bits,
1542 int is_function_definition,
1543 int is_inline_function)
1545 lf_printf(file, "\n");
1546 lf_print_function_type(file, "unsigned_word", "EXTERN_SEMANTICS",
1548 lf_print_function_name(file,
1551 function_name_prefix_semantics);
1552 lf_printf(file, "\n(%s)",
1553 (idecode_cache ? cache_semantic_formal : semantic_formal));
1554 if (!is_function_definition)
1555 lf_printf(file, ";");
1556 lf_printf(file, "\n");
1561 semantics_h_leaf(insn_table *entry,
1565 lf *file = (lf*)data;
1566 ASSERT(entry->nr_insn == 1);
1567 lf_print_semantic_function_header(file,
1568 entry->insns->file_entry->fields[insn_name],
1569 entry->expanded_bits,
1570 0/* isnt function definition*/,
1571 !idecode_cache && entry->parent->opcode_rule->use_switch);
1575 semantics_h_insn(insn_table *entry,
1579 lf *file = (lf*)data;
1580 lf_print_semantic_function_header(file,
1581 instruction->file_entry->fields[insn_name],
1583 0/*isnt function definition*/,
1584 0/*isnt inline function*/);
1588 semantics_h_function(insn_table *entry,
1590 table_entry *function)
1592 lf *file = (lf*)data;
1593 if (function->fields[function_type] == NULL
1594 || function->fields[function_type][0] == '\0') {
1595 lf_print_semantic_function_header(file,
1596 function->fields[function_name],
1598 0/*isnt function definition*/,
1599 1/*is inline function*/);
1602 lf_printf(file, "\n");
1603 lf_print_function_type(file, function->fields[function_type],
1604 "INLINE_SEMANTICS", " ");
1605 lf_printf(file, "%s\n(%s);\n",
1606 function->fields[function_name],
1607 function->fields[function_param]);
1613 gen_semantics_h(insn_table *table, lf *file)
1616 lf_print_copyleft(file);
1617 lf_printf(file, "\n");
1618 lf_printf(file, "#ifndef _SEMANTICS_H_\n");
1619 lf_printf(file, "#define _SEMANTICS_H_\n");
1620 lf_printf(file, "\n");
1622 /* output a declaration for all functions */
1623 insn_table_traverse_function(table,
1625 semantics_h_function);
1627 /* output a declaration for all instructions */
1628 if (idecode_expand_semantics)
1629 insn_table_traverse_tree(table,
1633 semantics_h_leaf, /* leaf */
1635 NULL); /* padding */
1637 insn_table_traverse_insn(table,
1641 lf_printf(file, "\n");
1642 lf_printf(file, "#endif /* _SEMANTICS_H_ */\n");
1646 /****************************************************************/
1648 typedef struct _icache_tree icache_tree;
1649 struct _icache_tree {
1652 icache_tree *children;
1655 static icache_tree *
1656 icache_tree_insert(icache_tree *tree,
1659 icache_tree *new_tree;
1661 icache_tree **ptr_to_cur_tree = &tree->children;
1662 icache_tree *cur_tree = *ptr_to_cur_tree;
1663 while (cur_tree != NULL
1664 && strcmp(cur_tree->name, name) < 0) {
1665 ptr_to_cur_tree = &cur_tree->next;
1666 cur_tree = *ptr_to_cur_tree;
1668 ASSERT(cur_tree == NULL
1669 || strcmp(cur_tree->name, name) >= 0);
1670 /* already in the tree */
1671 if (cur_tree != NULL
1672 && strcmp(cur_tree->name, name) == 0)
1674 /* missing, insert it */
1675 ASSERT(cur_tree == NULL
1676 || strcmp(cur_tree->name, name) > 0);
1677 new_tree = ZALLOC(icache_tree);
1678 new_tree->name = name;
1679 new_tree->next = cur_tree;
1680 *ptr_to_cur_tree = new_tree;
1685 static icache_tree *
1686 insn_table_cache_fields(insn_table *table)
1688 icache_tree *tree = ZALLOC(icache_tree);
1690 for (instruction = table->insns;
1691 instruction != NULL;
1692 instruction = instruction->next) {
1695 icache_tree_insert(tree,
1696 instruction->file_entry->fields[insn_form]);
1697 for (field = instruction->fields->first;
1699 field = field->next) {
1700 if (field->is_string)
1701 icache_tree_insert(form, field->val_string);
1710 gen_icache_h(icache_tree *tree,
1713 lf_print_copyleft(file);
1714 lf_printf(file, "\n");
1715 lf_printf(file, "#ifndef _ICACHE_H_\n");
1716 lf_printf(file, "#define _ICACHE_H_\n");
1717 lf_printf(file, "\n");
1719 lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1721 lf_printf(file, "\n");
1723 /* create an instruction cache if being used */
1724 if (idecode_cache) {
1726 lf_printf(file, "typedef struct _idecode_cache {\n");
1727 lf_printf(file, " unsigned_word address;\n");
1728 lf_printf(file, " void *semantic;\n");
1729 lf_printf(file, " union {\n");
1730 for (form = tree->children;
1732 form = form->next) {
1734 lf_printf(file, " struct {\n");
1735 for (field = form->children;
1737 field = field->next) {
1738 cache_rules *cache_rule;
1740 for (cache_rule = cache_table;
1742 cache_rule = cache_rule->next) {
1743 if (strcmp(field->name, cache_rule->old_name) == 0) {
1745 if (cache_rule->new_name != NULL)
1746 lf_printf(file, " %s %s; /* %s */\n",
1747 (cache_rule->type == NULL
1749 : cache_rule->type),
1750 cache_rule->new_name,
1751 cache_rule->old_name);
1755 lf_printf(file, " unsigned %s;\n", field->name);
1757 lf_printf(file, " } %s;\n", form->name);
1759 lf_printf(file, " } crack;\n");
1760 lf_printf(file, "} idecode_cache;\n");
1763 /* alernativly, since no cache, #define the fields to be
1764 extractions from the instruction variable. Emit a dummy
1765 definition for idecode_cache to allow model_issue to not
1766 be #ifdefed at the call level */
1767 cache_rules *cache_rule;
1768 lf_printf(file, "\n");
1769 lf_printf(file, "typedef void idecode_cache;\n");
1770 lf_printf(file, "\n");
1771 for (cache_rule = cache_table;
1773 cache_rule = cache_rule->next) {
1774 if (cache_rule->expression != NULL
1775 && strlen(cache_rule->expression) > 0)
1776 lf_printf(file, "#define %s %s\n",
1777 cache_rule->new_name, cache_rule->expression);
1781 lf_printf(file, "\n");
1782 lf_printf(file, "#endif /* _ICACHE_H_ */\n");
1788 /****************************************************************/
1792 lf_print_c_extraction(lf *file,
1796 char *field_expression,
1797 insn_field *cur_field,
1799 int get_value_from_cache,
1800 int put_value_in_cache)
1802 ASSERT(field_name != NULL);
1804 && (!bits->opcode->is_boolean || bits->value == 0)
1805 && strcmp(field_name, cur_field->val_string) == 0) {
1806 ASSERT(bits->field == cur_field);
1807 ASSERT(field_type == NULL);
1808 table_entry_lf_c_line_nr(file, instruction->file_entry);
1809 lf_printf(file, "const unsigned %s __attribute__((__unused__)) = ",
1811 if (bits->opcode->last < bits->field->last)
1812 lf_printf(file, "%d;\n",
1813 bits->value << (bits->field->last - bits->opcode->last));
1815 lf_printf(file, "%d;\n", bits->value);
1817 else if (get_value_from_cache && !put_value_in_cache
1818 && semantics_use_cache_struct) {
1819 insn_undef *undef = ZALLOC(insn_undef);
1820 /* Use #define to reference the cache struct directly, rather than putting
1821 them into local variables */
1822 lf_indent_suppress(file);
1823 lf_printf(file, "#define %s (cache_entry->crack.%s.%s)\n",
1825 instruction->file_entry->fields[insn_form],
1829 last_undef->next = undef;
1831 first_undef = undef;
1832 last_undef = undef;;
1833 undef->name = field_name;
1836 /* put the field in the local variable */
1837 table_entry_lf_c_line_nr(file, instruction->file_entry);
1838 lf_printf(file, "%s const %s __attribute__((__unused__)) = ",
1839 field_type == NULL ? "unsigned" : field_type,
1841 /* getting it from the cache */
1842 if (get_value_from_cache || put_value_in_cache) {
1843 lf_printf(file, "cache_entry->crack.%s.%s",
1844 instruction->file_entry->fields[insn_form],
1846 if (put_value_in_cache) /* also put it in the cache? */
1847 lf_printf(file, " = ");
1849 if (!get_value_from_cache) {
1850 if (strcmp(field_name, cur_field->val_string) == 0)
1851 lf_printf(file, "EXTRACTED32(instruction, %d, %d)",
1852 i2target(hi_bit_nr, cur_field->first),
1853 i2target(hi_bit_nr, cur_field->last));
1854 else if (field_expression != NULL)
1855 lf_printf(file, "%s", field_expression);
1857 lf_printf(file, "eval_%s", field_name);
1859 lf_printf(file, ";\n");
1865 lf_print_c_extractions(lf *file,
1867 insn_bits *expanded_bits,
1868 int get_value_from_cache,
1869 int put_value_in_cache)
1871 insn_field *cur_field;
1873 /* extract instruction fields */
1874 lf_printf(file, "/* extraction: %s */\n",
1875 instruction->file_entry->fields[insn_format]);
1877 for (cur_field = instruction->fields->first;
1878 cur_field->first < insn_size;
1879 cur_field = cur_field->next) {
1880 if (cur_field->is_string) {
1883 /* find any corresponding value */
1884 for (bits = expanded_bits;
1886 bits = bits->last) {
1887 if (bits->field == cur_field)
1890 /* try the cache rule table for what to do */
1891 if (get_value_from_cache || put_value_in_cache) {
1892 cache_rules *cache_rule;
1893 for (cache_rule = cache_table;
1895 cache_rule = cache_rule->next) {
1896 if (strcmp(cur_field->val_string, cache_rule->old_name) == 0) {
1898 if (cache_rule->valid > 1 && put_value_in_cache)
1899 lf_print_c_extraction(file,
1901 cache_rule->new_name,
1903 cache_rule->expression,
1908 else if (cache_rule->valid == 1)
1909 lf_print_c_extraction(file,
1911 cache_rule->new_name,
1913 cache_rule->expression,
1916 get_value_from_cache,
1917 put_value_in_cache);
1921 if (found_rule == 0)
1922 lf_print_c_extraction(file,
1924 cur_field->val_string,
1929 get_value_from_cache,
1930 put_value_in_cache);
1931 /* if any (XXX == 0), output a corresponding test */
1932 if (instruction->file_entry->annex != NULL) {
1933 char *field_name = cur_field->val_string;
1934 char *is_0_ptr = instruction->file_entry->annex;
1935 int field_len = strlen(field_name);
1936 if (strlen(is_0_ptr) >= (strlen("_is_0") + field_len)) {
1937 is_0_ptr += field_len;
1938 while ((is_0_ptr = strstr(is_0_ptr, "_is_0")) != NULL) {
1939 if (strncmp(is_0_ptr - field_len, field_name, field_len) == 0
1940 && !isalpha(is_0_ptr[ - field_len - 1])) {
1941 table_entry_lf_c_line_nr(file, instruction->file_entry);
1942 lf_printf(file, "const unsigned %s_is_0 __attribute__((__unused__)) = (", field_name);
1944 lf_printf(file, "%d", bits->value);
1946 lf_printf(file, "%s", field_name);
1947 lf_printf(file, " == 0);\n");
1950 is_0_ptr += strlen("_is_0");
1954 /* any thing else ... */
1957 lf_print_lf_c_line_nr(file);
1962 lf_print_idecode_illegal(lf *file)
1965 lf_printf(file, "return idecode_illegal(%s);\n", cache_idecode_actual);
1967 lf_printf(file, "return semantic_illegal(%s);\n", semantic_actual);
1972 lf_print_idecode_floating_point_unavailable(lf *file)
1975 lf_printf(file, "return idecode_floating_point_unavailable(%s);\n",
1976 cache_idecode_actual);
1978 lf_printf(file, "return semantic_floating_point_unavailable(%s);\n",
1983 /* Output code to do any final checks on the decoded instruction.
1984 This includes things like verifying any on decoded fields have the
1985 correct value and checking that (for floating point) floating point
1986 hardware isn't disabled */
1989 lf_print_c_validate(lf *file,
1991 opcode_field *opcodes)
1993 /* Validate: unchecked instruction fields
1995 If any constant fields in the instruction were not checked by the
1996 idecode tables, output code to check that they have the correct
1999 unsigned check_mask = 0;
2000 unsigned check_val = 0;
2002 opcode_field *opcode;
2004 /* form check_mask/check_val containing what needs to be checked
2005 in the instruction */
2006 for (field = instruction->fields->first;
2007 field->first < insn_size;
2008 field = field->next) {
2010 check_mask <<= field->width;
2011 check_val <<= field->width;
2013 /* is it a constant that could need validating? */
2014 if (!field->is_int && !field->is_slash)
2017 /* has it been checked by a table? */
2018 for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
2019 if (field->first >= opcode->first
2020 && field->last <= opcode->last)
2026 check_mask |= (1 << field->width)-1;
2027 check_val |= field->val_int;
2030 /* if any bits not checked by opcode tables, output code to check them */
2032 lf_printf(file, "\n");
2033 lf_printf(file, "/* validate: %s */\n",
2034 instruction->file_entry->fields[insn_format]);
2035 lf_printf(file, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
2036 check_mask, check_val);
2037 lf_indent(file, +2);
2038 lf_print_idecode_illegal(file);
2039 lf_indent(file, -2);
2043 /* Validate floating point hardware
2045 If the simulator is being built with out floating point hardware
2046 (different to it being disabled in the MSR) then floating point
2047 instructions are invalid */
2049 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2050 lf_printf(file, "\n");
2051 lf_printf(file, "/* Validate: FP hardware exists */\n");
2052 lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
2053 lf_indent(file, +2);
2054 lf_print_idecode_illegal(file);
2055 lf_indent(file, -2);
2059 /* Validate: Floating Point available
2061 If floating point is not available, we enter a floating point
2062 unavailable interrupt into the cache instead of the instruction
2065 The PowerPC spec requires a CSI after MSR[FP] is changed and when
2066 ever a CSI occures we flush the instruction cache. */
2069 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2070 lf_printf(file, "\n");
2071 lf_printf(file, "/* Validate: FP available according to MSR[FP] */\n");
2072 lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n");
2073 lf_indent(file, +2);
2074 lf_print_idecode_floating_point_unavailable(file);
2075 lf_indent(file, -2);
2082 lf_print_c_cracker(lf *file,
2084 insn_bits *expanded_bits,
2085 opcode_field *opcodes)
2088 /* function header */
2089 lf_printf(file, "{\n");
2090 lf_indent(file, +2);
2092 lf_print_my_prefix(file,
2093 instruction->file_entry,
2094 1/*putting-value-in-cache*/);
2096 lf_print_ptrace(file,
2097 1/*putting-value-in-cache*/);
2099 lf_print_c_validate(file, instruction, opcodes);
2101 lf_printf(file, "\n");
2102 lf_printf(file, "{\n");
2103 lf_indent(file, +2);
2104 lf_print_c_extractions(file,
2107 0/*get_value_from_cache*/,
2108 1/*put_value_in_cache*/);
2109 lf_indent(file, -2);
2110 lf_printf(file, "}\n");
2112 /* return the function propper (main sorts this one out) */
2113 lf_printf(file, "\n");
2114 lf_printf(file, "/* semantic routine */\n");
2115 table_entry_lf_c_line_nr(file, instruction->file_entry);
2116 lf_printf(file, "return ");
2117 lf_print_function_name(file,
2118 instruction->file_entry->fields[insn_name],
2120 function_name_prefix_semantics);
2121 lf_printf(file, ";\n");
2123 lf_print_lf_c_line_nr(file);
2124 lf_indent(file, -2);
2125 lf_printf(file, "}\n");
2130 lf_print_c_semantic(lf *file,
2132 insn_bits *expanded_bits,
2133 opcode_field *opcodes)
2136 lf_printf(file, "{\n");
2137 lf_indent(file, +2);
2139 lf_print_my_prefix(file,
2140 instruction->file_entry,
2141 0/*not putting value in cache*/);
2142 lf_printf(file, "unsigned_word nia = cia + %d;\n", insn_size / 8);
2144 lf_printf(file, "\n");
2145 lf_print_c_extractions(file,
2148 idecode_cache/*get_value_from_cache*/,
2149 0/*put_value_in_cache*/);
2151 lf_print_ptrace(file,
2152 0/*put_value_in_cache*/);
2154 /* validate the instruction, if a cache this has already been done */
2156 lf_print_c_validate(file, instruction, opcodes);
2158 /* generate the profiling call - this is delayed until after the
2159 instruction has been verified */
2160 lf_printf(file, "\n");
2161 lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE) {\n");
2162 lf_printf(file, " mon_issue(");
2163 lf_print_function_name(file,
2164 instruction->file_entry->fields[insn_name],
2166 function_name_prefix_itable);
2167 lf_printf(file, ", processor, cia);\n");
2168 lf_printf(file, "}\n");
2169 lf_printf(file, "\n");
2171 /* generate the code (or at least something */
2172 if (instruction->file_entry->annex != NULL) {
2174 lf_printf(file, "\n");
2175 table_entry_lf_c_line_nr(file, instruction->file_entry);
2176 lf_printf(file, "{\n");
2177 lf_indent(file, +2);
2178 lf_print_c_code(file, instruction->file_entry->annex);
2179 lf_indent(file, -2);
2180 lf_printf(file, "}\n");
2181 lf_print_lf_c_line_nr(file);
2183 else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
2184 lf_print_lf_c_line_nr(file);
2186 else if (it_is("f", instruction->file_entry->fields[insn_flags])) {
2187 /* unimplemented floating point instruction - call for assistance */
2188 lf_printf(file, "\n");
2189 lf_printf(file, "/* unimplemented floating point instruction - call for assistance */\n");
2190 table_entry_lf_c_line_nr(file, instruction->file_entry);
2191 lf_putstr(file, "floating_point_assist_interrupt(processor, cia);\n");
2192 lf_print_lf_c_line_nr(file);
2195 /* abort so it is implemented now */
2196 table_entry_lf_c_line_nr(file, instruction->file_entry);
2197 lf_putstr(file, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2198 lf_print_lf_c_line_nr(file);
2199 lf_printf(file, "\n");
2202 lf_printf(file, "return nia;\n");
2203 lf_indent(file, -2);
2204 lf_printf(file, "}\n");
2208 lf_print_c_semantic_function(lf *file,
2210 insn_bits *expanded_bits,
2211 opcode_field *opcodes,
2212 int is_inline_function)
2214 insn_undef *undef, *next;
2216 /* build the semantic routine to execute the instruction */
2217 lf_print_semantic_function_header(file,
2218 instruction->file_entry->fields[insn_name],
2220 1/*is-function-definition*/,
2221 is_inline_function);
2222 lf_print_c_semantic(file,
2227 /* If we are referencing the cache structure directly instead of putting the values
2228 in local variables, undef any defines we created */
2229 for(undef = first_undef; undef; undef = next) {
2231 lf_indent_suppress(file);
2232 lf_printf(file, "#undef %s\n", undef->name);
2233 free((void *)undef);
2235 first_undef = (insn_undef *)0;
2236 last_undef = (insn_undef *)0;
2241 semantics_c_leaf(insn_table *entry,
2245 lf *file = (lf*)data;
2246 ASSERT(entry->nr_insn == 1
2247 && entry->opcode == NULL
2248 && entry->parent != NULL
2249 && entry->parent->opcode != NULL);
2250 lf_print_c_semantic_function(file,
2252 entry->expanded_bits,
2253 entry->parent->opcode,
2254 !idecode_cache && entry->parent->opcode_rule->use_switch);
2258 semantics_c_insn(insn_table *table,
2262 lf *file = (lf*)data;
2263 lf_print_c_semantic_function(file, instruction,
2265 0/*isnt_inline_function*/);
2269 semantics_c_function(insn_table *table,
2271 table_entry *function)
2273 lf *file = (lf*)data;
2274 if (function->fields[function_type] == NULL
2275 || function->fields[function_type][0] == '\0') {
2276 lf_print_semantic_function_header(file,
2277 function->fields[function_name],
2279 1/*is function definition*/,
2280 1/*is inline function*/);
2283 lf_printf(file, "\n");
2284 lf_print_function_type(file, function->fields[function_type],
2285 "INLINE_SEMANTICS", "\n");
2286 lf_printf(file, "%s(%s)\n",
2287 function->fields[function_name],
2288 function->fields[function_param]);
2290 table_entry_lf_c_line_nr(file, function);
2291 lf_printf(file, "{\n");
2292 lf_indent(file, +2);
2293 lf_print_c_code(file, function->annex);
2294 lf_indent(file, -2);
2295 lf_printf(file, "}\n");
2296 lf_print_lf_c_line_nr(file);
2302 gen_semantics_c(insn_table *table, lf *file)
2304 lf_print_copyleft(file);
2305 lf_printf(file, "\n");
2306 lf_printf(file, "#ifndef _SEMANTICS_C_\n");
2307 lf_printf(file, "#define _SEMANTICS_C_\n");
2308 lf_printf(file, "\n");
2309 lf_printf(file, "#include \"cpu.h\"\n");
2310 lf_printf(file, "#include \"idecode.h\"\n");
2311 lf_printf(file, "#include \"semantics.h\"\n");
2312 lf_printf(file, "\n");
2314 /* output a definition (c-code) for all functions */
2315 insn_table_traverse_function(table,
2317 semantics_c_function);
2319 /* output a definition (c-code) for all instructions */
2320 if (idecode_expand_semantics)
2321 insn_table_traverse_tree(table,
2327 NULL); /* padding */
2329 insn_table_traverse_insn(table,
2333 lf_printf(file, "\n");
2334 lf_printf(file, "#endif /* _SEMANTICS_C_ */\n");
2338 /****************************************************************/
2341 gen_idecode_h(insn_table *table, lf *file)
2343 lf_print_copyleft(file);
2344 lf_printf(file, "\n");
2345 lf_printf(file, "#ifndef _IDECODE_H_\n");
2346 lf_printf(file, "#define _IDECODE_H_\n");
2347 lf_printf(file, "\n");
2348 lf_printf(file, "#include \"idecode_expression.h\"\n");
2349 lf_printf(file, "#include \"idecode_fields.h\"\n");
2350 lf_printf(file, "#include \"idecode_branch.h\"\n");
2351 lf_printf(file, "\n");
2352 lf_printf(file, "#include \"icache.h\"\n");
2353 lf_printf(file, "\n");
2354 lf_printf(file, "typedef unsigned_word idecode_semantic\n(%s);\n",
2355 (idecode_cache ? cache_semantic_formal : semantic_formal));
2356 lf_printf(file, "\n");
2357 if (idecode_cache) {
2358 lf_print_function_type(file, "idecode_semantic *", "INLINE_IDECODE", " ");
2359 lf_printf(file, "idecode\n(%s);\n", cache_idecode_formal);
2362 lf_print_function_type(file, "unsigned_word", "INLINE_IDECODE", " ");
2363 lf_printf(file, "idecode_issue\n(%s);\n", semantic_formal);
2365 lf_printf(file, "\n");
2366 lf_printf(file, "#endif /* _IDECODE_H_ */\n");
2370 /****************************************************************/
2374 idecode_table_start(insn_table *table,
2378 lf *file = (lf*)data;
2380 /* start of the table */
2381 if (!table->opcode_rule->use_switch) {
2382 lf_printf(file, "\n");
2383 lf_printf(file, "static idecode_table_entry ");
2384 lf_print_table_name(file, table);
2385 lf_printf(file, "[] = {\n");
2390 idecode_table_leaf(insn_table *entry,
2394 lf *file = (lf*)data;
2395 ASSERT(entry->parent != NULL);
2398 /* add an entry to the table */
2399 if (!entry->parent->opcode_rule->use_switch) {
2400 if (entry->opcode == NULL) {
2401 /* table leaf entry */
2402 lf_printf(file, " /*%d*/ { 0, 0, ", entry->opcode_nr);
2403 lf_print_function_name(file,
2404 entry->insns->file_entry->fields[insn_name],
2405 entry->expanded_bits,
2407 ? function_name_prefix_idecode
2408 : function_name_prefix_semantics));
2409 lf_printf(file, " },\n");
2411 else if (entry->opcode_rule->use_switch) {
2412 /* table calling switch statement */
2413 lf_printf(file, " /*%d*/ { 0, 0, ",
2415 lf_print_table_name(file, entry);
2416 lf_printf(file, " },\n");
2419 /* table `calling' another table */
2420 lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
2421 if (entry->opcode->is_boolean)
2422 lf_printf(file, "MASK32(%d,%d), 0, ",
2423 i2target(hi_bit_nr, entry->opcode->first),
2424 i2target(hi_bit_nr, entry->opcode->last));
2426 lf_printf(file, "%d, MASK32(%d,%d), ",
2427 insn_size - entry->opcode->last - 1,
2428 i2target(hi_bit_nr, entry->opcode->first),
2429 i2target(hi_bit_nr, entry->opcode->last));
2430 lf_print_table_name(file, entry);
2431 lf_printf(file, " },\n");
2437 idecode_table_end(insn_table *table,
2441 lf *file = (lf*)data;
2444 if (!table->opcode_rule->use_switch) {
2445 lf_printf(file, "};\n");
2450 idecode_table_padding(insn_table *table,
2455 lf *file = (lf*)data;
2458 if (!table->opcode_rule->use_switch) {
2459 lf_printf(file, " /*%d*/ { 0, 0, %s_illegal },\n",
2460 opcode_nr, (idecode_cache ? "idecode" : "semantic"));
2465 /****************************************************************/
2468 void lf_print_idecode_switch
2474 idecode_switch_start(insn_table *table,
2478 lf *file = (lf*)data;
2480 ASSERT(table->opcode_rule->use_switch);
2482 lf_printf(file, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2483 i2target(hi_bit_nr, table->opcode->first),
2484 i2target(hi_bit_nr, table->opcode->last));
2489 idecode_switch_leaf(insn_table *entry,
2493 lf *file = (lf*)data;
2494 ASSERT(entry->parent != NULL);
2496 ASSERT(entry->parent->opcode_rule->use_switch);
2497 ASSERT(entry->parent->opcode);
2499 if (!entry->parent->opcode->is_boolean
2500 || entry->opcode_nr == 0)
2501 lf_printf(file, "case %d:\n", entry->opcode_nr);
2503 lf_printf(file, "default:\n");
2504 lf_indent(file, +2);
2506 if (entry->opcode == NULL) {
2507 /* switch calling leaf */
2508 lf_printf(file, "return ");
2509 lf_print_function_name(file,
2510 entry->insns->file_entry->fields[insn_name],
2511 entry->expanded_bits,
2513 ? function_name_prefix_idecode
2514 : function_name_prefix_semantics));
2516 lf_printf(file, "(%s);\n", cache_idecode_actual);
2518 lf_printf(file, "(%s);\n", semantic_actual);
2520 else if (entry->opcode_rule->use_switch) {
2521 /* switch calling switch */
2522 lf_print_idecode_switch(file, entry);
2525 /* switch looking up a table */
2526 lf_print_idecode_table(file, entry);
2528 lf_printf(file, "break;\n");
2530 lf_indent(file, -2);
2535 lf_print_idecode_switch_illegal(lf *file)
2537 lf_indent(file, +2);
2538 lf_print_idecode_illegal(file);
2539 lf_printf(file, "break;\n");
2540 lf_indent(file, -2);
2544 idecode_switch_end(insn_table *table,
2548 lf *file = (lf*)data;
2550 ASSERT(table->opcode_rule->use_switch);
2551 ASSERT(table->opcode);
2553 lf_printf(file, "default:\n");
2554 if (table->opcode_rule->use_switch == 1
2555 && !table->opcode->is_boolean) {
2556 lf_print_idecode_switch_illegal(file);
2559 lf_printf(file, " error(\"igen internal error - bad switch generated\n\");\n");
2561 lf_printf(file, "}\n");
2565 idecode_switch_padding(insn_table *table,
2570 lf *file = (lf*)data;
2573 ASSERT(table->opcode_rule->use_switch);
2575 if (table->opcode_rule->use_switch > 1) {
2576 lf_printf(file, "case %d:\n", opcode_nr);
2577 lf_print_idecode_switch_illegal(file);
2583 lf_print_idecode_switch(lf *file,
2586 insn_table_traverse_tree(table,
2589 idecode_switch_start,
2590 idecode_switch_leaf,
2592 idecode_switch_padding);
2597 lf_print_idecode_switch_function_header(lf *file,
2599 int is_function_definition)
2601 lf_printf(file, "\n");
2602 lf_printf(file, "static ");
2604 lf_printf(file, "idecode_semantic *");
2606 lf_printf(file, "unsigned_word");
2607 if (is_function_definition)
2608 lf_printf(file, "\n");
2610 lf_printf(file, " ");
2611 lf_print_table_name(file, table);
2612 lf_printf(file, "\n(%s)",
2613 (idecode_cache ? cache_idecode_formal : semantic_formal));
2614 if (!is_function_definition)
2615 lf_printf(file, ";");
2616 lf_printf(file, "\n");
2621 idecode_declare_if_switch(insn_table *table,
2625 lf *file = (lf*)data;
2627 if (table->opcode_rule->use_switch
2628 && table->parent != NULL /* don't declare the top one yet */
2629 && !table->parent->opcode_rule->use_switch) {
2630 lf_print_idecode_switch_function_header(file,
2632 0/*isnt function definition*/);
2638 idecode_expand_if_switch(insn_table *table,
2642 lf *file = (lf*)data;
2644 if (table->opcode_rule->use_switch
2645 && table->parent != NULL /* don't expand the top one yet */
2646 && !table->parent->opcode_rule->use_switch) {
2647 lf_print_idecode_switch_function_header(file,
2649 1/*is function definition*/);
2650 lf_printf(file, "{\n");
2652 lf_indent(file, +2);
2653 lf_print_idecode_switch(file, table);
2654 lf_indent(file, -2);
2656 lf_printf(file, "}\n");
2662 lf_print_c_cracker_function(lf *file,
2664 insn_bits *expanded_bits,
2665 opcode_field *opcodes,
2666 int is_inline_function)
2668 /* if needed, generate code to enter this routine into a cache */
2669 lf_printf(file, "\n");
2670 lf_printf(file, "static idecode_semantic *\n");
2671 lf_print_function_name(file,
2672 instruction->file_entry->fields[insn_name],
2674 function_name_prefix_idecode);
2675 lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2677 lf_print_c_cracker(file,
2684 idecode_crack_leaf(insn_table *entry,
2688 lf *file = (lf*)data;
2689 ASSERT(entry->nr_insn == 1
2690 && entry->opcode == NULL
2691 && entry->parent != NULL
2692 && entry->parent->opcode != NULL
2693 && entry->parent->opcode_rule != NULL);
2694 lf_print_c_cracker_function(file,
2696 entry->expanded_bits,
2698 entry->parent->opcode_rule->use_switch);
2702 idecode_crack_insn(insn_table *entry,
2706 lf *file = (lf*)data;
2707 lf_print_c_cracker_function(file,
2711 0/*isnt inline function*/);
2715 idecode_c_internal_function(insn_table *table,
2717 table_entry *function)
2719 lf *file = (lf*)data;
2720 ASSERT(idecode_cache != 0);
2721 if (it_is("internal", function->fields[insn_flags])) {
2722 lf_printf(file, "\n");
2723 lf_print_function_type(file, "idecode_semantic *", "STATIC_INLINE_IDECODE",
2725 lf_print_function_name(file,
2726 function->fields[insn_name],
2728 function_name_prefix_idecode);
2729 lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2730 lf_printf(file, "{\n");
2731 lf_indent(file, +2);
2732 lf_printf(file, "/* semantic routine */\n");
2733 table_entry_lf_c_line_nr(file, function);
2734 lf_printf(file, "return ");
2735 lf_print_function_name(file,
2736 function->fields[insn_name],
2738 function_name_prefix_semantics);
2739 lf_printf(file, ";\n");
2741 lf_print_lf_c_line_nr(file);
2742 lf_indent(file, -2);
2743 lf_printf(file, "}\n");
2748 /****************************************************************/
2751 gen_idecode_c(insn_table *table, lf *file)
2756 lf_print_copyleft(file);
2757 lf_printf(file, "\n");
2758 lf_printf(file, "\n");
2759 lf_printf(file, "#ifndef _IDECODE_C_\n");
2760 lf_printf(file, "#define _IDECODE_C_\n");
2761 lf_printf(file, "\n");
2762 lf_printf(file, "#include \"cpu.h\"\n");
2763 lf_printf(file, "#include \"idecode.h\"\n");
2764 lf_printf(file, "#include \"semantics.h\"\n");
2765 lf_printf(file, "\n");
2766 lf_printf(file, "\n");
2767 lf_printf(file, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2768 (idecode_cache ? cache_idecode_formal : semantic_formal));
2769 lf_printf(file, "\n");
2770 lf_printf(file, "typedef struct _idecode_table_entry {\n");
2771 lf_printf(file, " unsigned shift;\n");
2772 lf_printf(file, " unsigned mask;\n");
2773 lf_printf(file, " void *function_or_table;\n");
2774 lf_printf(file, "} idecode_table_entry;\n");
2775 lf_printf(file, "\n");
2776 lf_printf(file, "\n");
2778 /* output `internal' invalid/floating-point unavailable functions
2780 if (idecode_cache) {
2781 insn_table_traverse_function(table,
2783 idecode_c_internal_function);
2786 /* output cracking functions where needed */
2787 if (idecode_cache) {
2788 if (idecode_expand_semantics)
2789 insn_table_traverse_tree(table,
2797 insn_table_traverse_insn(table,
2799 idecode_crack_insn);
2802 /* output switch function declarations where needed by tables */
2803 insn_table_traverse_tree(table,
2806 idecode_declare_if_switch, /* START */
2809 /* output tables where needed */
2810 for (depth = insn_table_depth(table);
2813 insn_table_traverse_tree(table,
2816 idecode_table_start,
2819 idecode_table_padding);
2822 /* output switch functions where needed */
2823 insn_table_traverse_tree(table,
2826 idecode_expand_if_switch, /* START */
2829 /* output the main idecode routine */
2830 lf_printf(file, "\n");
2831 if (idecode_cache) {
2832 lf_print_function_type(file, "idecode_semantic *", "INLINE_IDECODE", "\n");
2833 lf_printf(file, "idecode\n(%s)\n", cache_idecode_formal);
2836 lf_print_function_type(file, "unsigned_word", "INLINE_IDECODE", "\n");
2837 lf_printf(file, "idecode_issue\n(%s)\n", semantic_formal);
2839 lf_printf(file, "{\n");
2840 lf_indent(file, +2);
2841 if (table->opcode_rule->use_switch)
2842 lf_print_idecode_switch(file, table);
2844 lf_print_idecode_table(file, table);
2845 lf_indent(file, -2);
2846 lf_printf(file, "}\n");
2847 lf_printf(file, "\n");
2848 lf_printf(file, "#endif /* _IDECODE_C_ */\n");
2852 /****************************************************************/
2855 itable_h_insn(insn_table *entry,
2859 lf *file = (lf*)data;
2860 lf_printf(file, " ");
2861 lf_print_function_name(file,
2862 instruction->file_entry->fields[insn_name],
2864 function_name_prefix_itable);
2865 lf_printf(file, ",\n");
2870 gen_itable_h(insn_table *table, lf *file)
2873 lf_print_copyleft(file);
2874 lf_printf(file, "\n");
2875 lf_printf(file, "#ifndef _ITABLE_H_\n");
2876 lf_printf(file, "#define _ITABLE_H_\n");
2877 lf_printf(file, "\n");
2879 /* output an enumerated type for each instruction */
2880 lf_printf(file, "typedef enum {\n");
2881 insn_table_traverse_insn(table,
2884 lf_printf(file, " nr_itable_entries,\n");
2885 lf_printf(file, "} itable_index;\n");
2886 lf_printf(file, "\n");
2888 /* output the table that contains the actual instruction info */
2889 lf_printf(file, "typedef struct _itable_instruction_info {\n");
2890 lf_printf(file, " itable_index nr;\n");
2891 lf_printf(file, " char *format;\n");
2892 lf_printf(file, " char *form;\n");
2893 lf_printf(file, " char *flags;\n");
2894 lf_printf(file, " char *mnemonic;\n");
2895 lf_printf(file, " char *name;\n");
2896 lf_printf(file, "} itable_info;\n");
2897 lf_printf(file, "\n");
2898 lf_printf(file, "extern itable_info itable[nr_itable_entries];\n");
2900 lf_printf(file, "\n");
2901 lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2905 /****************************************************************/
2908 itable_c_insn(insn_table *entry,
2912 lf *file = (lf*)data;
2913 char **fields = instruction->file_entry->fields;
2914 lf_printf(file, " { ");
2915 lf_print_function_name(file,
2916 instruction->file_entry->fields[insn_name],
2918 function_name_prefix_itable);
2919 lf_printf(file, ",\n");
2920 lf_printf(file, " \"%s\",\n", fields[insn_format]);
2921 lf_printf(file, " \"%s\",\n", fields[insn_form]);
2922 lf_printf(file, " \"%s\",\n", fields[insn_flags]);
2923 lf_printf(file, " \"%s\",\n", fields[insn_mnemonic]);
2924 lf_printf(file, " \"%s\",\n", fields[insn_name]);
2925 lf_printf(file, " },\n");
2930 gen_itable_c(insn_table *table, lf *file)
2933 lf_print_copyleft(file);
2934 lf_printf(file, "\n");
2935 lf_printf(file, "#ifndef _ITABLE_C_\n");
2936 lf_printf(file, "#define _ITABLE_C_\n");
2937 lf_printf(file, "\n");
2938 lf_printf(file, "#include \"itable.h\"\n");
2939 lf_printf(file, "\n");
2941 /* output the table that contains the actual instruction info */
2942 lf_printf(file, "itable_info itable[nr_itable_entries] = {\n");
2943 insn_table_traverse_insn(table,
2946 lf_printf(file, "};\n");
2947 lf_printf(file, "\n");
2949 lf_printf(file, "\n");
2950 lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2953 /****************************************************************/
2956 model_c_or_h_data(insn_table *table,
2961 table_entry_lf_c_line_nr(file, data);
2962 lf_print_c_code(file, data->annex);
2963 lf_print_lf_c_line_nr(file);
2964 lf_printf(file, "\n");
2969 model_c_or_h_function(insn_table *entry,
2971 table_entry *function,
2974 if (function->fields[function_type] == NULL
2975 || function->fields[function_type][0] == '\0') {
2976 error("Model function type not specified for %s", function->fields[function_name]);
2978 lf_printf(file, "\n");
2979 lf_print_function_type(file, function->fields[function_type], prefix, " ");
2980 lf_printf(file, "%s\n(%s);\n",
2981 function->fields[function_name],
2982 function->fields[function_param]);
2983 lf_printf(file, "\n");
2987 gen_model_h(insn_table *table, lf *file)
2993 int model_create_p = 0;
2994 int model_init_p = 0;
2995 int model_halt_p = 0;
2996 int model_mon_info_p = 0;
2997 int model_mon_info_free_p = 0;
2999 lf_print_copyleft(file);
3000 lf_printf(file, "\n");
3001 lf_printf(file, "#ifndef _MODEL_H_\n");
3002 lf_printf(file, "#define _MODEL_H_\n");
3003 lf_printf(file, "\n");
3005 for(macro = model_macros; macro; macro = macro->next) {
3006 model_c_or_h_data(table, file, macro->file_entry);
3009 lf_printf(file, "typedef enum _model_enum {\n");
3010 lf_printf(file, " MODEL_NONE,\n");
3011 for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3012 lf_printf(file, " MODEL_%s,\n", model_ptr->name);
3014 lf_printf(file, " nr_models\n");
3015 lf_printf(file, "} model_enum;\n");
3016 lf_printf(file, "\n");
3018 lf_printf(file, "#define DEFAULT_MODEL MODEL_%s\n", (models) ? models->name : "NONE");
3019 lf_printf(file, "\n");
3021 lf_printf(file, "typedef struct _model_data model_data;\n");
3022 lf_printf(file, "typedef struct _model_time model_time;\n");
3023 lf_printf(file, "\n");
3025 lf_printf(file, "extern model_enum current_model;\n");
3026 lf_printf(file, "extern const char *model_name[ (int)nr_models ];\n");
3027 lf_printf(file, "extern const char *const *const model_func_unit_name[ (int)nr_models ];\n");
3028 lf_printf(file, "extern const model_time *const model_time_mapping[ (int)nr_models ];\n");
3029 lf_printf(file, "\n");
3031 for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
3032 model_c_or_h_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
3033 name = insn_ptr->file_entry->fields[function_name];
3034 if (strcmp (name, "model_create") == 0)
3036 else if (strcmp (name, "model_init") == 0)
3038 else if (strcmp (name, "model_halt") == 0)
3040 else if (strcmp (name, "model_mon_info") == 0)
3041 model_mon_info_p = 1;
3042 else if (strcmp (name, "model_mon_info_free") == 0)
3043 model_mon_info_free_p = 1;
3046 if (!model_create_p) {
3047 lf_print_function_type(file, "model_data *", "INLINE_MODEL", " ");
3048 lf_printf(file, "model_create\n");
3049 lf_printf(file, "(cpu *processor);\n");
3050 lf_printf(file, "\n");
3053 if (!model_init_p) {
3054 lf_print_function_type(file, "void", "INLINE_MODEL", " ");
3055 lf_printf(file, "model_init\n");
3056 lf_printf(file, "(model_data *model_ptr);\n");
3057 lf_printf(file, "\n");
3060 if (!model_halt_p) {
3061 lf_print_function_type(file, "void", "INLINE_MODEL", " ");
3062 lf_printf(file, "model_halt\n");
3063 lf_printf(file, "(model_data *model_ptr);\n");
3064 lf_printf(file, "\n");
3067 if (!model_mon_info_p) {
3068 lf_print_function_type(file, "model_print *", "INLINE_MODEL", " ");
3069 lf_printf(file, "model_mon_info\n");
3070 lf_printf(file, "(model_data *model_ptr);\n");
3071 lf_printf(file, "\n");
3074 if (!model_mon_info_free_p) {
3075 lf_print_function_type(file, "void", "INLINE_MODEL", " ");
3076 lf_printf(file, "model_mon_info_free\n");
3077 lf_printf(file, "(model_data *model_ptr,\n");
3078 lf_printf(file, " model_print *info_ptr);\n");
3079 lf_printf(file, "\n");
3082 lf_print_function_type(file, "void", "INLINE_MODEL", " ");
3083 lf_printf(file, "model_set\n");
3084 lf_printf(file, "(const char *name);\n");
3085 lf_printf(file, "\n");
3086 lf_printf(file, "#endif /* _MODEL_H_ */\n");
3089 /****************************************************************/
3091 typedef struct _model_c_passed_data model_c_passed_data;
3092 struct _model_c_passed_data {
3098 model_c_insn(insn_table *entry,
3102 model_c_passed_data *data_ptr = (model_c_passed_data *)data;
3103 lf *file = data_ptr->file;
3104 char *current_name = data_ptr->model_ptr->printable_name;
3105 table_model_entry *model_ptr = instruction->file_entry->model_first;
3108 if (model_ptr->fields[insn_model_name] == current_name) {
3109 lf_printf(file, " { %-*s }, /* %s */\n",
3110 max_model_fields_len,
3111 model_ptr->fields[insn_model_fields],
3112 instruction->file_entry->fields[insn_name]);
3116 model_ptr = model_ptr->next;
3119 lf_printf(file, " { %-*s }, /* %s */\n",
3120 max_model_fields_len,
3121 data_ptr->model_ptr->insn_default,
3122 instruction->file_entry->fields[insn_name]);
3126 model_c_function(insn_table *table,
3128 table_entry *function,
3131 if (function->fields[function_type] == NULL
3132 || function->fields[function_type][0] == '\0') {
3133 error("Model function return type not specified for %s", function->fields[function_name]);
3136 lf_printf(file, "\n");
3137 lf_print_function_type(file, function->fields[function_type], prefix, "\n");
3138 lf_printf(file, "%s(%s)\n",
3139 function->fields[function_name],
3140 function->fields[function_param]);
3142 table_entry_lf_c_line_nr(file, function);
3143 lf_printf(file, "{\n");
3144 if (function->annex) {
3145 lf_indent(file, +2);
3146 lf_print_c_code(file, function->annex);
3147 lf_indent(file, -2);
3149 lf_printf(file, "}\n");
3150 lf_print_lf_c_line_nr(file);
3151 lf_printf(file, "\n");
3155 gen_model_c(insn_table *table, lf *file)
3160 int model_create_p = 0;
3161 int model_init_p = 0;
3162 int model_halt_p = 0;
3163 int model_mon_info_p = 0;
3164 int model_mon_info_free_p = 0;
3166 lf_print_copyleft(file);
3167 lf_printf(file, "\n");
3168 lf_printf(file, "#ifndef _MODEL_C_\n");
3169 lf_printf(file, "#define _MODEL_C_\n");
3170 lf_printf(file, "\n");
3171 lf_printf(file, "#include \"cpu.h\"\n");
3172 lf_printf(file, "#include \"mon.h\"\n");
3173 lf_printf(file, "\n");
3174 lf_printf(file, "#ifdef HAVE_STDLIB_H\n");
3175 lf_printf(file, "#include <stdlib.h>\n");
3176 lf_printf(file, "#endif\n");
3177 lf_printf(file, "\n");
3179 for(insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) {
3180 model_c_or_h_data(table, file, insn_ptr->file_entry);
3183 for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
3184 model_c_or_h_function(table, file, insn_ptr->file_entry, "/*h*/STATIC");
3187 for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
3188 model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
3191 for(insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) {
3192 model_c_function(table, file, insn_ptr->file_entry, "/*c*/STATIC");
3195 for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
3196 model_c_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
3199 for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
3200 model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
3201 name = insn_ptr->file_entry->fields[function_name];
3202 if (strcmp (name, "model_create") == 0)
3204 else if (strcmp (name, "model_init") == 0)
3206 else if (strcmp (name, "model_halt") == 0)
3208 else if (strcmp (name, "model_mon_info") == 0)
3209 model_mon_info_p = 1;
3210 else if (strcmp (name, "model_mon_info_free") == 0)
3211 model_mon_info_free_p = 1;
3214 if (!model_create_p) {
3215 lf_print_function_type(file, "model_data *", "INLINE_MODEL", "\n");
3216 lf_printf(file, "model_create(cpu *processor)\n");
3217 lf_printf(file, "{\n");
3218 lf_printf(file, " return (model_data *)0;\n");
3219 lf_printf(file, "}\n");
3220 lf_printf(file, "\n");
3223 if (!model_init_p) {
3224 lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
3225 lf_printf(file, "model_init(model_data *model_ptr)\n");
3226 lf_printf(file, "{\n");
3227 lf_printf(file, "}\n");
3228 lf_printf(file, "\n");
3231 if (!model_halt_p) {
3232 lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
3233 lf_printf(file, "model_halt(model_data *model_ptr)\n");
3234 lf_printf(file, "{\n");
3235 lf_printf(file, "}\n");
3236 lf_printf(file, "\n");
3239 if (!model_mon_info_p) {
3240 lf_print_function_type(file, "model_print *", "INLINE_MODEL", "\n");
3241 lf_printf(file, "model_mon_info(model_data *model_ptr)\n");
3242 lf_printf(file, "{\n");
3243 lf_printf(file, " return (model_print *)0;\n");
3244 lf_printf(file, "}\n");
3245 lf_printf(file, "\n");
3248 if (!model_mon_info_free_p) {
3249 lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
3250 lf_printf(file, "model_mon_info_free(model_data *model_ptr,\n");
3251 lf_printf(file, " model_print *info_ptr)\n");
3252 lf_printf(file, "{\n");
3253 lf_printf(file, "}\n");
3254 lf_printf(file, "\n");
3257 lf_printf(file, "/* Insn functional unit info */\n");
3258 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3259 model_c_passed_data data;
3261 lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
3263 data.model_ptr = model_ptr;
3264 insn_table_traverse_insn(table,
3268 lf_printf(file, "};\n");
3269 lf_printf(file, "\n");
3270 lf_printf(file, "\f\n");
3273 lf_printf(file, "#ifndef _INLINE_C_\n");
3274 lf_printf(file, "const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3275 lf_printf(file, " (const model_time *const)0,\n");
3276 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3277 lf_printf(file, " model_time_%s,\n", model_ptr->name);
3279 lf_printf(file, "};\n");
3280 lf_printf(file, "#endif\n");
3281 lf_printf(file, "\n");
3283 lf_printf(file, "\f\n");
3284 lf_printf(file, "/* map model enumeration into printable string */\n");
3285 lf_printf(file, "#ifndef _INLINE_C_\n");
3286 lf_printf(file, "const char *model_name[ (int)nr_models ] = {\n");
3287 lf_printf(file, " \"NONE\",\n");
3288 for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3289 lf_printf(file, " \"%s\",\n", model_ptr->printable_name);
3291 lf_printf(file, "};\n");
3292 lf_printf(file, "#endif\n");
3293 lf_printf(file, "\n");
3295 lf_print_function_type(file, "void", "INLINE_MODEL", "\n");
3296 lf_printf(file, "model_set(const char *name)\n");
3297 lf_printf(file, "{\n");
3299 lf_printf(file, " model_enum model;\n");
3300 lf_printf(file, " for(model = MODEL_%s; model < nr_models; model++) {\n", models->name);
3301 lf_printf(file, " if(strcmp(name, model_name[model]) == 0) {\n");
3302 lf_printf(file, " current_model = model;\n");
3303 lf_printf(file, " return;\n");
3304 lf_printf(file, " }\n");
3305 lf_printf(file, " }\n");
3306 lf_printf(file, "\n");
3307 lf_printf(file, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3308 lf_printf(file, " name,\n");
3309 lf_printf(file, " \"");
3310 for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
3311 lf_printf(file, "\\n\\t%s", model_ptr->printable_name);
3313 lf_printf(file, "\");\n");
3315 lf_printf(file, " error(\"No models are currently known about\");\n");
3318 lf_printf(file, "}\n");
3319 lf_printf(file, "\n");
3321 lf_printf(file, "#endif /* _MODEL_C_ */\n");
3325 /****************************************************************/
3333 insn_table *instructions = NULL;
3334 icache_tree *cache_fields = NULL;
3335 char *real_file_name = NULL;
3340 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
3341 printf("Config options:\n");
3342 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
3343 printf(" -e Expand (duplicate) semantic functions\n");
3344 printf(" -r <icache-size> Generate cracking cache version\n");
3345 printf(" -R Use defines to reference cache vars\n");
3346 printf(" -l Supress line numbering in output files\n");
3347 printf(" -b <bit-size> Set the number of bits in an instruction\n");
3348 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
3350 printf("Input options (ucase version also dumps loaded table):\n");
3351 printf(" -[Oo] <opcode-rules>\n");
3352 printf(" -[Kk] <cache-rules>\n");
3353 printf(" -[Ii] <instruction-table>\n");
3355 printf("Output options:\n");
3356 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
3357 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
3358 printf(" -[Mm] <output-file> output model.h(M) model.c(M)\n");
3359 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
3360 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
3363 while ((ch = getopt(argc, argv,
3364 "leb:h:r:Rf:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
3365 fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : ""));
3371 idecode_expand_semantics = 1;
3374 idecode_cache = a2i(optarg);
3377 semantics_use_cache_struct = 1;
3380 insn_size = a2i(optarg);
3381 ASSERT(insn_size > 0 && insn_size <= max_insn_size
3382 && (hi_bit_nr == insn_size-1 || hi_bit_nr == 0));
3385 hi_bit_nr = a2i(optarg);
3386 ASSERT(hi_bit_nr == insn_size-1 || hi_bit_nr == 0);
3390 filter *new_filter = ZALLOC(filter);
3391 new_filter->flag = strdup(optarg);
3392 new_filter->next = filters;
3393 filters = new_filter;
3398 ASSERT(opcode_table != NULL);
3399 ASSERT(cache_table != NULL);
3400 instructions = insn_table_load_insns(optarg);
3401 fprintf(stderr, "\texpanding ...\n");
3402 insn_table_expand_insns(instructions);
3403 fprintf(stderr, "\tcache fields ...\n");
3404 cache_fields = insn_table_cache_fields(instructions);
3406 dump_traverse(instructions);
3407 dump_insn_table(instructions, 0, 1);
3412 opcode_table = load_opcode_rules(optarg);
3414 dump_opcode_rules(opcode_table, 0);
3418 cache_table = load_cache_rules(optarg);
3420 dump_cache_rules(cache_table, 0);
3423 real_file_name = strdup(optarg);
3435 lf *file = lf_open(optarg, real_file_name, number_lines);
3436 ASSERT(instructions != NULL);
3439 gen_semantics_h(instructions, file);
3442 gen_semantics_c(instructions, file);
3445 gen_idecode_h(instructions, file);
3448 gen_idecode_c(instructions, file);
3451 gen_model_h(instructions, file);
3454 gen_model_c(instructions, file);
3457 gen_itable_h(instructions, file);
3460 gen_itable_c(instructions, file);
3463 gen_icache_h(cache_fields, file);
3468 real_file_name = NULL;
3471 error("unknown option\n");