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