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