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