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