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