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