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