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