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