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