Problems with conditional instruction-table fields (N!M, N=M, ...).
[binutils-gdb.git] / sim / igen / gen.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, 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
22 #include "misc.h"
23 #include "lf.h"
24 #include "table.h"
25 #include "filter.h"
26
27 #include "igen.h"
28 #include "ld-insn.h"
29 #include "ld-decode.h"
30 #include "gen.h"
31
32 static insn_uint
33 sub_val (insn_uint val,
34 int val_last_pos,
35 int first_pos,
36 int last_pos)
37 {
38 return ((val >> (val_last_pos - last_pos))
39 & (((insn_uint)1 << (last_pos - first_pos + 1)) - 1));
40 }
41
42 static void
43 update_depth (lf *file,
44 gen_entry *entry,
45 int depth,
46 void *data)
47 {
48 int *max_depth = (int*)data;
49 if (*max_depth < depth)
50 *max_depth = depth;
51 }
52
53
54 int
55 gen_entry_depth (gen_entry *table)
56 {
57 int depth = 0;
58 gen_entry_traverse_tree (NULL,
59 table,
60 1,
61 NULL, /*start*/
62 update_depth,
63 NULL, /*end*/
64 &depth); /* data */
65 return depth;
66 }
67
68
69 static void
70 print_gen_entry_path (line_ref *line,
71 gen_entry *table,
72 error_func *print)
73 {
74 if (table->parent == NULL)
75 {
76 if (table->top->model != NULL)
77 print (line, "%s", table->top->model->name);
78 else
79 print (line, "");
80 }
81 else
82 {
83 print_gen_entry_path (line, table->parent, print);
84 print (NULL, ".%d", table->opcode_nr);
85 }
86 }
87
88 static void
89 print_gen_entry_insns (gen_entry *table,
90 error_func *print,
91 char *first_message,
92 char *next_message)
93 {
94 insn_list *i;
95 char *message;
96 message = first_message;
97 for (i = table->insns; i != NULL; i = i->next)
98 {
99 insn_entry *insn = i->insn;
100 print_gen_entry_path (insn->line, table, print);
101 print (NULL, ": %s.%s %s\n",
102 insn->format_name,
103 insn->name,
104 message);
105 if (next_message != NULL)
106 message = next_message;
107 }
108 }
109
110 /* same as strcmp */
111 static int
112 insn_field_cmp (insn_word_entry *l, insn_word_entry *r)
113 {
114 while (1)
115 {
116 int bit_nr;
117 if (l == NULL && r == NULL)
118 return 0; /* all previous fields the same */
119 if (l == NULL)
120 return -1; /* left shorter than right */
121 if (r == NULL)
122 return +1; /* left longer than right */
123 for (bit_nr = 0;
124 bit_nr < options.insn_bit_size;
125 bit_nr++)
126 {
127 if (l->bit[bit_nr]->field->type != insn_field_string)
128 continue;
129 if (r->bit[bit_nr]->field->type != insn_field_string)
130 continue;
131 if (l->bit[bit_nr]->field->conditions == NULL)
132 continue;
133 if (r->bit[bit_nr]->field->conditions == NULL)
134 continue;
135 if (0)
136 printf ("%s%s%s VS %s%s%s\n",
137 l->bit[bit_nr]->field->val_string,
138 l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!",
139 l->bit[bit_nr]->field->conditions->string,
140 r->bit[bit_nr]->field->val_string,
141 r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq ? "=" : "!",
142 r->bit[bit_nr]->field->conditions->string);
143 if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq
144 && r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
145 {
146 if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field
147 && r->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
148 /* somewhat arbitrary */
149 {
150 int cmp = strcmp (l->bit[bit_nr]->field->conditions->string,
151 r->bit[bit_nr]->field->conditions->string);
152 if (cmp != 0)
153 return cmp;
154 else
155 continue;
156 }
157 if (l->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
158 return +1;
159 if (r->bit[bit_nr]->field->conditions->type == insn_field_cond_field)
160 return -1;
161 /* The case of both fields having constant values should have
162 already have been handled because such fields are converted
163 into normal constant fields. */
164 continue;
165 }
166 if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
167 return +1; /* left = only */
168 if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq)
169 return -1; /* right = only */
170 /* FIXME: Need to some what arbitrarily order conditional lists */
171 continue;
172 }
173 l = l->next;
174 r = r->next;
175 }
176 }
177
178 /* same as strcmp */
179 static int
180 insn_word_cmp (insn_word_entry *l, insn_word_entry *r)
181 {
182 while (1)
183 {
184 int bit_nr;
185 if (l == NULL && r == NULL)
186 return 0; /* all previous fields the same */
187 if (l == NULL)
188 return -1; /* left shorter than right */
189 if (r == NULL)
190 return +1; /* left longer than right */
191 for (bit_nr = 0;
192 bit_nr < options.insn_bit_size;
193 bit_nr++)
194 {
195 if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask)
196 return -1;
197 if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask)
198 return 1;
199 if (l->bit[bit_nr]->value < r->bit[bit_nr]->value)
200 return -1;
201 if (l->bit[bit_nr]->value > r->bit[bit_nr]->value)
202 return 1;
203 }
204 l = l->next;
205 r = r->next;
206 }
207 }
208
209 /* same as strcmp */
210 static int
211 opcode_bit_cmp (opcode_bits *l,
212 opcode_bits *r)
213 {
214 if (l == NULL && r == NULL)
215 return 0; /* all previous bits the same */
216 if (l == NULL)
217 return -1; /* left shorter than right */
218 if (r == NULL)
219 return +1; /* left longer than right */
220 /* most significant word */
221 if (l->field->word_nr < r->field->word_nr)
222 return +1; /* left has more significant word */
223 if (l->field->word_nr > r->field->word_nr)
224 return -1; /* right has more significant word */
225 /* most significant bit? */
226 if (l->first < r->first)
227 return +1; /* left as more significant bit */
228 if (l->first > r->first)
229 return -1; /* right as more significant bit */
230 /* nr bits? */
231 if (l->last < r->last)
232 return +1; /* left as less bits */
233 if (l->last > r->last)
234 return -1; /* right as less bits */
235 /* value? */
236 if (l->value < r->value)
237 return -1;
238 if (l->value > r->value)
239 return 1;
240 return 0;
241 }
242
243
244 /* same as strcmp */
245 static int
246 opcode_bits_cmp (opcode_bits *l,
247 opcode_bits *r)
248 {
249 while (1)
250 {
251 int cmp;
252 if (l == NULL && r == NULL)
253 return 0; /* all previous bits the same */
254 cmp = opcode_bit_cmp (l, r);
255 if (cmp != 0)
256 return cmp;
257 l = l->next;
258 r = r->next;
259 }
260 }
261
262 /* same as strcmp */
263 static opcode_bits *
264 new_opcode_bits (opcode_bits *old_bits,
265 int value,
266 int first,
267 int last,
268 insn_field_entry *field,
269 opcode_field *opcode)
270 {
271 opcode_bits *new_bits = ZALLOC (opcode_bits);
272 new_bits->field = field;
273 new_bits->value = value;
274 new_bits->first = first;
275 new_bits->last = last;
276 new_bits->opcode = opcode;
277
278 if (old_bits != NULL)
279 {
280 opcode_bits *new_list;
281 opcode_bits **last = &new_list;
282 new_list = new_opcode_bits (old_bits->next,
283 old_bits->value,
284 old_bits->first,
285 old_bits->last,
286 old_bits->field,
287 old_bits->opcode);
288 while (*last != NULL)
289 {
290 int cmp = opcode_bit_cmp (new_bits, *last);
291 if (cmp < 0) /* new < new_list */
292 {
293 break;
294 }
295 if (cmp == 0)
296 {
297 ERROR ("Duplicated insn bits in list");
298 }
299 last = &(*last)->next;
300 }
301 new_bits->next = *last;
302 *last = new_bits;
303 return new_list;
304 }
305 else
306 {
307 return new_bits;
308 }
309 }
310
311
312
313
314 typedef enum {
315 merge_duplicate_insns,
316 report_duplicate_insns,
317 } duplicate_insn_actions;
318
319 static insn_list *
320 insn_list_insert (insn_list **cur_insn_ptr,
321 int *nr_insns,
322 insn_entry *insn,
323 opcode_bits *expanded_bits,
324 opcode_field *opcodes,
325 int nr_prefetched_words,
326 duplicate_insn_actions duplicate_action)
327 {
328 /* insert it according to the order of the fields & bits */
329 for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next)
330 {
331 int cmp;
332
333 /* key#1 sort according to the constant fields of each instruction */
334 cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words);
335 if (cmp < 0)
336 break;
337 else if (cmp > 0)
338 continue;
339
340 /* key#2 sort according to the expanded bits of each instruction */
341 cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits);
342 if (cmp < 0)
343 break;
344 else if (cmp > 0)
345 continue;
346
347 /* key#3 sort according to the non-constant fields of each instruction */
348 cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words);
349 if (cmp < 0)
350 break;
351 else if (cmp > 0)
352 continue;
353
354 /* duplicate keys, report problem */
355 switch (duplicate_action)
356 {
357 case report_duplicate_insns:
358 /* two instructions with the same constant field
359 values across all words and bits */
360 warning (insn->line,
361 "Two instructions with identical constant fields\n");
362 error ((*cur_insn_ptr)->insn->line,
363 "Location of second (duplicated?) instruction\n");
364 case merge_duplicate_insns:
365 /* Add the opcode path to the instructions list */
366 if (opcodes != NULL)
367 {
368 insn_opcodes **last = &(*cur_insn_ptr)->opcodes;
369 while (*last != NULL)
370 {
371 last = &(*last)->next;
372 }
373 (*last) = ZALLOC (insn_opcodes);
374 (*last)->opcode = opcodes;
375 }
376 /* Use the larger nr_prefetched_words */
377 if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words)
378 (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words;
379 return (*cur_insn_ptr);
380 }
381
382 }
383
384 /* create a new list entry and insert it */
385 {
386 insn_list *new_insn = ZALLOC (insn_list);
387 new_insn->insn = insn;
388 new_insn->expanded_bits = expanded_bits;
389 new_insn->next = (*cur_insn_ptr);
390 new_insn->nr_prefetched_words = nr_prefetched_words;
391 if (opcodes != NULL)
392 {
393 new_insn->opcodes = ZALLOC (insn_opcodes);
394 new_insn->opcodes->opcode = opcodes;
395 }
396 (*cur_insn_ptr) = new_insn;
397 }
398
399 *nr_insns += 1;
400
401 return (*cur_insn_ptr);
402 }
403
404
405 extern void
406 gen_entry_traverse_tree (lf *file,
407 gen_entry *table,
408 int depth,
409 gen_entry_handler *start,
410 gen_entry_handler *leaf,
411 gen_entry_handler *end,
412 void *data)
413 {
414 gen_entry *entry;
415
416 ASSERT (table != NULL);
417 ASSERT (table->opcode != NULL);
418 ASSERT (table->nr_entries > 0);
419 ASSERT (table->entries != 0);
420
421 /* prefix */
422 if (start != NULL && depth >= 0)
423 {
424 start (file, table, depth, data);
425 }
426 /* infix leaves */
427 for (entry = table->entries;
428 entry != NULL;
429 entry = entry->sibling)
430 {
431 if (entry->entries != NULL && depth != 0)
432 {
433 gen_entry_traverse_tree (file, entry, depth + 1,
434 start, leaf, end, data);
435 }
436 else if (depth >= 0)
437 {
438 if (leaf != NULL)
439 {
440 leaf (file, entry, depth, data);
441 }
442 }
443 }
444 /* postfix */
445 if (end != NULL && depth >= 0)
446 {
447 end (file, table, depth, data);
448 }
449 }
450
451
452
453 /* create a list element containing a single gen_table entry */
454
455 static gen_list *
456 make_table (insn_table *isa,
457 decode_table *rules,
458 model_entry *model)
459 {
460 insn_entry *insn;
461 gen_list *entry = ZALLOC (gen_list);
462 entry->table = ZALLOC (gen_entry);
463 entry->table->top = entry;
464 entry->model = model;
465 entry->isa = isa;
466 for (insn = isa->insns; insn != NULL; insn = insn->next)
467 {
468 if (model == NULL
469 || insn->processors == NULL
470 || filter_is_member (insn->processors, model->name))
471 {
472 insn_list_insert (&entry->table->insns,
473 &entry->table->nr_insns,
474 insn,
475 NULL, /* expanded_bits - none yet */
476 NULL, /* opcodes - none yet */
477 0, /* nr_prefetched_words - none yet */
478 report_duplicate_insns);
479 }
480 }
481 entry->table->opcode_rule = rules;
482 return entry;
483 }
484
485
486 gen_table *
487 make_gen_tables (insn_table *isa,
488 decode_table *rules)
489 {
490 gen_table *gen = ZALLOC (gen_table);
491 gen->isa = isa;
492 gen->rules = rules;
493 if (options.gen.multi_sim)
494 {
495 gen_list **last = &gen->tables;
496 model_entry *model;
497 filter *processors;
498 if (options.model_filter != NULL)
499 processors = options.model_filter;
500 else
501 processors = isa->model->processors;
502 for (model = isa->model->models;
503 model != NULL;
504 model = model->next)
505 {
506 if (filter_is_member (processors, model->name))
507 {
508 *last = make_table (isa, rules, model);
509 last = &(*last)->next;
510 }
511 }
512 }
513 else
514 {
515 gen->tables = make_table (isa, rules, NULL);
516 }
517 return gen;
518 }
519
520
521 /****************************************************************/
522
523 #if 0
524 typedef enum {
525 field_is_not_constant = 0,
526 field_constant_int = 1,
527 field_constant_reserved = 2,
528 field_constant_string = 3
529 } constant_field_types;
530
531 static constant_field_types
532 insn_field_is_constant (insn_field *field,
533 decode_table *rule)
534 {
535 switch (field->type)
536 {
537 case insn_field_int:
538 /* field is an integer */
539 return field_constant_int;
540 case insn_field_reserved:
541 /* field is `/' and treating that as a constant */
542 if (rule->with_zero_reserved)
543 return field_constant_reserved;
544 else
545 return field_is_not_constant;
546 case insn_field_wild:
547 return field_is_not_constant; /* never constant */
548 case insn_field_string:
549 /* field, though variable, is on the list of forced constants */
550 if (filter_is_member (rule->constant_field_names, field->val_string))
551 return field_constant_string;
552 else
553 return field_is_not_constant;
554 }
555 ERROR ("Internal error");
556 return field_is_not_constant;
557 }
558 #endif
559
560
561 /****************************************************************/
562
563
564 /* Is the bit, according to the decode rule, identical across all the
565 instructions? */
566 static int
567 insns_bit_useless (insn_list *insns,
568 decode_table *rule,
569 int bit_nr)
570 {
571 insn_list *entry;
572 int value = -1;
573 int is_useless = 1; /* cleared if something actually found */
574
575 /* check the instructions for some constant value in at least one of
576 the bit fields */
577 for (entry = insns; entry != NULL; entry = entry->next)
578 {
579 insn_word_entry *word = entry->insn->word[rule->word_nr];
580 insn_bit_entry *bit = word->bit[bit_nr];
581 switch (bit->field->type)
582 {
583 case insn_field_invalid:
584 ASSERT (0);
585 break;
586 case insn_field_wild:
587 case insn_field_reserved:
588 /* neither useless or useful - ignore */
589 break;
590 case insn_field_int:
591 switch (rule->search)
592 {
593 case decode_find_strings:
594 /* an integer isn't a string */
595 return 1;
596 case decode_find_constants:
597 case decode_find_mixed:
598 /* an integer is useful if its value isn't the same
599 between all instructions. The first time through the
600 value is saved, the second time through (if the
601 values differ) it is marked as useful. */
602 if (value < 0)
603 value = bit->value;
604 else if (value != bit->value)
605 is_useless = 0;
606 break;
607 }
608 break;
609 case insn_field_string:
610 switch (rule->search)
611 {
612 case decode_find_strings:
613 /* at least one string, keep checking */
614 is_useless = 0;
615 break;
616 case decode_find_constants:
617 case decode_find_mixed:
618 if (filter_is_member (rule->constant_field_names,
619 bit->field->val_string))
620 /* a string field forced to constant? */
621 is_useless = 0;
622 else if (rule->search == decode_find_constants)
623 /* the string field isn't constant */
624 return 1;
625 break;
626 }
627 }
628 }
629
630 /* Given only one constant value has been found, check through all
631 the instructions to see if at least one conditional makes it
632 usefull */
633 if (value >= 0 && is_useless)
634 {
635 for (entry = insns; entry != NULL; entry = entry->next)
636 {
637 insn_word_entry *word = entry->insn->word[rule->word_nr];
638 insn_bit_entry *bit = word->bit[bit_nr];
639 switch (bit->field->type)
640 {
641 case insn_field_invalid:
642 ASSERT (0);
643 break;
644 case insn_field_wild:
645 case insn_field_reserved:
646 case insn_field_int:
647 /* already processed */
648 break;
649 case insn_field_string:
650 switch (rule->search)
651 {
652 case decode_find_strings:
653 case decode_find_constants:
654 /* already processed */
655 break;
656 case decode_find_mixed:
657 /* string field with conditions. If this condition
658 eliminates the value then the compare is useful */
659 if (bit->field->conditions != NULL)
660 {
661 insn_field_cond *condition;
662 int shift = bit->field->last - bit_nr;
663 for (condition = bit->field->conditions;
664 condition != NULL;
665 condition = condition->next)
666 {
667 switch (condition->type)
668 {
669 case insn_field_cond_value:
670 switch (condition->test)
671 {
672 case insn_field_cond_ne:
673 if (((condition->value >> shift) & 1)
674 == (unsigned) value)
675 /* conditional field excludes the
676 current value */
677 is_useless = 0;
678 break;
679 case insn_field_cond_eq:
680 if (((condition->value >> shift) & 1)
681 != (unsigned) value)
682 /* conditional field requires the
683 current value */
684 is_useless = 0;
685 break;
686 }
687 break;
688 case insn_field_cond_field:
689 /* are these handled separatly? */
690 break;
691 }
692 }
693 }
694 }
695 }
696 }
697 }
698
699 return is_useless;
700 }
701
702
703 /* go through a gen-table's list of instruction formats looking for a
704 range of bits that meet the decode table RULEs requirements */
705
706 static opcode_field *
707 gen_entry_find_opcode_field (insn_list *insns,
708 decode_table *rule,
709 int string_only)
710 {
711 opcode_field curr_opcode;
712 ASSERT (rule != NULL);
713
714 memset (&curr_opcode, 0, sizeof (curr_opcode));
715 curr_opcode.word_nr = rule->word_nr;
716 curr_opcode.first = rule->first;
717 curr_opcode.last = rule->last;
718
719 /* Try to reduce the size of first..last in accordance with the
720 decode rules */
721
722 while (curr_opcode.first <= rule->last)
723 {
724 if (insns_bit_useless (insns, rule, curr_opcode.first))
725 curr_opcode.first ++;
726 else
727 break;
728 }
729 while (curr_opcode.last >= rule->first)
730 {
731 if (insns_bit_useless (insns, rule, curr_opcode.last))
732 curr_opcode.last --;
733 else
734 break;
735 }
736
737
738 #if 0
739 for (entry = insns; entry != NULL; entry = entry->next)
740 {
741 insn_word_entry *fields = entry->insn->word[rule->word_nr];
742 opcode_field new_opcode;
743
744 ASSERT (fields != NULL);
745
746 /* find a start point for the opcode field */
747 new_opcode.first = rule->first;
748 while (new_opcode.first <= rule->last
749 && (!string_only
750 || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
751 != field_constant_string))
752 && (string_only
753 || (insn_field_is_constant(fields->bit[new_opcode.first], rule)
754 == field_is_not_constant)))
755 {
756 int new_first = fields->bit[new_opcode.first]->last + 1;
757 ASSERT (new_first > new_opcode.first);
758 new_opcode.first = new_first;
759 }
760 ASSERT(new_opcode.first > rule->last
761 || (string_only
762 && insn_field_is_constant(fields->bit[new_opcode.first],
763 rule) == field_constant_string)
764 || (!string_only
765 && insn_field_is_constant(fields->bit[new_opcode.first],
766 rule)));
767
768 /* find the end point for the opcode field */
769 new_opcode.last = rule->last;
770 while (new_opcode.last >= rule->first
771 && (!string_only
772 || insn_field_is_constant(fields->bit[new_opcode.last],
773 rule) != field_constant_string)
774 && (string_only
775 || !insn_field_is_constant(fields->bit[new_opcode.last],
776 rule)))
777 {
778 int new_last = fields->bit[new_opcode.last]->first - 1;
779 ASSERT (new_last < new_opcode.last);
780 new_opcode.last = new_last;
781 }
782 ASSERT(new_opcode.last < rule->first
783 || (string_only
784 && insn_field_is_constant(fields->bit[new_opcode.last],
785 rule) == field_constant_string)
786 || (!string_only
787 && insn_field_is_constant(fields->bit[new_opcode.last],
788 rule)));
789
790 /* now see if our current opcode needs expanding to include the
791 interesting fields within this instruction */
792 if (new_opcode.first <= rule->last
793 && curr_opcode.first > new_opcode.first)
794 curr_opcode.first = new_opcode.first;
795 if (new_opcode.last >= rule->first
796 && curr_opcode.last < new_opcode.last)
797 curr_opcode.last = new_opcode.last;
798
799 }
800 #endif
801
802 /* did the final opcode field end up being empty? */
803 if (curr_opcode.first > curr_opcode.last)
804 {
805 return NULL;
806 }
807 ASSERT (curr_opcode.last >= rule->first);
808 ASSERT (curr_opcode.first <= rule->last);
809 ASSERT (curr_opcode.first <= curr_opcode.last);
810
811 /* Ensure that, for the non string only case, the opcode includes
812 the range forced_first .. forced_last */
813 if (!string_only
814 && curr_opcode.first > rule->force_first)
815 {
816 curr_opcode.first = rule->force_first;
817 }
818 if (!string_only
819 && curr_opcode.last < rule->force_last)
820 {
821 curr_opcode.last = rule->force_last;
822 }
823
824 /* For the string only case, force just the lower bound (so that the
825 shift can be eliminated) */
826 if (string_only
827 && rule->force_last == options.insn_bit_size - 1)
828 {
829 curr_opcode.last = options.insn_bit_size - 1;
830 }
831
832 /* handle any special cases */
833 switch (rule->type)
834 {
835 case normal_decode_rule:
836 /* let the above apply */
837 curr_opcode.nr_opcodes =
838 (1 << (curr_opcode.last - curr_opcode.first + 1));
839 break;
840 case boolean_rule:
841 curr_opcode.is_boolean = 1;
842 curr_opcode.boolean_constant = rule->constant;
843 curr_opcode.nr_opcodes = 2;
844 break;
845 }
846
847 {
848 opcode_field *new_field = ZALLOC (opcode_field);
849 memcpy (new_field, &curr_opcode, sizeof (opcode_field));
850 return new_field;
851 }
852 }
853
854
855 static void
856 gen_entry_insert_insn (gen_entry *table,
857 insn_entry *old_insn,
858 int new_word_nr,
859 int new_nr_prefetched_words,
860 int new_opcode_nr,
861 opcode_bits *new_bits)
862 {
863 gen_entry **entry = &table->entries;
864
865 /* find the new table for this entry */
866 while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr)
867 {
868 entry = &(*entry)->sibling;
869 }
870
871 if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr)
872 {
873 /* insert the missing entry */
874 gen_entry *new_entry = ZALLOC (gen_entry);
875 new_entry->sibling = (*entry);
876 (*entry) = new_entry;
877 table->nr_entries++;
878 /* fill it in */
879 new_entry->top = table->top;
880 new_entry->opcode_nr = new_opcode_nr;
881 new_entry->word_nr = new_word_nr;
882 new_entry->expanded_bits = new_bits;
883 new_entry->opcode_rule = table->opcode_rule->next;
884 new_entry->parent = table;
885 new_entry->nr_prefetched_words = new_nr_prefetched_words;
886 }
887 /* ASSERT new_bits == cur_entry bits */
888 ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr);
889 insn_list_insert (&(*entry)->insns,
890 &(*entry)->nr_insns,
891 old_insn,
892 NULL, /* expanded_bits - only in final list */
893 NULL, /* opcodes - only in final list */
894 new_nr_prefetched_words, /* for this table */
895 report_duplicate_insns);
896 }
897
898
899 static void
900 gen_entry_expand_opcode (gen_entry *table,
901 insn_entry *instruction,
902 int bit_nr,
903 int opcode_nr,
904 opcode_bits *bits)
905 {
906 if (bit_nr > table->opcode->last)
907 {
908 /* Only include the hardwired bit information with an entry IF
909 that entry (and hence its functions) are being duplicated. */
910 if (options.trace.insn_expansion)
911 {
912 print_gen_entry_path (table->opcode_rule->line, table, notify);
913 notify (NULL, ": insert %d - %s.%s%s\n",
914 opcode_nr,
915 instruction->format_name,
916 instruction->name,
917 (table->opcode_rule->with_duplicates ? " (duplicated)" : ""));
918 }
919 if (table->opcode_rule->with_duplicates)
920 {
921 gen_entry_insert_insn (table, instruction,
922 table->opcode->word_nr,
923 table->nr_prefetched_words,
924 opcode_nr, bits);
925 }
926 else
927 {
928 gen_entry_insert_insn (table, instruction,
929 table->opcode->word_nr,
930 table->nr_prefetched_words,
931 opcode_nr, NULL);
932 }
933 }
934 else
935 {
936 insn_word_entry *word = instruction->word[table->opcode->word_nr];
937 insn_field_entry *field = word->bit[bit_nr]->field;
938 int last_pos = ((field->last < table->opcode->last)
939 ? field->last
940 : table->opcode->last);
941 int first_pos = ((field->first > table->opcode->first)
942 ? field->first
943 : table->opcode->first);
944 int width = last_pos - first_pos + 1;
945 switch (field->type)
946 {
947 case insn_field_int:
948 {
949 int val;
950 val = sub_val (field->val_int, field->last,
951 first_pos, last_pos);
952 gen_entry_expand_opcode (table, instruction,
953 last_pos + 1,
954 ((opcode_nr << width) | val),
955 bits);
956 break;
957 }
958 default:
959 {
960 if (field->type == insn_field_reserved)
961 gen_entry_expand_opcode (table, instruction,
962 last_pos + 1,
963 ((opcode_nr << width)),
964 bits);
965 else
966 {
967 int val;
968 int last_val = (table->opcode->is_boolean
969 ? 2
970 : (1 << width));
971 for (val = 0; val < last_val; val++)
972 {
973 /* check to see if the value has been precluded
974 (by a conditional) in some way */
975 int is_precluded;
976 insn_field_cond *condition;
977 for (condition = field->conditions, is_precluded = 0;
978 condition != NULL && !is_precluded;
979 condition = condition->next)
980 {
981 switch (condition->type)
982 {
983 case insn_field_cond_value:
984 {
985 int value = sub_val (condition->value, field->last,
986 first_pos, last_pos);
987 switch (condition->test)
988 {
989 case insn_field_cond_ne:
990 if (value == val)
991 is_precluded = 1;
992 break;
993 case insn_field_cond_eq:
994 if (value != val)
995 is_precluded = 1;
996 break;
997 }
998 break;
999 }
1000 case insn_field_cond_field:
1001 {
1002 int value;
1003 opcode_bits *bit;
1004 gen_entry *t;
1005 /* Try to find a value for the
1006 conditional by looking back through
1007 the previously defined bits for the
1008 specified conditional field */
1009 for (bit = bits;
1010 bit != NULL;
1011 bit = bit->next)
1012 {
1013 if (bit->field == condition->field
1014 && (bit->last - bit->first + 1 == condition->field->width))
1015 {
1016 /* the bit field fully specified
1017 the conditional field's value */
1018 value = sub_val (bit->value, bit->last,
1019 first_pos, last_pos);
1020 break;
1021 }
1022 }
1023 /* Try to find a value by looking
1024 through this and previous tables */
1025 if (bit == NULL)
1026 {
1027 for (t = table;
1028 t->parent != NULL;
1029 t = t->parent)
1030 {
1031 if (t->parent->opcode->word_nr != condition->field->word_nr)
1032 continue;
1033 if (t->parent->opcode->first <= condition->field->first
1034 && t->parent->opcode->last >= condition->field->last)
1035 {
1036 /* the table entry fully
1037 specified the condition
1038 field's value */
1039 value = sub_val (t->opcode_nr, t->parent->opcode->last,
1040 first_pos, last_pos);
1041 }
1042 }
1043 }
1044 if (bit == NULL && t == NULL)
1045 error (instruction->line,
1046 "Conditional `%s' of field `%s' isn't expanded",
1047 condition->string, field->val_string);
1048 switch (condition->test)
1049 {
1050 case insn_field_cond_ne:
1051 if (value == val)
1052 is_precluded = 1;
1053 break;
1054 case insn_field_cond_eq:
1055 if (value != val)
1056 is_precluded = 1;
1057 break;
1058 }
1059 break;
1060 }
1061 }
1062 }
1063 if (!is_precluded)
1064 {
1065 /* Only add additional hardwired bit
1066 information if the entry is not going to
1067 later be combined */
1068 if (table->opcode_rule->with_combine)
1069 {
1070 gen_entry_expand_opcode (table, instruction,
1071 last_pos + 1,
1072 ((opcode_nr << width) | val),
1073 bits);
1074 }
1075 else
1076 {
1077 opcode_bits *new_bits = new_opcode_bits (bits, val,
1078 first_pos, last_pos,
1079 field,
1080 table->opcode);
1081 gen_entry_expand_opcode (table, instruction,
1082 last_pos + 1,
1083 ((opcode_nr << width) | val),
1084 new_bits);
1085 }
1086 }
1087 }
1088 }
1089 }
1090 }
1091 }
1092 }
1093
1094 static void
1095 gen_entry_insert_expanding (gen_entry *table,
1096 insn_entry *instruction)
1097 {
1098 gen_entry_expand_opcode (table,
1099 instruction,
1100 table->opcode->first,
1101 0,
1102 table->expanded_bits);
1103 }
1104
1105
1106 static int
1107 insns_match_format_names (insn_list *insns,
1108 filter *format_names)
1109 {
1110 if (format_names != NULL)
1111 {
1112 insn_list *i;
1113 for (i = insns; i != NULL; i = i->next)
1114 {
1115 if ( i->insn->format_name != NULL
1116 && !filter_is_member (format_names, i->insn->format_name))
1117 return 0;
1118 }
1119 }
1120 return 1;
1121 }
1122
1123 static int
1124 table_matches_path (gen_entry *table,
1125 decode_path_list *paths)
1126 {
1127 if (paths == NULL)
1128 return 1;
1129 while (paths != NULL)
1130 {
1131 gen_entry *entry = table;
1132 decode_path *path = paths->path;
1133 while (1)
1134 {
1135 if (entry == NULL && path == NULL)
1136 return 1;
1137 if (entry == NULL || path == NULL)
1138 break;
1139 if (entry->opcode_nr != path->opcode_nr)
1140 break;
1141 entry = entry->parent;
1142 path = path->parent;
1143 }
1144 paths = paths->next;
1145 }
1146 return 0;
1147 }
1148
1149
1150 static int
1151 insns_match_conditions (insn_list *insns,
1152 decode_cond *conditions)
1153 {
1154 if (conditions != NULL)
1155 {
1156 insn_list *i;
1157 for (i = insns; i != NULL; i = i->next)
1158 {
1159 decode_cond *cond;
1160 for (cond = conditions; cond != NULL; cond = cond->next)
1161 {
1162 int bit_nr;
1163 if (i->insn->nr_words <= cond->word_nr)
1164 return 0;
1165 for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1166 {
1167 if (!cond->mask[bit_nr])
1168 continue;
1169 if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask)
1170 return 0;
1171 if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value
1172 == cond->value[bit_nr])
1173 == !cond->is_equal)
1174 return 0;
1175 }
1176 }
1177 }
1178 }
1179 return 1;
1180 }
1181
1182 static int
1183 insns_match_nr_words (insn_list *insns,
1184 int nr_words)
1185 {
1186 insn_list *i;
1187 for (i = insns; i != NULL; i = i->next)
1188 {
1189 if (i->insn->nr_words < nr_words)
1190 return 0;
1191 }
1192 return 1;
1193 }
1194
1195 static int
1196 insn_list_cmp (insn_list *l,
1197 insn_list *r)
1198 {
1199 while (1)
1200 {
1201 insn_entry *insn;
1202 if (l == NULL && r == NULL)
1203 return 0;
1204 if (l == NULL)
1205 return -1;
1206 if (r == NULL)
1207 return 1;
1208 if (l->insn != r->insn)
1209 return -1; /* somewhat arbitrary at present */
1210 /* skip this insn */
1211 insn = l->insn;
1212 while (l != NULL && l->insn == insn)
1213 l = l->next;
1214 while (r != NULL && r->insn == insn)
1215 r = r->next;
1216 }
1217 }
1218
1219
1220
1221 static void
1222 gen_entry_expand_insns (gen_entry *table)
1223 {
1224 decode_table *opcode_rule;
1225
1226 ASSERT(table->nr_insns >= 1);
1227
1228 /* determine a valid opcode */
1229 for (opcode_rule = table->opcode_rule;
1230 opcode_rule != NULL;
1231 opcode_rule = opcode_rule->next)
1232 {
1233 char *discard_reason;
1234 if (table->top->model != NULL
1235 && opcode_rule->model_names != NULL
1236 && !filter_is_member (opcode_rule->model_names,
1237 table->top->model->name))
1238 {
1239 /* the rule isn't applicable to this processor */
1240 discard_reason = "wrong model";
1241 }
1242 else if (table->nr_insns == 1 && opcode_rule->conditions == NULL)
1243 {
1244 /* for safety, require a pre-codition when attempting to
1245 apply a rule to a single instruction */
1246 discard_reason = "need pre-condition when nr-insn == 1";
1247 }
1248 else if (table->nr_insns == 1 && !opcode_rule->with_duplicates)
1249 {
1250 /* Little point in expanding a single instruction when we're
1251 not duplicating the semantic functions that this table
1252 calls */
1253 discard_reason = "need duplication with nr-insns == 1";
1254 }
1255 else if (!insns_match_format_names (table->insns, opcode_rule->format_names))
1256 {
1257 discard_reason = "wrong format name";
1258 }
1259 else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1))
1260 {
1261 discard_reason = "wrong nr words";
1262 }
1263 else if (!table_matches_path (table, opcode_rule->paths))
1264 {
1265 discard_reason = "path failed";
1266 }
1267 else if (!insns_match_conditions (table->insns, opcode_rule->conditions))
1268 {
1269 discard_reason = "condition failed";
1270 }
1271 else
1272 {
1273 discard_reason = "no opcode field";
1274 table->opcode =
1275 gen_entry_find_opcode_field (table->insns,
1276 opcode_rule,
1277 table->nr_insns == 1/*string-only*/
1278 );
1279 if (table->opcode != NULL)
1280 {
1281 table->opcode_rule = opcode_rule;
1282 break;
1283 }
1284 }
1285
1286 if (options.trace.rule_rejection)
1287 {
1288 print_gen_entry_path (opcode_rule->line, table, notify);
1289 notify (NULL, ": rule discarded - %s\n", discard_reason);
1290 }
1291 }
1292
1293 /* did we find anything */
1294 if (opcode_rule == NULL)
1295 {
1296 /* the decode table failed, this set of instructions haven't
1297 been uniquely identified */
1298 if (table->nr_insns > 1)
1299 {
1300 print_gen_entry_insns (table, warning,
1301 "was not uniquely decoded",
1302 "decodes to the same entry");
1303 error (NULL, "");
1304 }
1305 return;
1306 }
1307
1308 /* Determine the number of words that must have been prefetched for
1309 this table to function */
1310 if (table->parent == NULL)
1311 table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
1312 else if (table->opcode_rule->word_nr + 1 > table->parent->nr_prefetched_words)
1313 table->nr_prefetched_words = table->opcode_rule->word_nr + 1;
1314 else
1315 table->nr_prefetched_words = table->parent->nr_prefetched_words;
1316
1317 /* back link what we found to its parent */
1318 if (table->parent != NULL)
1319 {
1320 ASSERT(table->parent->opcode != NULL);
1321 table->opcode->parent = table->parent->opcode;
1322 }
1323
1324 /* report the rule being used to expand the instructions */
1325 if (options.trace.rule_selection)
1326 {
1327 print_gen_entry_path (table->opcode_rule->line, table, notify);
1328 notify (NULL,
1329 ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
1330 table->opcode->word_nr,
1331 i2target (options.hi_bit_nr, table->opcode->first),
1332 i2target (options.hi_bit_nr, table->opcode->last),
1333 i2target (options.hi_bit_nr, table->opcode_rule->first),
1334 i2target (options.hi_bit_nr, table->opcode_rule->last),
1335 table->opcode->nr_opcodes,
1336 table->nr_entries);
1337 }
1338
1339 /* expand the raw instructions according to the opcode */
1340 {
1341 insn_list *entry;
1342 for (entry = table->insns; entry != NULL; entry = entry->next)
1343 {
1344 if (options.trace.insn_expansion)
1345 {
1346 print_gen_entry_path (table->opcode_rule->line, table, notify);
1347 notify (NULL, ": expand - %s.%s\n",
1348 entry->insn->format_name,
1349 entry->insn->name);
1350 }
1351 gen_entry_insert_expanding (table, entry->insn);
1352 }
1353 }
1354
1355 /* dump the results */
1356 if (options.trace.entries)
1357 {
1358 gen_entry *entry;
1359 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1360 {
1361 insn_list *l;
1362 print_gen_entry_path (table->opcode_rule->line, entry, notify);
1363 notify (NULL, ": %d - entries %d -",
1364 entry->opcode_nr,
1365 entry->nr_insns);
1366 for (l = entry->insns; l != NULL; l = l->next)
1367 notify (NULL, " %s.%s", l->insn->format_name, l->insn->name);
1368 notify (NULL, "\n");
1369 }
1370 }
1371
1372 /* perform a combine pass if needed */
1373 if (table->opcode_rule->with_combine)
1374 {
1375 gen_entry *entry;
1376 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1377 {
1378 if (entry->combined_parent == NULL)
1379 {
1380 gen_entry **last = &entry->combined_next;
1381 gen_entry *alt;
1382 for (alt = entry->sibling; alt != NULL; alt = alt->sibling)
1383 {
1384 if (alt->combined_parent == NULL
1385 && insn_list_cmp (entry->insns, alt->insns) == 0)
1386 {
1387 alt->combined_parent = entry;
1388 *last = alt;
1389 last = &alt->combined_next;
1390 }
1391 }
1392 }
1393 }
1394 if (options.trace.combine)
1395 {
1396 int nr_unique = 0;
1397 gen_entry *entry;
1398 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1399 {
1400 if (entry->combined_parent == NULL)
1401 {
1402 insn_list *l;
1403 gen_entry *duplicate;
1404 nr_unique++;
1405 print_gen_entry_path (table->opcode_rule->line, entry, notify);
1406 for (duplicate = entry->combined_next;
1407 duplicate != NULL;
1408 duplicate = duplicate->combined_next)
1409 {
1410 notify (NULL, "+%d", duplicate->opcode_nr);
1411 }
1412 notify (NULL, ": entries %d -", entry->nr_insns);
1413 for (l = entry->insns; l != NULL; l = l->next)
1414 {
1415 notify (NULL, " %s.%s",
1416 l->insn->format_name,
1417 l->insn->name);
1418 }
1419 notify (NULL, "\n");
1420 }
1421 }
1422 print_gen_entry_path (table->opcode_rule->line, table, notify);
1423 notify (NULL, ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
1424 table->opcode->word_nr,
1425 i2target (options.hi_bit_nr, table->opcode->first),
1426 i2target (options.hi_bit_nr, table->opcode->last),
1427 i2target (options.hi_bit_nr, table->opcode_rule->first),
1428 i2target (options.hi_bit_nr, table->opcode_rule->last),
1429 table->opcode->nr_opcodes,
1430 table->nr_entries,
1431 nr_unique);
1432 }
1433 }
1434
1435 /* Check that the rule did more than re-arange the order of the
1436 instructions */
1437 {
1438 gen_entry *entry;
1439 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1440 {
1441 if (entry->combined_parent == NULL)
1442 {
1443 if (insn_list_cmp (table->insns, entry->insns) == 0)
1444 {
1445 print_gen_entry_path (table->opcode_rule->line, table, warning);
1446 warning (NULL, ": Applying rule just copied all instructions\n");
1447 print_gen_entry_insns (entry, warning, "Copied", NULL);
1448 error (NULL, "");
1449 }
1450 }
1451 }
1452 }
1453
1454 /* if some form of expanded table, fill in the missing dots */
1455 switch (table->opcode_rule->gen)
1456 {
1457 case padded_switch_gen:
1458 case array_gen:
1459 case goto_switch_gen:
1460 if (!table->opcode->is_boolean)
1461 {
1462 gen_entry **entry = &table->entries;
1463 gen_entry *illegals = NULL;
1464 gen_entry **last_illegal = &illegals;
1465 int opcode_nr = 0;
1466 while (opcode_nr < table->opcode->nr_opcodes)
1467 {
1468 if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr)
1469 {
1470 /* missing - insert it under our feet at *entry */
1471 gen_entry_insert_insn (table,
1472 table->top->isa->illegal_insn,
1473 table->opcode->word_nr,
1474 0, /* nr_prefetched_words == 0 for invalid */
1475 opcode_nr, NULL);
1476 ASSERT ((*entry) != NULL);
1477 ASSERT ((*entry)->opcode_nr == opcode_nr);
1478 (*last_illegal) = *entry;
1479 (*last_illegal)->combined_parent = illegals;
1480 last_illegal = &(*last_illegal)->combined_next;
1481 }
1482 entry = &(*entry)->sibling;
1483 opcode_nr++;
1484 }
1485 /* oops, will have pointed the first illegal insn back to
1486 its self. Fix this */
1487 if (illegals != NULL)
1488 illegals->combined_parent = NULL;
1489 }
1490 break;
1491 case switch_gen:
1492 case invalid_gen:
1493 /* ignore */
1494 break;
1495 }
1496
1497 /* and do the same for the newly created sub entries but *only*
1498 expand entries that haven't been combined. */
1499 {
1500 gen_entry *entry;
1501 for (entry = table->entries; entry != NULL; entry = entry->sibling)
1502 {
1503 if (entry->combined_parent == NULL)
1504 {
1505 gen_entry_expand_insns (entry);
1506 }
1507 }
1508 }
1509 }
1510
1511 void
1512 gen_tables_expand_insns (gen_table *gen)
1513 {
1514 gen_list *entry;
1515 for (entry = gen->tables; entry != NULL; entry = entry->next)
1516 {
1517 gen_entry_expand_insns (entry->table);
1518 }
1519 }
1520
1521
1522 /* create a list of all the semantic functions that need to be
1523 generated. Eliminate any duplicates. Verify that the decode stage
1524 worked. */
1525
1526 static void
1527 make_gen_semantics_list (lf *file,
1528 gen_entry *entry,
1529 int depth,
1530 void *data)
1531 {
1532 gen_table *gen = (gen_table*) data;
1533 insn_list *insn;
1534 /* Not interested in an entrie that have been combined into some
1535 other entry at the same level */
1536 if (entry->combined_parent != NULL)
1537 return;
1538
1539 /* a leaf should contain exactly one instruction. If not the decode
1540 stage failed. */
1541 ASSERT (entry->nr_insns == 1);
1542
1543 /* Enter this instruction into the list of semantic functions. */
1544 insn = insn_list_insert (&gen->semantics, &gen->nr_semantics,
1545 entry->insns->insn,
1546 entry->expanded_bits,
1547 entry->parent->opcode,
1548 entry->insns->nr_prefetched_words,
1549 merge_duplicate_insns);
1550 /* point the table entry at the real semantic function */
1551 ASSERT (insn != NULL);
1552 entry->insns->semantic = insn;
1553 }
1554
1555
1556 void
1557 gen_tables_expand_semantics (gen_table *gen)
1558 {
1559 gen_list *entry;
1560 for (entry = gen->tables; entry != NULL; entry = entry->next)
1561 {
1562 gen_entry_traverse_tree (NULL,
1563 entry->table,
1564 1, /* depth */
1565 NULL, /* start-handler */
1566 make_gen_semantics_list, /* leaf-handler */
1567 NULL, /* end-handler */
1568 gen); /* data */
1569 }
1570 }
1571
1572
1573
1574 #ifdef MAIN
1575
1576
1577 static void
1578 dump_opcode_field (lf *file,
1579 char *prefix,
1580 opcode_field *field,
1581 char *suffix,
1582 int levels)
1583 {
1584 lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field);
1585 if (levels && field != NULL) {
1586 lf_indent (file, +1);
1587 lf_printf (file, "\n(first %d)", field->first);
1588 lf_printf (file, "\n(last %d)", field->last);
1589 lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes);
1590 lf_printf (file, "\n(is_boolean %d)", field->is_boolean);
1591 lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant);
1592 dump_opcode_field(file, "\n(parent ", field->parent, ")", levels - 1);
1593 lf_indent (file, -1);
1594 }
1595 lf_printf (file, "%s", suffix);
1596 }
1597
1598
1599 static void
1600 dump_opcode_bits (lf *file,
1601 char *prefix,
1602 opcode_bits *bits,
1603 char *suffix,
1604 int levels)
1605 {
1606 lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits);
1607
1608 if (levels && bits != NULL)
1609 {
1610 lf_indent (file, +1);
1611 lf_printf (file, "\n(value %d)", bits->value);
1612 dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0);
1613 dump_insn_field (file, "\n(field ", bits->field, ")");
1614 dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1);
1615 lf_indent (file, -1);
1616 }
1617 lf_printf (file, "%s", suffix);
1618 }
1619
1620
1621
1622 static void
1623 dump_insn_list (lf *file,
1624 char *prefix,
1625 insn_list *entry,
1626 char *suffix)
1627 {
1628 lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry);
1629
1630 if (entry != NULL) {
1631 lf_indent (file, +1);
1632 dump_insn_entry (file, "\n(insn ", entry->insn, ")");
1633 lf_printf (file, "\n(next 0x%lx)", (long) entry->next);
1634 lf_indent (file, -1);
1635 }
1636 lf_printf (file, "%s", suffix);
1637 }
1638
1639
1640 static void
1641 dump_insn_word_entry_list_entries (lf *file,
1642 char *prefix,
1643 insn_list *entry,
1644 char *suffix)
1645 {
1646 lf_printf (file, "%s", prefix);
1647 while (entry != NULL)
1648 {
1649 dump_insn_list (file, "\n(", entry, ")");
1650 entry = entry->next;
1651 }
1652 lf_printf (file, "%s", suffix);
1653 }
1654
1655
1656 static void
1657 dump_gen_entry (lf *file,
1658 char *prefix,
1659 gen_entry *table,
1660 char *suffix,
1661 int levels)
1662 {
1663
1664 lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table);
1665
1666 if (levels && table != NULL) {
1667
1668 lf_indent (file, +1);
1669 lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr);
1670 lf_printf (file, "\n(word_nr %d)", table->word_nr);
1671 dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", -1);
1672 lf_printf (file, "\n(nr_insns %d)", table->nr_insns);
1673 dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, ")");
1674 dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")");
1675 dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0);
1676 lf_printf (file, "\n(nr_entries %d)", table->nr_entries);
1677 dump_gen_entry (file, "\n(entries ", table->entries, ")", table->nr_entries);
1678 dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1);
1679 dump_gen_entry (file, "\n(parent ", table->parent, ")", 0);
1680 lf_indent (file, -1);
1681 }
1682 lf_printf (file, "%s", suffix);
1683 }
1684
1685 static void
1686 dump_gen_list (lf *file,
1687 char *prefix,
1688 gen_list *entry,
1689 char *suffix,
1690 int levels)
1691 {
1692 while (entry != NULL)
1693 {
1694 lf_printf (file, "%s(gen_list *) 0x%lx", prefix, (long) entry);
1695 dump_gen_entry (file, "\n(", entry->table, ")", levels);
1696 lf_printf (file, "\n(next (gen_list *) 0x%lx)", (long) entry->next);
1697 lf_printf (file, "%s", suffix);
1698 }
1699 }
1700
1701
1702 static void
1703 dump_gen_table (lf *file,
1704 char *prefix,
1705 gen_table *gen,
1706 char *suffix,
1707 int levels)
1708 {
1709 lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen);
1710 lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa);
1711 lf_printf (file, "\n(rules (decode_table *) 0x%lx)", (long) gen->rules);
1712 dump_gen_list (file, "\n(", gen->tables, ")", levels);
1713 lf_printf (file, "%s", suffix);
1714 }
1715
1716
1717 igen_options options;
1718
1719 int
1720 main (int argc,
1721 char **argv)
1722 {
1723 decode_table *decode_rules;
1724 insn_table *instructions;
1725 gen_table *gen;
1726 lf *l;
1727
1728 if (argc != 7)
1729 error (NULL, "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
1730
1731 INIT_OPTIONS (options);
1732
1733 filter_parse (&options.flags_filter, argv[1]);
1734
1735 options.hi_bit_nr = a2i(argv[2]);
1736 options.insn_bit_size = a2i(argv[3]);
1737 options.insn_specifying_widths = a2i(argv[4]);
1738 ASSERT(options.hi_bit_nr < options.insn_bit_size);
1739
1740 instructions = load_insn_table (argv[6], NULL);
1741 decode_rules = load_decode_table (argv[5]);
1742 gen = make_gen_tables (instructions, decode_rules);
1743
1744 gen_tables_expand_insns (gen);
1745
1746 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
1747
1748 dump_gen_table (l, "(", gen, ")\n", -1);
1749 return 0;
1750 }
1751
1752 #endif