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.
31 /****************************************************************/
37 int idecode_expand_semantics = 0;
38 int idecode_cache = 0;
42 /****************************************************************/
45 char *cache_idecode_formal = "cpu *processor,\n instruction_word instruction,\n unsigned_word cia,\n idecode_cache *cache_entry";
46 char *cache_idecode_actual = "processor, instruction, cia, cache_entry";
48 char *cache_semantic_formal = "cpu *processor,\n idecode_cache *cache_entry,\n unsigned_word cia";
49 char *cache_semantic_actual = "processor, entry, cia";
51 char *semantic_formal = "cpu *processor,\n instruction_word instruction,\n unsigned_word cia";
52 char *semantic_actual = "processor, instruction, cia";
54 char *semantic_local = "unsigned_word nia = cia + 4;";
57 /****************************************************************/
60 typedef struct _filter filter;
65 filter *filters = NULL;
68 /****************************************************************/
71 typedef struct _cache_rules cache_rules;
80 cache_rules *cache_table;
93 load_cache_rules(char *file_name)
95 table *file = table_open(file_name, nr_cache_rule_fields);
97 cache_rules *table = NULL;
98 cache_rules **curr_rule = &table;
99 while ((entry = table_entry_read(file)) != NULL) {
100 cache_rules *new_rule = ZALLOC(cache_rules);
101 new_rule->valid = a2i(entry->fields[ca_valid]);
102 new_rule->old_name = entry->fields[ca_old_name];
103 new_rule->new_name = entry->fields[ca_new_name];
104 new_rule->type = (strlen(entry->fields[ca_type])
105 ? entry->fields[ca_type]
107 new_rule->expression = (strlen(entry->fields[ca_expression]) > 0
108 ? entry->fields[ca_expression]
110 *curr_rule = new_rule;
111 curr_rule = &new_rule->next;
119 dump_cache_rule(cache_rules* rule,
122 dumpf(indent, "((cache_rules*)0x%x\n", rule);
123 dumpf(indent, " (valid %d)\n", rule->valid);
124 dumpf(indent, " (old_name \"%s\")\n", rule->old_name);
125 dumpf(indent, " (new_name \"%s\")\n", rule->new_name);
126 dumpf(indent, " (type \"%s\")\n", rule->type);
127 dumpf(indent, " (expression \"%s\")\n", rule->expression);
128 dumpf(indent, " (next 0x%x)\n", rule->next);
129 dumpf(indent, " )\n");
134 dump_cache_rules(cache_rules* rule, int indent)
137 dump_cache_rule(rule, indent);
143 /****************************************************************/
146 typedef struct _opcode_rules opcode_rules;
147 struct _opcode_rules {
153 char *force_expansion;
155 unsigned special_mask;
156 unsigned special_value;
157 unsigned special_rule;
160 opcode_rules *opcode_table;
178 static opcode_rules *
179 load_opcode_rules(char *file_name)
181 table *file = table_open(file_name, nr_opcode_fields);
183 opcode_rules *table = NULL;
184 opcode_rules **curr_rule = &table;
185 while ((entry = table_entry_read(file)) != NULL) {
186 opcode_rules *new_rule = ZALLOC(opcode_rules);
187 new_rule->first = a2i(entry->fields[op_first]);
188 new_rule->last = a2i(entry->fields[op_last]);
189 new_rule->force_first = a2i(entry->fields[op_force_first]);
190 new_rule->force_last = a2i(entry->fields[op_force_last]);
191 new_rule->force_slash = a2i(entry->fields[op_force_slash]);
192 new_rule->force_expansion = entry->fields[op_force_expansion];
193 new_rule->use_switch = a2i(entry->fields[op_use_switch]);
194 new_rule->special_mask = a2i(entry->fields[op_special_mask]);
195 new_rule->special_value = a2i(entry->fields[op_special_value]);
196 new_rule->special_rule = a2i(entry->fields[op_special_rule]);
197 *curr_rule = new_rule;
198 curr_rule = &new_rule->next;
205 dump_opcode_rule(opcode_rules *rule,
208 dumpf(indent, "((opcode_rules*)%p\n", rule);
210 dumpf(indent, " (first %d)\n", rule->first);
211 dumpf(indent, " (last %d)\n", rule->last);
212 dumpf(indent, " (force_first %d)\n", rule->force_first);
213 dumpf(indent, " (force_last %d)\n", rule->force_last);
214 dumpf(indent, " (force_slash %d)\n", rule->force_slash);
215 dumpf(indent, " (force_expansion \"%s\")\n", rule->force_expansion);
216 dumpf(indent, " (use_switch %d)\n", rule->use_switch);
217 dumpf(indent, " (special_mask 0x%x)\n", rule->special_mask);
218 dumpf(indent, " (special_value 0x%x)\n", rule->special_value);
219 dumpf(indent, " (special_rule 0x%x)\n", rule->special_rule);
220 dumpf(indent, " (next 0x%x)\n", rule->next);
222 dumpf(indent, " )\n");
227 dump_opcode_rules(opcode_rules *rule,
231 dump_opcode_rule(rule, indent);
237 /****************************************************************/
239 typedef struct _insn_field insn_field;
254 typedef struct _insn_fields insn_fields;
255 struct _insn_fields {
256 insn_field *bits[insn_size];
263 parse_insn_format(table_entry *entry,
267 insn_fields *fields = ZALLOC(insn_fields);
269 /* create a leading sentinal */
270 fields->first = ZALLOC(insn_field);
271 fields->first->first = -1;
272 fields->first->last = -1;
273 fields->first->width = 0;
275 /* and a trailing sentinal */
276 fields->last = ZALLOC(insn_field);
277 fields->last->first = insn_size;
278 fields->last->last = insn_size;
279 fields->last->width = 0;
281 /* link them together */
282 fields->first->next = fields->last;
283 fields->last->prev = fields->first;
285 /* now work through the formats */
288 while (*chp != '\0') {
293 insn_field *new_field;
296 if (!isdigit(*chp)) {
297 error("%s:%d: missing position field at `%s'\n",
298 entry->file_name, entry->line_nr, chp);
301 /* break out the bit position */
303 while (isdigit(*chp))
305 strlen_pos = chp - start_pos;
306 if (*chp == '.' && strlen_pos > 0)
309 error("%s:%d: missing field value at %s\n",
310 entry->file_name, entry->line_nr, chp);
314 /* break out the value */
316 while ((*start_val == '/' && *chp == '/')
317 || (isdigit(*start_val) && isdigit(*chp))
318 || (isalpha(*start_val) && (isalnum(*chp) || *chp == '_')))
320 strlen_val = chp - start_val;
323 else if (*chp != '\0' || strlen_val == 0) {
324 error("%s:%d: missing field terminator at %s\n",
325 entry->file_name, entry->line_nr, chp);
329 /* create a new field and insert it */
330 new_field = ZALLOC(insn_field);
331 new_field->next = fields->last;
332 new_field->prev = fields->last->prev;
333 new_field->next->prev = new_field;
334 new_field->prev->next = new_field;
337 new_field->val_string = (char*)zalloc(strlen_val+1);
338 strncpy(new_field->val_string, start_val, strlen_val);
339 if (isdigit(*new_field->val_string)) {
340 new_field->val_int = a2i(new_field->val_string);
341 new_field->is_int = 1;
343 else if (new_field->val_string[0] == '/') {
344 new_field->is_slash = 1;
347 new_field->is_string = 1;
351 new_field->pos_string = (char*)zalloc(strlen_pos+1);
352 strncpy(new_field->pos_string, start_pos, strlen_pos);
353 new_field->first = a2i(new_field->pos_string);
354 new_field->last = new_field->next->first - 1; /* guess */
355 new_field->width = new_field->last - new_field->first + 1; /* guess */
356 new_field->prev->last = new_field->first-1; /*fix*/
357 new_field->prev->width = new_field->first - new_field->prev->first; /*fix*/
360 /* fiddle first/last so that the sentinals `disapear' */
361 ASSERT(fields->first->last < 0);
362 ASSERT(fields->last->first >= insn_size);
363 fields->first = fields->first->next;
364 fields->last = fields->last->prev;
366 /* now go over this again, pointing each bit position at a field
371 field = fields->first;
372 for (i = 0; i < insn_size; i++) {
373 while (field->last < i)
375 fields->bits[i] = field;
379 /* go over each of the fields, and compute a `value' for the insn */
383 for (field = fields->first;
384 field->last < insn_size;
385 field = field->next) {
386 fields->value <<= field->width;
388 fields->value |= field->val_int;
396 field_constant_int = 1,
397 field_constant_slash = 2,
398 field_constant_string = 3
399 } constant_field_types;
403 insn_field_is_constant(insn_field *field,
406 /* field is an integer */
408 return field_constant_int;
409 /* field is `/' and treating that as a constant */
410 if (field->is_slash && rule->force_slash)
411 return field_constant_slash;
412 /* field, though variable is on the list */
413 if (field->is_string && rule->force_expansion != NULL) {
414 char *forced_fields = rule->force_expansion;
415 while (*forced_fields != '\0') {
417 char *end = strchr(forced_fields, ',');
419 field_len = strlen(forced_fields);
421 field_len = end-forced_fields;
422 if (strncmp(forced_fields, field->val_string, field_len) == 0
423 && field->val_string[field_len] == '\0')
424 return field_constant_string;
425 forced_fields += field_len;
426 if (*forced_fields == ',')
435 dump_insn_field(insn_field *field,
439 printf("(insn_field*)0x%x\n", (unsigned)field);
441 dumpf(indent, "(first %d)\n", field->first);
443 dumpf(indent, "(last %d)\n", field->last);
445 dumpf(indent, "(width %d)\n", field->width);
448 dumpf(indent, "(is_int %d)\n", field->val_int);
451 dumpf(indent, "(is_slash)\n");
453 if (field->is_string)
454 dumpf(indent, "(is_string `%s')\n", field->val_string);
456 dumpf(indent, "(next 0x%x)\n", field->next);
458 dumpf(indent, "(prev 0x%x)\n", field->prev);
464 dump_insn_fields(insn_fields *fields,
469 printf("(insn_fields*)%p\n", fields);
471 dumpf(indent, "(first 0x%x)\n", fields->first);
472 dumpf(indent, "(last 0x%x)\n", fields->last);
474 dumpf(indent, "(value 0x%x)\n", fields->value);
476 for (i = 0; i < insn_size; i++) {
477 dumpf(indent, "(bits[%d] ", i, fields->bits[i]);
478 dump_insn_field(fields->bits[i], indent+1);
479 dumpf(indent, " )\n");
485 /****************************************************************/
487 typedef struct _opcode_field opcode_field;
488 struct _opcode_field {
492 opcode_field *parent;
495 static opcode_field *
498 opcode_field *new_field = (opcode_field*)zalloc(sizeof(opcode_field));
499 ASSERT(new_field != NULL);
500 new_field->first = insn_size;
501 new_field->last = -1;
506 dump_opcode_field(opcode_field *field, int indent, int levels)
508 printf("(opcode_field*)%p\n", field);
509 if (levels && field != NULL) {
510 dumpf(indent, "(first %d)\n", field->first);
511 dumpf(indent, "(last %d)\n", field->last);
512 dumpf(indent, "(is_boolean %d)\n", field->is_boolean);
513 dumpf(indent, "(parent ");
514 dump_opcode_field(field->parent, indent, levels-1);
519 /****************************************************************/
521 typedef struct _insn_bits insn_bits;
526 opcode_field *opcode;
532 dump_insn_bits(insn_bits *bits, int indent, int levels)
534 printf("(insn_bits*)%p\n", bits);
536 if (levels && bits != NULL) {
537 dumpf(indent, "(value %d)\n", bits->value);
538 dumpf(indent, "(opcode ");
539 dump_opcode_field(bits->opcode, indent+1, 0);
540 dumpf(indent, " )\n");
541 dumpf(indent, "(field ");
542 dump_insn_field(bits->field, indent+1);
543 dumpf(indent, " )\n");
544 dumpf(indent, "(last ");
545 dump_insn_bits(bits->last, indent+1, levels-1);
550 /****************************************************************/
560 nr_insn_table_fields,
562 char *insn_field_name[nr_insn_table_fields] = {
563 "format", "form", "flags", "nmemonic", "name", "comments"
567 function_type = insn_format,
568 function_name = insn_name,
569 function_param = insn_comment,
570 } function_table_fields;
573 typedef struct _insn insn;
575 table_entry *file_entry;
580 typedef struct _insn_table insn_table;
583 insn_bits *expanded_bits;
587 opcode_rules *opcode_rule;
588 opcode_field *opcode;
598 insn_table_insert_function(insn_table *table,
599 table_entry *file_entry)
601 insn **ptr_to_cur_function = &table->functions;
603 /* create a new function */
604 insn *new_function = ZALLOC(insn);
605 new_function->file_entry = file_entry;
607 /* append it to the end of the function list */
608 while (*ptr_to_cur_function != NULL) {
609 ptr_to_cur_function = &(*ptr_to_cur_function)->next;
611 *ptr_to_cur_function = new_function;
616 insn_table_insert_insn(insn_table *table,
617 table_entry *file_entry,
620 insn **ptr_to_cur_insn = &table->insns;
621 insn *cur_insn = *ptr_to_cur_insn;
623 /* create a new instruction */
624 insn *new_insn = ZALLOC(insn);
625 new_insn->file_entry = file_entry;
626 new_insn->fields = fields;
628 /* insert it according to the order of the fields */
629 while (cur_insn != NULL
630 && new_insn->fields->value >= cur_insn->fields->value) {
631 ptr_to_cur_insn = &cur_insn->next;
632 cur_insn = *ptr_to_cur_insn;
635 new_insn->next = cur_insn;
636 *ptr_to_cur_insn = new_insn;
642 static opcode_field *
643 insn_table_find_opcode_field(insn *insns,
647 opcode_field *curr_opcode = opcode_field_new();
652 for (entry = insns; entry != NULL; entry = entry->next) {
653 insn_fields *fields = entry->fields;
654 opcode_field new_opcode;
656 /* find a start point for the opcode field */
657 new_opcode.first = rule->first;
658 while (new_opcode.first <= rule->last
660 || insn_field_is_constant(fields->bits[new_opcode.first],
661 rule) != field_constant_string)
663 || !insn_field_is_constant(fields->bits[new_opcode.first],
665 new_opcode.first = fields->bits[new_opcode.first]->last + 1;
666 ASSERT(new_opcode.first > rule->last
668 && insn_field_is_constant(fields->bits[new_opcode.first],
669 rule) == field_constant_string)
671 && insn_field_is_constant(fields->bits[new_opcode.first],
674 /* find the end point for the opcode field */
675 new_opcode.last = rule->last;
676 while (new_opcode.last >= rule->first
678 || insn_field_is_constant(fields->bits[new_opcode.last],
679 rule) != field_constant_string)
681 || !insn_field_is_constant(fields->bits[new_opcode.last],
683 new_opcode.last = fields->bits[new_opcode.last]->first - 1;
684 ASSERT(new_opcode.last < rule->first
686 && insn_field_is_constant(fields->bits[new_opcode.last],
687 rule) == field_constant_string)
689 && insn_field_is_constant(fields->bits[new_opcode.last],
692 /* now see if our current opcode needs expanding */
693 if (new_opcode.first <= rule->last
694 && curr_opcode->first > new_opcode.first)
695 curr_opcode->first = new_opcode.first;
696 if (new_opcode.last >= rule->first
697 && curr_opcode->last < new_opcode.last)
698 curr_opcode->last = new_opcode.last;
702 /* was any thing interesting found? */
703 if (curr_opcode->first > rule->last) {
704 ASSERT(curr_opcode->last < rule->first);
707 ASSERT(curr_opcode->last >= rule->first);
708 ASSERT(curr_opcode->first <= rule->last);
710 /* if something was found, check it includes the forced field range */
712 && curr_opcode->first > rule->force_first) {
713 curr_opcode->first = rule->force_first;
716 && curr_opcode->last < rule->force_last) {
717 curr_opcode->last = rule->force_last;
719 /* handle special case elminating any need to do shift after mask */
721 && rule->force_last == insn_size-1) {
722 curr_opcode->last = insn_size-1;
725 /* handle any special cases */
726 switch (rule->special_rule) {
727 case 0: /* let the above apply */
729 case 1: /* expand a limited nr of bits, ignoring the rest */
730 curr_opcode->first = rule->force_first;
731 curr_opcode->last = rule->force_last;
733 case 2: /* boolean field */
734 curr_opcode->is_boolean = 1;
743 insn_table_insert_expanded(insn_table *table,
748 insn_table **ptr_to_cur_entry = &table->entries;
749 insn_table *cur_entry = *ptr_to_cur_entry;
751 /* find the new table for this entry */
752 while (cur_entry != NULL
753 && cur_entry->opcode_nr < new_opcode_nr) {
754 ptr_to_cur_entry = &cur_entry->sibling;
755 cur_entry = *ptr_to_cur_entry;
758 if (cur_entry == NULL || cur_entry->opcode_nr != new_opcode_nr) {
759 insn_table *new_entry = ZALLOC(insn_table);
760 new_entry->opcode_nr = new_opcode_nr;
761 new_entry->expanded_bits = new_bits;
762 new_entry->opcode_rule = table->opcode_rule->next;
763 new_entry->sibling = cur_entry;
764 new_entry->parent = table;
765 *ptr_to_cur_entry = new_entry;
766 cur_entry = new_entry;
769 /* ASSERT new_bits == cur_entry bits */
770 ASSERT(cur_entry != NULL && cur_entry->opcode_nr == new_opcode_nr);
771 insn_table_insert_insn(cur_entry,
772 old_insn->file_entry,
777 insn_table_expand_opcode(insn_table *table,
784 if (field_nr > table->opcode->last) {
785 insn_table_insert_expanded(table, instruction, opcode_nr, bits);
788 insn_field *field = instruction->fields->bits[field_nr];
789 if (field->is_int || field->is_slash) {
790 ASSERT(field->first >= table->opcode->first
791 && field->last <= table->opcode->last);
792 insn_table_expand_opcode(table, instruction, field->last+1,
793 ((opcode_nr << field->width) + field->val_int),
798 int last_pos = ((field->last < table->opcode->last)
799 ? field->last : table->opcode->last);
800 int first_pos = ((field->first > table->opcode->first)
801 ? field->first : table->opcode->first);
802 int width = last_pos - first_pos + 1;
803 int last_val = (table->opcode->is_boolean
805 for (val = 0; val < last_val; val++) {
806 insn_bits *new_bits = ZALLOC(insn_bits);
807 new_bits->field = field;
808 new_bits->value = val;
809 new_bits->last = bits;
810 new_bits->opcode = table->opcode;
811 insn_table_expand_opcode(table, instruction, last_pos+1,
812 ((opcode_nr << width) | val),
820 insn_table_insert_expanding(insn_table *table,
823 insn_table_expand_opcode(table,
825 table->opcode->first,
827 table->expanded_bits);
832 insn_table_expand_insns(insn_table *table)
835 ASSERT(table->nr_insn >= 1);
837 /* determine a valid opcode */
838 while (table->opcode_rule) {
839 /* specials only for single instructions */
840 if ((table->nr_insn > 1
841 && table->opcode_rule->special_mask == 0
842 && table->opcode_rule->special_rule == 0)
843 || (table->nr_insn == 1
844 && table->opcode_rule->special_mask != 0
845 && ((table->insns->fields->value
846 & table->opcode_rule->special_mask)
847 == table->opcode_rule->special_value))
848 || (idecode_expand_semantics
849 && table->opcode_rule->special_mask == 0
850 && table->opcode_rule->special_rule == 0))
852 insn_table_find_opcode_field(table->insns,
854 table->nr_insn == 1/*string*/
856 if (table->opcode != NULL)
858 table->opcode_rule = table->opcode_rule->next;
861 /* did we find anything */
862 if (table->opcode == NULL) {
865 ASSERT(table->opcode != NULL);
867 /* back link what we found to its parent */
868 if (table->parent != NULL) {
869 ASSERT(table->parent->opcode != NULL);
870 table->opcode->parent = table->parent->opcode;
873 /* expand the raw instructions according to the opcode */
876 for (entry = table->insns; entry != NULL; entry = entry->next) {
877 insn_table_insert_expanding(table, entry);
881 /* and do the same for the sub entries */
884 for (entry = table->entries; entry != NULL; entry = entry->sibling) {
885 insn_table_expand_insns(entry);
893 insn_table_load_insns(char *file_name)
895 table *file = table_open(file_name, nr_insn_table_fields);
896 insn_table *table = ZALLOC(insn_table);
897 table_entry *file_entry;
898 table->opcode_rule = opcode_table;
900 while ((file_entry = table_entry_read(file)) != NULL) {
901 if (it_is("function", file_entry->fields[insn_flags])
902 || it_is("internal", file_entry->fields[insn_flags])) {
903 insn_table_insert_function(table, file_entry);
907 /* skip instructions that aren't relevant to the mode */
908 filter *filt = filters;
909 while (filt != NULL) {
910 if (it_is(filt->flag, file_entry->fields[insn_flags]))
915 /* create/insert the new instruction */
916 fields = parse_insn_format(file_entry,
917 file_entry->fields[insn_format]);
918 insn_table_insert_insn(table, file_entry, fields);
927 dump_insn(insn *entry, int indent, int levels)
929 printf("(insn*)%p\n", entry);
931 if (levels && entry != NULL) {
933 dumpf(indent, "(file_entry ");
934 dump_table_entry(entry->file_entry, indent+1);
935 dumpf(indent, " )\n");
937 dumpf(indent, "(fields ");
938 dump_insn_fields(entry->fields, indent+1);
939 dumpf(indent, " )\n");
941 dumpf(indent, "(next ");
942 dump_insn(entry->next, indent+1, levels-1);
943 dumpf(indent, " )\n");
951 dump_insn_table(insn_table *table,
952 int indent, int levels)
955 printf("(insn_table*)%p\n", table);
957 if (levels && table != NULL) {
959 dumpf(indent, "(opcode_nr %d)\n", table->opcode_nr);
961 dumpf(indent, "(expanded_bits ");
962 dump_insn_bits(table->expanded_bits, indent+1, -1);
963 dumpf(indent, " )\n");
965 dumpf(indent, "(int nr_insn %d)\n", table->nr_insn);
967 dumpf(indent, "(insns ");
968 dump_insn(table->insns, indent+1, table->nr_insn);
969 dumpf(indent, " )\n");
971 dumpf(indent, "(opcode_rule ");
972 dump_opcode_rule(table->opcode_rule, indent+1);
973 dumpf(indent, " )\n");
975 dumpf(indent, "(opcode ");
976 dump_opcode_field(table->opcode, indent+1, 1);
977 dumpf(indent, " )\n");
979 dumpf(indent, "(nr_entries %d)\n", table->entries);
980 dumpf(indent, "(entries ");
981 dump_insn_table(table->entries, indent+1, table->nr_entries);
982 dumpf(indent, " )\n");
984 dumpf(indent, "(sibling ", table->sibling);
985 dump_insn_table(table->sibling, indent+1, levels-1);
986 dumpf(indent, " )\n");
988 dumpf(indent, "(parent ", table->parent);
989 dump_insn_table(table->parent, indent+1, 0);
990 dumpf(indent, " )\n");
996 /****************************************************************/
1000 lf_print_insn_bits(lf *file, insn_bits *bits)
1004 lf_print_insn_bits(file, bits->last);
1005 lf_putchr(file, '_');
1006 lf_putstr(file, bits->field->val_string);
1007 if (!bits->opcode->is_boolean || bits->value == 0) {
1008 if (bits->opcode->last < bits->field->last)
1009 lf_putint(file, bits->value << (bits->field->last - bits->opcode->last));
1011 lf_putint(file, bits->value);
1016 lf_print_opcodes(lf *file,
1019 if (table != NULL) {
1021 lf_printf(file, "_%d_%d",
1022 table->opcode->first,
1023 table->opcode->last);
1024 if (table->parent == NULL) break;
1025 lf_printf(file, "__%d", table->opcode_nr);
1026 table = table->parent;
1032 lf_print_table_name(lf *file,
1035 lf_printf(file, "idecode_table");
1036 lf_print_opcodes(file, table);
1042 function_name_prefix_semantics,
1043 function_name_prefix_idecode,
1044 function_name_prefix_itable,
1045 function_name_prefix_none
1046 } lf_function_name_prefixes;
1049 lf_print_function_name(lf *file,
1051 insn_bits *expanded_bits,
1052 lf_function_name_prefixes prefix)
1057 case function_name_prefix_semantics:
1058 lf_putstr(file, "semantic_");
1060 case function_name_prefix_idecode:
1061 lf_printf(file, "idecode_");
1063 case function_name_prefix_itable:
1064 lf_putstr(file, "itable_");
1070 /* the function name */
1073 for (pos = basename;
1081 lf_putchr(file, '_');
1084 lf_putchr(file, *pos);
1091 if (idecode_expand_semantics)
1092 lf_print_insn_bits(file, expanded_bits);
1097 lf_print_idecode_table(lf *file,
1100 int can_assume_leaf;
1101 opcode_rules *opcode_rule;
1103 /* have a look at the rule table, if all table rules follow all
1104 switch rules, I can assume that all end points are leaves */
1105 opcode_rule = opcode_table;
1106 while (opcode_rule != NULL
1107 && opcode_rule->use_switch)
1108 opcode_rule = opcode_rule->next;
1109 while (opcode_rule != NULL
1110 && opcode_rule->use_switch
1111 && opcode_rule->special_rule)
1112 opcode_rule = opcode_rule->next;
1113 can_assume_leaf = opcode_rule == NULL;
1115 lf_printf(file, "{\n");
1116 lf_indent(file, +2);
1118 lf_printf(file, "idecode_table_entry *table = ");
1119 lf_print_table_name(file, entry);
1120 lf_printf(file, ";\n");
1121 lf_printf(file, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1122 entry->opcode->first, entry->opcode->last);
1123 lf_printf(file, "idecode_table_entry *table_entry = table + opcode;\n");
1124 lf_printf(file, "while (1) {\n");
1125 lf_indent(file, +2);
1127 lf_printf(file, "while (table_entry->mask != 0) {\n");
1128 lf_indent(file, +2);
1130 lf_printf(file, "table = ((idecode_table_entry*)\n");
1131 lf_printf(file, " table_entry->function_or_table);\n");
1132 lf_printf(file, "opcode = ((instruction & table_entry->mask)\n");
1133 lf_printf(file, " >> table_entry->shift);\n");
1134 lf_printf(file, "table_entry = table + opcode;\n");
1136 lf_indent(file, -2);
1137 lf_printf(file, "}\n");
1138 if (!idecode_cache && can_assume_leaf) {
1139 lf_printf(file, "return (((idecode_semantic*)\n");
1140 lf_printf(file, " table_entry->function_or_table)\n");
1141 lf_printf(file, " (%s));\n", semantic_actual);
1143 else if (!idecode_cache && !can_assume_leaf) {
1144 lf_printf(file, "if (table_entry->shift == 0)");
1145 lf_printf(file, " return (((idecode_semantic*)\n");
1146 lf_printf(file, " table_entry->function_or_table)\n");
1147 lf_printf(file, " (%s));\n", semantic_actual);
1150 lf_printf(file, "if (table_entry->shift == 0)\n");
1151 lf_printf(file, " return (((idecode_crack*)\n");
1152 lf_printf(file, " table_entry->function_or_table)\n");
1153 lf_printf(file, " (%s));\n", cache_idecode_actual);
1155 if (!can_assume_leaf) {
1156 lf_printf(file, "opcode = (instruction & table_entry->shift) != 0;\n");
1157 lf_printf(file, "table = ((idecode_table_entry*)\n");
1158 lf_printf(file, " table_entry->function_or_table);\n");
1159 lf_printf(file, "table_entry = table + opcode;\n");
1162 lf_indent(file, -2);
1163 lf_printf(file, "}\n");
1165 lf_indent(file, -2);
1166 lf_printf(file, "}\n");
1171 lf_print_my_prefix(lf *file,
1172 table_entry *file_entry,
1175 lf_printf(file, "const char *const my_prefix = \n");
1176 lf_printf(file, " \"%s:%s:%s:%d\";\n",
1177 filter_filename (file_entry->file_name),
1178 (idecode ? "idecode" : "semantics"),
1179 file_entry->fields[insn_name],
1180 file_entry->line_nr);
1185 lf_print_ptrace(lf *file,
1188 lf_printf(file, "\n");
1189 lf_printf(file, "ITRACE(trace_%s, (\"\\n\"));\n",
1190 (idecode ? "idecode" : "semantics"));
1194 /****************************************************************/
1196 typedef void leaf_handler
1200 typedef void padding_handler
1208 insn_table_traverse_tree(insn_table *table,
1211 leaf_handler *start,
1214 padding_handler *padding)
1219 ASSERT(table != NULL
1220 && table->opcode != NULL
1221 && table->nr_entries > 0
1222 && table->entries != 0);
1224 if (start != NULL && depth >= 0)
1225 start(table, data, depth);
1227 for (entry_nr = 0, entry = table->entries;
1228 entry_nr < (table->opcode->is_boolean
1230 : (1 << (table->opcode->last - table->opcode->first + 1)));
1233 || (!table->opcode->is_boolean
1234 && entry_nr < entry->opcode_nr)) {
1235 if (padding != NULL && depth >= 0)
1236 padding(table, data, depth, entry_nr);
1239 ASSERT(entry != NULL && (entry->opcode_nr == entry_nr
1240 || table->opcode->is_boolean));
1241 if (entry->opcode != NULL && depth != 0) {
1242 insn_table_traverse_tree(entry, data, depth+1,
1243 start, leaf, end, padding);
1245 else if (depth >= 0) {
1247 leaf(entry, data, depth);
1249 entry = entry->sibling;
1252 if (end != NULL && depth >= 0)
1253 end(table, data, depth);
1257 typedef void function_handler
1260 table_entry *function);
1263 insn_table_traverse_function(insn_table *table,
1265 function_handler *leaf)
1268 for (function = table->functions;
1270 function = function->next) {
1271 leaf(table, data, function->file_entry);
1276 typedef void insn_handler
1282 insn_table_traverse_insn(insn_table *table,
1287 for (instruction = table->insns;
1288 instruction != NULL;
1289 instruction = instruction->next) {
1290 leaf(table, data, instruction);
1296 update_depth(insn_table *entry,
1300 int *max_depth = (int*)data;
1301 if (*max_depth < depth)
1307 insn_table_depth(insn_table *table)
1310 insn_table_traverse_tree(table,
1321 /****************************************************************/
1324 dump_traverse_start(insn_table *table,
1328 dumpf(depth*2, "(%d\n", table->opcode_nr);
1332 dump_traverse_leaf(insn_table *entry,
1336 ASSERT(entry->nr_entries == 0
1337 && entry->nr_insn == 1
1338 && entry->opcode == NULL);
1339 dumpf(depth*2, ".%d %s\n", entry->opcode_nr,
1340 entry->insns->file_entry->fields[insn_format]);
1344 dump_traverse_end(insn_table *table,
1348 dumpf(depth*2, ")\n");
1352 dump_traverse_padding(insn_table *table,
1357 dumpf(depth*2, ".<%d>\n", opcode_nr);
1362 dump_traverse(insn_table *table)
1364 insn_table_traverse_tree(table, NULL, 1,
1365 dump_traverse_start,
1368 dump_traverse_padding);
1372 /****************************************************************/
1376 semantics_h_print_function(lf *file,
1378 insn_bits *expanded_bits)
1380 lf_printf(file, "\n");
1381 lf_printf(file, "INLINE_SEMANTICS unsigned_word ");
1382 lf_print_function_name(file,
1385 function_name_prefix_semantics);
1386 lf_printf(file, "\n(%s);\n",
1387 (idecode_cache ? cache_semantic_formal : semantic_formal));
1392 semantics_h_leaf(insn_table *entry,
1396 lf *file = (lf*)data;
1397 ASSERT(entry->nr_insn == 1);
1398 semantics_h_print_function(file,
1399 entry->insns->file_entry->fields[insn_name],
1400 entry->expanded_bits);
1404 semantics_h_insn(insn_table *entry,
1408 lf *file = (lf*)data;
1409 semantics_h_print_function(file,
1410 instruction->file_entry->fields[insn_name],
1415 semantics_h_function(insn_table *entry,
1417 table_entry *function)
1419 lf *file = (lf*)data;
1420 if (function->fields[function_type] == NULL
1421 || function->fields[function_type][0] == '\0') {
1422 semantics_h_print_function(file,
1423 function->fields[function_name],
1427 lf_printf(file, "\n");
1428 lf_printf(file, "INLINE_SEMANTICS %s %s\n(%s);\n",
1429 function->fields[function_type],
1430 function->fields[function_name],
1431 function->fields[function_param]);
1437 gen_semantics_h(insn_table *table, lf *file)
1440 lf_print_copyleft(file);
1441 lf_printf(file, "\n");
1442 lf_printf(file, "#ifndef _SEMANTICS_H_\n");
1443 lf_printf(file, "#define _SEMANTICS_H_\n");
1444 lf_printf(file, "\n");
1445 lf_printf(file, "#ifndef INLINE_SEMANTICS\n");
1446 lf_printf(file, "#define INLINE_SEMANTICS\n");
1447 lf_printf(file, "#endif\n");
1448 lf_printf(file, "\n");
1449 lf_printf(file, "\n");
1451 /* output a declaration for all functions */
1452 insn_table_traverse_function(table,
1454 semantics_h_function);
1456 /* output a declaration for all instructions */
1457 if (idecode_expand_semantics)
1458 insn_table_traverse_tree(table,
1462 semantics_h_leaf, /* leaf */
1464 NULL); /* padding */
1466 insn_table_traverse_insn(table,
1470 lf_printf(file, "\n");
1471 lf_printf(file, "#endif /* _SEMANTICS_H_ */\n");
1475 /****************************************************************/
1477 typedef struct _icache_tree icache_tree;
1478 struct _icache_tree {
1481 icache_tree *children;
1484 static icache_tree *
1485 icache_tree_insert(icache_tree *tree,
1488 icache_tree *new_tree;
1490 icache_tree **ptr_to_cur_tree = &tree->children;
1491 icache_tree *cur_tree = *ptr_to_cur_tree;
1492 while (cur_tree != NULL
1493 && strcmp(cur_tree->name, name) < 0) {
1494 ptr_to_cur_tree = &cur_tree->next;
1495 cur_tree = *ptr_to_cur_tree;
1497 ASSERT(cur_tree == NULL
1498 || strcmp(cur_tree->name, name) >= 0);
1499 /* already in the tree */
1500 if (cur_tree != NULL
1501 && strcmp(cur_tree->name, name) == 0)
1503 /* missing, insert it */
1504 ASSERT(cur_tree == NULL
1505 || strcmp(cur_tree->name, name) > 0);
1506 new_tree = ZALLOC(icache_tree);
1507 new_tree->name = name;
1508 new_tree->next = cur_tree;
1509 *ptr_to_cur_tree = new_tree;
1514 static icache_tree *
1515 insn_table_cache_fields(insn_table *table)
1517 icache_tree *tree = ZALLOC(icache_tree);
1519 for (instruction = table->insns;
1520 instruction != NULL;
1521 instruction = instruction->next) {
1524 icache_tree_insert(tree,
1525 instruction->file_entry->fields[insn_form]);
1526 for (field = instruction->fields->first;
1528 field = field->next) {
1529 if (field->is_string)
1530 icache_tree_insert(form, field->val_string);
1539 gen_icache_h(icache_tree *tree,
1542 lf_print_copyleft(file);
1543 lf_printf(file, "\n");
1544 lf_printf(file, "#ifndef _ICACHE_H_\n");
1545 lf_printf(file, "#define _ICACHE_H_\n");
1546 lf_printf(file, "\n");
1547 lf_printf(file, "#ifndef INLINE_ICACHE\n");
1548 lf_printf(file, "#define INLINE_ICACHE\n");
1549 lf_printf(file, "#endif\n");
1550 lf_printf(file, "\n");
1552 lf_printf(file, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1554 lf_printf(file, "\n");
1556 /* create an instruction cache if being used */
1557 if (idecode_cache) {
1559 lf_printf(file, "typedef struct _idecode_cache {\n");
1560 lf_printf(file, " unsigned_word address;\n");
1561 lf_printf(file, " void *semantic;\n");
1562 lf_printf(file, " union {\n");
1563 for (form = tree->children;
1565 form = form->next) {
1567 lf_printf(file, " struct {\n");
1568 for (field = form->children;
1570 field = field->next) {
1571 cache_rules *cache_rule;
1573 for (cache_rule = cache_table;
1575 cache_rule = cache_rule->next) {
1576 if (strcmp(field->name, cache_rule->old_name) == 0) {
1578 if (cache_rule->new_name != NULL)
1579 lf_printf(file, " %s %s; /* %s */\n",
1580 (cache_rule->type == NULL
1582 : cache_rule->type),
1583 cache_rule->new_name,
1584 cache_rule->old_name);
1588 lf_printf(file, " unsigned %s;\n", field->name);
1590 lf_printf(file, " } %s;\n", form->name);
1592 lf_printf(file, " } crack;\n");
1593 lf_printf(file, "} idecode_cache;\n");
1596 /* alernativly, since no cache, #define the fields to be
1597 extractions from the instruction variable */
1598 cache_rules *cache_rule;
1599 lf_printf(file, "\n");
1600 for (cache_rule = cache_table;
1602 cache_rule = cache_rule->next) {
1603 if (cache_rule->expression != NULL
1604 && strlen(cache_rule->expression) > 0)
1605 lf_printf(file, "#define %s %s\n",
1606 cache_rule->new_name, cache_rule->expression);
1610 lf_printf(file, "\n");
1611 lf_printf(file, "#endif /* _ICACHE_H_ */\n");
1617 /****************************************************************/
1621 lf_print_c_extraction(lf *file,
1625 char *field_expression,
1626 insn_field *cur_field,
1628 int get_value_from_cache,
1629 int put_value_in_cache)
1631 ASSERT(field_name != NULL);
1633 && (!bits->opcode->is_boolean || bits->value == 0)
1634 && strcmp(field_name, cur_field->val_string) == 0) {
1635 ASSERT(bits->field == cur_field);
1636 ASSERT(field_type == NULL);
1637 table_entry_lf_c_line_nr(file, instruction->file_entry);
1638 lf_printf(file, "const unsigned %s = ",
1640 if (bits->opcode->last < bits->field->last)
1641 lf_printf(file, "%d;\n",
1642 bits->value << (bits->field->last - bits->opcode->last));
1644 lf_printf(file, "%d;\n", bits->value);
1647 /* put the field in the local variable */
1648 table_entry_lf_c_line_nr(file, instruction->file_entry);
1649 lf_printf(file, "%s const %s = ",
1650 field_type == NULL ? "unsigned" : field_type,
1652 /* getting it from the cache */
1653 if (get_value_from_cache || put_value_in_cache) {
1654 lf_printf(file, "cache_entry->crack.%s.%s",
1655 instruction->file_entry->fields[insn_form],
1657 if (put_value_in_cache) /* also put it in the cache? */
1658 lf_printf(file, " = ");
1660 if (!get_value_from_cache) {
1661 if (strcmp(field_name, cur_field->val_string) == 0)
1662 lf_printf(file, "EXTRACTED32(instruction, %d, %d)",
1663 cur_field->first, cur_field->last);
1664 else if (field_expression != NULL)
1665 lf_printf(file, "%s", field_expression);
1667 lf_printf(file, "eval_%s", field_name);
1669 lf_printf(file, ";\n");
1675 lf_print_c_extractions(lf *file,
1677 insn_bits *expanded_bits,
1678 int get_value_from_cache,
1679 int put_value_in_cache)
1681 insn_field *cur_field;
1683 /* extract instruction fields */
1684 lf_printf(file, "/* extraction: %s */\n",
1685 instruction->file_entry->fields[insn_format]);
1687 for (cur_field = instruction->fields->first;
1688 cur_field->first < insn_size;
1689 cur_field = cur_field->next) {
1690 if (cur_field->is_string) {
1693 /* find any corresponding value */
1694 for (bits = expanded_bits;
1696 bits = bits->last) {
1697 if (bits->field == cur_field)
1700 /* try the cache rule table for what to do */
1701 if (get_value_from_cache || put_value_in_cache) {
1702 cache_rules *cache_rule;
1703 for (cache_rule = cache_table;
1705 cache_rule = cache_rule->next) {
1706 if (strcmp(cur_field->val_string, cache_rule->old_name) == 0) {
1708 if (cache_rule->valid > 1 && put_value_in_cache)
1709 lf_print_c_extraction(file,
1711 cache_rule->new_name,
1713 cache_rule->expression,
1718 else if (cache_rule->valid == 1)
1719 lf_print_c_extraction(file,
1721 cache_rule->new_name,
1723 cache_rule->expression,
1726 get_value_from_cache,
1727 put_value_in_cache);
1731 if (found_rule == 0)
1732 lf_print_c_extraction(file,
1734 cur_field->val_string,
1739 get_value_from_cache,
1740 put_value_in_cache);
1741 /* if any (XXX == 0), output a corresponding test */
1742 if (instruction->file_entry->annex != NULL) {
1743 char *field_name = cur_field->val_string;
1744 char *is_0_ptr = instruction->file_entry->annex;
1745 int field_len = strlen(field_name);
1746 if (strlen(is_0_ptr) >= (strlen("_is_0") + field_len)) {
1747 is_0_ptr += field_len;
1748 while ((is_0_ptr = strstr(is_0_ptr, "_is_0")) != NULL) {
1749 if (strncmp(is_0_ptr - field_len, field_name, field_len) == 0
1750 && !isalpha(is_0_ptr[ - field_len - 1])) {
1751 table_entry_lf_c_line_nr(file, instruction->file_entry);
1752 lf_printf(file, "const unsigned %s_is_0 = (", field_name);
1754 lf_printf(file, "%d", bits->value);
1756 lf_printf(file, "%s", field_name);
1757 lf_printf(file, " == 0);\n");
1760 is_0_ptr += strlen("_is_0");
1764 /* any thing else ... */
1767 lf_print_lf_c_line_nr(file);
1772 lf_print_idecode_illegal(lf *file)
1775 lf_printf(file, "return idecode_illegal(%s);\n", cache_idecode_actual);
1777 lf_printf(file, "return semantic_illegal(%s);\n", semantic_actual);
1782 lf_print_idecode_floating_point_unavailable(lf *file)
1785 lf_printf(file, "return idecode_floating_point_unavailable(%s);\n",
1786 cache_idecode_actual);
1788 lf_printf(file, "return semantic_floating_point_unavailable(%s);\n",
1793 /* Output code to do any final checks on the decoded instruction.
1794 This includes things like verifying any on decoded fields have the
1795 correct value and checking that (for floating point) floating point
1796 hardware isn't disabled */
1799 lf_print_c_validate(lf *file,
1801 opcode_field *opcodes)
1803 /* Validate: unchecked instruction fields
1805 If any constant fields in the instruction were not checked by the
1806 idecode tables, output code to check that they have the correct
1809 unsigned check_mask = 0;
1810 unsigned check_val = 0;
1812 opcode_field *opcode;
1814 /* form check_mask/check_val containing what needs to be checked
1815 in the instruction */
1816 for (field = instruction->fields->first;
1817 field->first < insn_size;
1818 field = field->next) {
1820 check_mask <<= field->width;
1821 check_val <<= field->width;
1823 /* is it a constant that could need validating? */
1824 if (!field->is_int && !field->is_slash)
1827 /* has it been checked by a table? */
1828 for (opcode = opcodes; opcode != NULL; opcode = opcode->parent) {
1829 if (field->first >= opcode->first
1830 && field->last <= opcode->last)
1836 check_mask |= (1 << field->width)-1;
1837 check_val |= field->val_int;
1840 /* if any bits not checked by opcode tables, output code to check them */
1842 lf_printf(file, "\n");
1843 lf_printf(file, "/* validate: %s */\n",
1844 instruction->file_entry->fields[insn_format]);
1845 lf_printf(file, "if ((instruction & 0x%x) != 0x%x)\n",
1846 check_mask, check_val);
1847 lf_indent(file, +2);
1848 lf_print_idecode_illegal(file);
1849 lf_indent(file, -2);
1853 /* Validate floating point hardware
1855 If the simulator is being built with out floating point hardware
1856 (different to it being disabled in the MSR) then floating point
1857 instructions are invalid */
1859 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1860 lf_printf(file, "\n");
1861 lf_printf(file, "/* Validate: FP hardware exists */\n");
1862 lf_printf(file, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1863 lf_indent(file, +2);
1864 lf_print_idecode_illegal(file);
1865 lf_indent(file, -2);
1869 /* Validate: Floating Point available
1871 If floating point is not available, we enter a floating point
1872 unavailable interrupt into the cache instead of the instruction
1875 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1876 ever a CSI occures we flush the instruction cache. */
1879 if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1880 lf_printf(file, "\n");
1881 lf_printf(file, "/* Validate: FP available according to MSR[FP] */\n");
1882 lf_printf(file, "if (!IS_FP_AVAILABLE(processor))\n");
1883 lf_indent(file, +2);
1884 lf_print_idecode_floating_point_unavailable(file);
1885 lf_indent(file, -2);
1892 lf_print_c_cracker(lf *file,
1894 insn_bits *expanded_bits,
1895 opcode_field *opcodes)
1898 /* function header */
1899 lf_printf(file, "{\n");
1900 lf_indent(file, +2);
1902 lf_print_my_prefix(file,
1903 instruction->file_entry,
1904 1/*putting-value-in-cache*/);
1906 lf_print_ptrace(file,
1907 1/*putting-value-in-cache*/);
1909 lf_print_c_validate(file, instruction, opcodes);
1911 lf_printf(file, "\n");
1912 lf_printf(file, "{\n");
1913 lf_indent(file, +2);
1914 lf_print_c_extractions(file,
1917 0/*get_value_from_cache*/,
1918 1/*put_value_in_cache*/);
1919 lf_indent(file, -2);
1920 lf_printf(file, "}\n");
1922 /* return the function propper (main sorts this one out) */
1923 lf_printf(file, "\n");
1924 lf_printf(file, "/* semantic routine */\n");
1925 table_entry_lf_c_line_nr(file, instruction->file_entry);
1926 lf_printf(file, "return ");
1927 lf_print_function_name(file,
1928 instruction->file_entry->fields[insn_name],
1930 function_name_prefix_semantics);
1931 lf_printf(file, ";\n");
1933 lf_print_lf_c_line_nr(file);
1934 lf_indent(file, -2);
1935 lf_printf(file, "}\n");
1940 lf_print_c_semantic(lf *file,
1942 insn_bits *expanded_bits,
1943 opcode_field *opcodes)
1946 lf_printf(file, "{\n");
1947 lf_indent(file, +2);
1949 lf_print_my_prefix(file,
1950 instruction->file_entry,
1951 0/*not putting value in cache*/);
1952 lf_putstr(file, semantic_local);
1953 lf_printf(file, "\n");
1955 lf_printf(file, "\n");
1956 lf_print_c_extractions(file,
1959 idecode_cache/*get_value_from_cache*/,
1960 0/*put_value_in_cache*/);
1962 lf_print_ptrace(file,
1963 0/*put_value_in_cache*/);
1965 /* validate the instruction, if a cache this has already been done */
1967 lf_print_c_validate(file, instruction, opcodes);
1969 /* generate the profileing call - this is delayed until after the
1970 instruction has been verified */
1971 lf_printf(file, "\n");
1972 lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
1973 lf_printf(file, " mon_issue(");
1974 lf_print_function_name(file,
1975 instruction->file_entry->fields[insn_name],
1977 function_name_prefix_itable);
1978 lf_printf(file, ", processor, cia);\n");
1980 /* generate the code (or at least something */
1981 if (instruction->file_entry->annex != NULL) {
1983 lf_printf(file, "\n");
1984 table_entry_lf_c_line_nr(file, instruction->file_entry);
1985 lf_printf(file, "{\n");
1986 lf_indent(file, +2);
1987 lf_print_c_code(file, instruction->file_entry->annex);
1988 lf_indent(file, -2);
1989 lf_printf(file, "}\n");
1990 lf_print_lf_c_line_nr(file);
1992 else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
1993 lf_print_lf_c_line_nr(file);
1995 else if (it_is("f", instruction->file_entry->fields[insn_flags])) {
1996 /* unimplemented floating point instruction - call for assistance */
1997 lf_printf(file, "\n");
1998 lf_printf(file, "/* unimplemented floating point instruction - call for assistance */\n");
1999 table_entry_lf_c_line_nr(file, instruction->file_entry);
2000 lf_putstr(file, "floating_point_assist_interrupt(processor, cia);\n");
2001 lf_print_lf_c_line_nr(file);
2004 /* abort so it is implemented now */
2005 table_entry_lf_c_line_nr(file, instruction->file_entry);
2006 lf_putstr(file, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2007 lf_print_lf_c_line_nr(file);
2008 lf_printf(file, "\n");
2011 /* the function footer */
2012 lf_printf(file, "return nia;\n");
2013 lf_indent(file, -2);
2014 lf_printf(file, "}\n");
2018 lf_print_c_semantic_function_header(lf *file,
2020 insn_bits *expanded_bits)
2022 lf_printf(file, "\n");
2023 lf_printf(file, "INLINE_SEMANTICS unsigned_word\n");
2024 lf_print_function_name(file,
2027 function_name_prefix_semantics);
2028 lf_printf(file, "\n(%s)\n",
2029 (idecode_cache ? cache_semantic_formal : semantic_formal));
2033 lf_print_c_semantic_function(lf *file,
2035 insn_bits *expanded_bits,
2036 opcode_field *opcodes)
2039 /* build the semantic routine to execute the instruction */
2040 lf_print_c_semantic_function_header(file,
2041 instruction->file_entry->fields[insn_name],
2043 lf_print_c_semantic(file,
2051 semantics_c_leaf(insn_table *entry,
2055 lf *file = (lf*)data;
2056 ASSERT(entry->nr_insn == 1
2057 && entry->opcode == NULL
2058 && entry->parent != NULL
2059 && entry->parent->opcode != NULL);
2060 lf_print_c_semantic_function(file,
2062 entry->expanded_bits,
2063 entry->parent->opcode);
2067 semantics_c_insn(insn_table *table,
2071 lf *file = (lf*)data;
2072 lf_print_c_semantic_function(file, instruction,
2077 semantics_c_function(insn_table *table,
2079 table_entry *function)
2081 lf *file = (lf*)data;
2082 if (function->fields[function_type] == NULL
2083 || function->fields[function_type][0] == '\0') {
2084 lf_print_c_semantic_function_header(file,
2085 function->fields[function_name],
2089 lf_printf(file, "\n");
2090 lf_printf(file, "INLINE_SEMANTICS %s\n%s(%s)\n",
2091 function->fields[function_type],
2092 function->fields[function_name],
2093 function->fields[function_param]);
2095 table_entry_lf_c_line_nr(file, function);
2096 lf_printf(file, "{\n");
2097 lf_indent(file, +2);
2098 lf_print_c_code(file, function->annex);
2099 lf_indent(file, -2);
2100 lf_printf(file, "}\n");
2101 lf_print_lf_c_line_nr(file);
2107 gen_semantics_c(insn_table *table, lf *file)
2109 lf_print_copyleft(file);
2110 lf_printf(file, "\n");
2111 lf_printf(file, "#ifndef _SEMANTICS_C_\n");
2112 lf_printf(file, "#define _SEMANTICS_C_\n");
2113 lf_printf(file, "\n");
2114 lf_printf(file, "#ifndef STATIC_INLINE_SEMANTICS\n");
2115 lf_printf(file, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2116 lf_printf(file, "#endif\n");
2117 lf_printf(file, "\n");
2118 lf_printf(file, "#include \"cpu.h\"\n");
2119 lf_printf(file, "#include \"idecode.h\"\n");
2120 lf_printf(file, "#include \"semantics.h\"\n");
2121 lf_printf(file, "\n");
2123 /* output a definition (c-code) for all functions */
2124 insn_table_traverse_function(table,
2126 semantics_c_function);
2128 /* output a definition (c-code) for all instructions */
2129 if (idecode_expand_semantics)
2130 insn_table_traverse_tree(table,
2136 NULL); /* padding */
2138 insn_table_traverse_insn(table,
2142 lf_printf(file, "\n");
2143 lf_printf(file, "#endif /* _SEMANTICS_C_ */\n");
2147 /****************************************************************/
2150 gen_idecode_h(insn_table *table, lf *file)
2152 lf_print_copyleft(file);
2153 lf_printf(file, "\n");
2154 lf_printf(file, "#ifndef _IDECODE_H_\n");
2155 lf_printf(file, "#define _IDECODE_H_\n");
2156 lf_printf(file, "\n");
2157 lf_printf(file, "#ifndef INLINE_IDECODE\n");
2158 lf_printf(file, "#define INLINE_IDECODE\n");
2159 lf_printf(file, "#endif\n");
2160 lf_printf(file, "\n");
2161 lf_printf(file, "#include \"idecode_expression.h\"\n");
2162 lf_printf(file, "#include \"idecode_fields.h\"\n");
2163 lf_printf(file, "#include \"idecode_branch.h\"\n");
2164 lf_printf(file, "\n");
2165 lf_printf(file, "#include \"icache.h\"\n");
2166 lf_printf(file, "\n");
2167 lf_printf(file, "typedef unsigned_word idecode_semantic\n(%s);\n",
2168 (idecode_cache ? cache_semantic_formal : semantic_formal));
2169 lf_printf(file, "\n");
2171 lf_printf(file, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2172 cache_idecode_formal);
2174 lf_printf(file, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2176 lf_printf(file, "\n");
2177 lf_printf(file, "#endif /* _IDECODE_H_ */\n");
2181 /****************************************************************/
2185 idecode_table_start(insn_table *table,
2189 lf *file = (lf*)data;
2191 /* start of the table */
2192 if (!table->opcode_rule->use_switch) {
2193 lf_printf(file, "\n");
2194 lf_printf(file, "static idecode_table_entry ");
2195 lf_print_table_name(file, table);
2196 lf_printf(file, "[] = {\n");
2201 idecode_table_leaf(insn_table *entry,
2205 lf *file = (lf*)data;
2206 ASSERT(entry->parent != NULL);
2209 /* add an entry to the table */
2210 if (!entry->parent->opcode_rule->use_switch) {
2211 if (entry->opcode == NULL) {
2212 /* table leaf entry */
2213 lf_printf(file, " /*%d*/ { 0, 0, ", entry->opcode_nr);
2214 lf_print_function_name(file,
2215 entry->insns->file_entry->fields[insn_name],
2216 entry->expanded_bits,
2218 ? function_name_prefix_idecode
2219 : function_name_prefix_semantics));
2220 lf_printf(file, " },\n");
2222 else if (entry->opcode_rule->use_switch) {
2223 /* table calling switch statement */
2224 lf_printf(file, " /*%d*/ { -1, 0, ",
2226 lf_print_table_name(file, entry);
2227 lf_printf(file, " },\n");
2230 /* table `calling' another table */
2231 lf_printf(file, " /*%d*/ { ", entry->opcode_nr);
2232 if (entry->opcode->is_boolean)
2233 lf_printf(file, "MASK32(%d,%d), 0, ",
2234 entry->opcode->first, entry->opcode->last);
2236 lf_printf(file, "%d, MASK32(%d,%d), ",
2237 insn_size - entry->opcode->last - 1,
2238 entry->opcode->first, entry->opcode->last);
2239 lf_print_table_name(file, entry);
2240 lf_printf(file, " },\n");
2246 idecode_table_end(insn_table *table,
2250 lf *file = (lf*)data;
2253 if (!table->opcode_rule->use_switch) {
2254 lf_printf(file, "};\n");
2259 idecode_table_padding(insn_table *table,
2264 lf *file = (lf*)data;
2267 if (!table->opcode_rule->use_switch) {
2268 lf_printf(file, " /*%d*/ { 0, 0, %s_illegal },\n",
2269 opcode_nr, (idecode_cache ? "idecode" : "semantic"));
2274 /****************************************************************/
2277 void lf_print_idecode_switch
2283 idecode_switch_start(insn_table *table,
2287 lf *file = (lf*)data;
2289 ASSERT(table->opcode_rule->use_switch);
2291 lf_printf(file, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2292 table->opcode->first, table->opcode->last);
2297 idecode_switch_leaf(insn_table *entry,
2301 lf *file = (lf*)data;
2302 ASSERT(entry->parent != NULL);
2304 ASSERT(entry->parent->opcode_rule->use_switch);
2306 lf_printf(file, "case %d:\n", entry->opcode_nr);
2307 lf_indent(file, +2);
2309 if (entry->opcode == NULL) {
2310 /* switch calling leaf */
2311 lf_printf(file, "return ");
2312 lf_print_function_name(file,
2313 entry->insns->file_entry->fields[insn_name],
2314 entry->expanded_bits,
2316 ? function_name_prefix_idecode
2317 : function_name_prefix_semantics));
2319 lf_printf(file, "(%s);\n", cache_idecode_actual);
2321 lf_printf(file, "(%s);\n", semantic_actual);
2323 else if (entry->opcode_rule->use_switch) {
2324 /* switch calling switch */
2325 lf_print_idecode_switch(file, entry);
2328 /* switch calling table */
2329 lf_printf(file, "return ");
2330 lf_print_idecode_table(file, entry);
2332 lf_printf(file, "break;\n");
2334 lf_indent(file, -2);
2339 lf_print_idecode_switch_illegal(lf *file)
2341 lf_indent(file, +2);
2342 lf_print_idecode_illegal(file);
2343 lf_printf(file, "break;\n");
2344 lf_indent(file, -2);
2348 idecode_switch_end(insn_table *table,
2352 lf *file = (lf*)data;
2354 ASSERT(table->opcode_rule->use_switch);
2356 if (table->opcode_rule->use_switch == 1) {
2357 lf_printf(file, "default:\n");
2358 lf_print_idecode_switch_illegal(file);
2360 lf_printf(file, "}\n");
2364 idecode_switch_padding(insn_table *table,
2369 lf *file = (lf*)data;
2372 ASSERT(table->opcode_rule->use_switch);
2374 if (table->opcode_rule->use_switch > 1) {
2375 lf_printf(file, "case %d:\n", opcode_nr);
2376 lf_print_idecode_switch_illegal(file);
2382 lf_print_idecode_switch(lf *file,
2385 insn_table_traverse_tree(table,
2388 idecode_switch_start,
2389 idecode_switch_leaf,
2391 idecode_switch_padding);
2396 idecode_expand_if_switch(insn_table *table,
2400 lf *file = (lf*)data;
2402 if (table->opcode_rule->use_switch
2403 && table->parent != NULL /* don't expand the top one yet */
2404 && !table->parent->opcode_rule->use_switch) {
2405 lf_printf(file, "\n");
2406 lf_printf(file, "STATIC_INLINE_IDECODE void\n");
2407 lf_print_table_name(file, table);
2408 lf_printf(file, "\n(%s)\n",
2409 (idecode_cache ? cache_idecode_formal : semantic_formal));
2410 lf_printf(file, "{\n");
2412 lf_indent(file, +2);
2413 lf_print_idecode_switch(file, table);
2414 lf_indent(file, -2);
2416 lf_printf(file, "}\n");
2422 lf_print_c_cracker_function(lf *file,
2424 insn_bits *expanded_bits,
2425 opcode_field *opcodes)
2427 /* if needed, generate code to enter this routine into a cache */
2428 lf_printf(file, "\n");
2429 lf_printf(file, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2430 lf_print_function_name(file,
2431 instruction->file_entry->fields[insn_name],
2433 function_name_prefix_idecode);
2434 lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2436 lf_print_c_cracker(file,
2443 idecode_crack_leaf(insn_table *entry,
2447 lf *file = (lf*)data;
2448 ASSERT(entry->nr_insn == 1
2449 && entry->opcode == NULL
2450 && entry->parent != NULL
2451 && entry->parent->opcode != NULL);
2452 lf_print_c_cracker_function(file,
2454 entry->expanded_bits,
2459 idecode_crack_insn(insn_table *entry,
2463 lf *file = (lf*)data;
2464 lf_print_c_cracker_function(file,
2471 idecode_c_internal_function(insn_table *table,
2473 table_entry *function)
2475 lf *file = (lf*)data;
2476 ASSERT(idecode_cache != 0);
2477 if (it_is("internal", function->fields[insn_flags])) {
2478 lf_printf(file, "\n");
2479 lf_printf(file, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2480 lf_print_function_name(file,
2481 function->fields[insn_name],
2483 function_name_prefix_idecode);
2484 lf_printf(file, "\n(%s)\n", cache_idecode_formal);
2485 lf_printf(file, "{\n");
2486 lf_indent(file, +2);
2487 lf_printf(file, "/* semantic routine */\n");
2488 table_entry_lf_c_line_nr(file, function);
2489 lf_printf(file, "return ");
2490 lf_print_function_name(file,
2491 function->fields[insn_name],
2493 function_name_prefix_semantics);
2494 lf_printf(file, ";\n");
2496 lf_print_lf_c_line_nr(file);
2497 lf_indent(file, -2);
2498 lf_printf(file, "}\n");
2503 /****************************************************************/
2506 gen_idecode_c(insn_table *table, lf *file)
2511 lf_print_copyleft(file);
2512 lf_printf(file, "\n");
2513 lf_printf(file, "\n");
2514 lf_printf(file, "#ifndef _IDECODE_C_\n");
2515 lf_printf(file, "#define _IDECODE_C_\n");
2516 lf_printf(file, "\n");
2517 lf_printf(file, "#ifndef STATIC_INLINE_IDECODE\n");
2518 lf_printf(file, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2519 lf_printf(file, "#endif\n");
2520 lf_printf(file, "\n");
2521 lf_printf(file, "#include \"cpu.h\"\n");
2522 lf_printf(file, "#include \"idecode.h\"\n");
2523 lf_printf(file, "#include \"semantics.h\"\n");
2524 lf_printf(file, "\n");
2525 lf_printf(file, "\n");
2526 lf_printf(file, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2527 (idecode_cache ? cache_idecode_formal : semantic_formal));
2528 lf_printf(file, "\n");
2529 lf_printf(file, "typedef struct _idecode_table_entry {\n");
2530 lf_printf(file, " unsigned shift;\n");
2531 lf_printf(file, " unsigned mask;\n");
2532 lf_printf(file, " void *function_or_table;\n");
2533 lf_printf(file, "} idecode_table_entry;\n");
2534 lf_printf(file, "\n");
2535 lf_printf(file, "\n");
2537 /* output `internal' invalid/floating-point unavailable functions
2539 if (idecode_cache) {
2540 insn_table_traverse_function(table,
2542 idecode_c_internal_function);
2545 /* output cracking functions where needed */
2546 if (idecode_cache) {
2547 if (idecode_expand_semantics)
2548 insn_table_traverse_tree(table,
2556 insn_table_traverse_insn(table,
2558 idecode_crack_insn);
2562 /* output tables where needed */
2563 for (depth = insn_table_depth(table);
2566 insn_table_traverse_tree(table,
2569 idecode_table_start,
2572 idecode_table_padding);
2575 /* output switch functions where needed */
2576 insn_table_traverse_tree(table,
2579 idecode_expand_if_switch, /* START */
2582 /* output the main idecode routine */
2583 lf_printf(file, "\n");
2585 lf_printf(file, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2586 cache_idecode_formal);
2588 lf_printf(file, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2590 lf_printf(file, "{\n");
2591 lf_indent(file, +2);
2592 if (table->opcode_rule->use_switch)
2593 lf_print_idecode_switch(file, table);
2595 lf_print_idecode_table(file, table);
2596 lf_indent(file, -2);
2597 lf_printf(file, "}\n");
2598 lf_printf(file, "\n");
2599 lf_printf(file, "#endif\n");
2603 /****************************************************************/
2606 itable_h_insn(insn_table *entry,
2610 lf *file = (lf*)data;
2611 lf_printf(file, " ");
2612 lf_print_function_name(file,
2613 instruction->file_entry->fields[insn_name],
2615 function_name_prefix_itable);
2616 lf_printf(file, ",\n");
2621 gen_itable_h(insn_table *table, lf *file)
2624 lf_print_copyleft(file);
2625 lf_printf(file, "\n");
2626 lf_printf(file, "#ifndef _ITABLE_H_\n");
2627 lf_printf(file, "#define _ITABLE_H_\n");
2628 lf_printf(file, "\n");
2629 lf_printf(file, "#ifndef INLINE_ITABLE\n");
2630 lf_printf(file, "#define INLINE_ITABLE\n");
2631 lf_printf(file, "#endif\n");
2632 lf_printf(file, "\n");
2633 lf_printf(file, "\n");
2635 /* output an enumerated type for each instruction */
2636 lf_printf(file, "typedef enum {\n");
2637 insn_table_traverse_insn(table,
2640 lf_printf(file, " nr_itable_entries,\n");
2641 lf_printf(file, "} itable_index;\n");
2642 lf_printf(file, "\n");
2644 /* output the table that contains the actual instruction info */
2645 lf_printf(file, "typedef struct _itable_instruction_info {\n");
2646 lf_printf(file, " itable_index nr;\n");
2647 lf_printf(file, " char *format;\n");
2648 lf_printf(file, " char *form;\n");
2649 lf_printf(file, " char *flags;\n");
2650 lf_printf(file, " char *nmemonic;\n");
2651 lf_printf(file, " char *name;\n");
2652 lf_printf(file, "} itable_info;\n");
2653 lf_printf(file, "\n");
2654 lf_printf(file, "extern itable_info itable[nr_itable_entries];\n");
2656 lf_printf(file, "\n");
2657 lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2661 /****************************************************************/
2664 itable_c_insn(insn_table *entry,
2668 lf *file = (lf*)data;
2669 char **fields = instruction->file_entry->fields;
2670 lf_printf(file, " { ");
2671 lf_print_function_name(file,
2672 instruction->file_entry->fields[insn_name],
2674 function_name_prefix_itable);
2675 lf_printf(file, ",\n");
2676 lf_printf(file, " \"%s\",\n", fields[insn_format]);
2677 lf_printf(file, " \"%s\",\n", fields[insn_form]);
2678 lf_printf(file, " \"%s\",\n", fields[insn_flags]);
2679 lf_printf(file, " \"%s\",\n", fields[insn_nmemonic]);
2680 lf_printf(file, " \"%s\",\n", fields[insn_name]);
2681 lf_printf(file, " },\n");
2686 gen_itable_c(insn_table *table, lf *file)
2689 lf_print_copyleft(file);
2690 lf_printf(file, "\n");
2691 lf_printf(file, "#ifndef _ITABLE_C_\n");
2692 lf_printf(file, "#define _ITABLE_C_\n");
2693 lf_printf(file, "\n");
2694 lf_printf(file, "#ifndef STATIC_INLINE_ITABLE\n");
2695 lf_printf(file, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2696 lf_printf(file, "#endif\n");
2697 lf_printf(file, "\n");
2698 lf_printf(file, "#include \"itable.h\"\n");
2699 lf_printf(file, "\n");
2701 /* output the table that contains the actual instruction info */
2702 lf_printf(file, "itable_info itable[nr_itable_entries] = {\n");
2703 insn_table_traverse_insn(table,
2706 lf_printf(file, "};\n");
2707 lf_printf(file, "\n");
2709 lf_printf(file, "\n");
2710 lf_printf(file, "#endif /* _ITABLE_C_ */\n");
2714 /****************************************************************/
2722 insn_table *instructions = NULL;
2723 icache_tree *cache_fields = NULL;
2724 char *real_file_name = NULL;
2729 printf("-f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
2730 printf("-[Ii] <instruction-table> -I to dump internal table\n");
2731 printf("-[Oo] <opcode-rules>\n");
2732 printf("-[Kk] <cache-rules>\n");
2733 printf("-[Ss] <schematic> output schematic.h(S) schematic.c(s)\n");
2734 printf("-[Dd] <schematic> output idecode.h(S) idecode.c(s)\n");
2735 printf("-[Tt] <table> output itable.h(t) itable.c(t)\n");
2736 printf("-[Cc] <schematic> output icache.h(S) invalid(s)\n");
2737 printf("-e Expand (duplicate) semantic functions\n");
2738 printf("-r <size> Generate a cracking cache of <size>\n");
2739 printf("-l Supress includsion of CPP line numbering in output files\n");
2742 while ((ch = getopt(argc, argv,
2743 "ler:f:I:i:O:o:K:k:n:S:s:D:d:T:t:C:")) != -1) {
2744 fprintf(stderr, "\t-%c %s\n", ch, (optarg ? optarg : ""));
2750 idecode_expand_semantics = 1;
2753 idecode_cache = a2i(optarg);
2757 filter *new_filter = ZALLOC(filter);
2758 new_filter->flag = strdup(optarg);
2759 new_filter->next = filters;
2760 filters = new_filter;
2765 ASSERT(opcode_table != NULL);
2766 ASSERT(cache_table != NULL);
2767 instructions = insn_table_load_insns(optarg);
2768 fprintf(stderr, "\texpanding ...\n");
2769 insn_table_expand_insns(instructions);
2770 fprintf(stderr, "\tcache fields ...\n");
2771 cache_fields = insn_table_cache_fields(instructions);
2773 dump_traverse(instructions);
2774 dump_insn_table(instructions, 0, 1);
2779 opcode_table = load_opcode_rules(optarg);
2781 dump_opcode_rules(opcode_table, 0);
2785 cache_table = load_cache_rules(optarg);
2787 dump_cache_rules(cache_table, 0);
2790 real_file_name = strdup(optarg);
2800 lf *file = lf_open(optarg, real_file_name, number_lines);
2801 ASSERT(instructions != NULL);
2804 gen_semantics_h(instructions, file);
2807 gen_semantics_c(instructions, file);
2810 gen_idecode_h(instructions, file);
2813 gen_idecode_c(instructions, file);
2816 gen_itable_h(instructions, file);
2819 gen_itable_c(instructions, file);
2822 gen_icache_h(cache_fields, file);
2827 real_file_name = NULL;
2830 error("unknown option\n");