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