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