1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
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.
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.
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.
29 #include "ld-decode.h"
33 sub_val (insn_uint val
,
38 return ((val
>> (val_last_pos
- last_pos
))
39 & (((insn_uint
)1 << (last_pos
- first_pos
+ 1)) - 1));
43 update_depth (lf
*file
,
48 int *max_depth
= (int*)data
;
49 if (*max_depth
< depth
)
55 gen_entry_depth (gen_entry
*table
)
58 gen_entry_traverse_tree (NULL
,
70 print_gen_entry_path (line_ref
*line
,
74 if (table
->parent
== NULL
)
76 if (table
->top
->model
!= NULL
)
77 print (line
, "%s", table
->top
->model
->name
);
83 print_gen_entry_path (line
, table
->parent
, print
);
84 print (NULL
, ".%d", table
->opcode_nr
);
89 print_gen_entry_insns (gen_entry
*table
,
96 message
= first_message
;
97 for (i
= table
->insns
; i
!= NULL
; i
= i
->next
)
99 insn_entry
*insn
= i
->insn
;
100 print_gen_entry_path (insn
->line
, table
, print
);
101 print (NULL
, ": %s.%s %s\n",
105 if (next_message
!= NULL
)
106 message
= next_message
;
112 insn_field_cmp (insn_word_entry
*l
, insn_word_entry
*r
)
117 if (l
== NULL
&& r
== NULL
)
118 return 0; /* all previous fields the same */
120 return -1; /* left shorter than right */
122 return +1; /* left longer than right */
124 bit_nr
< options
.insn_bit_size
;
127 if (l
->bit
[bit_nr
]->field
->type
!= insn_field_string
)
129 if (r
->bit
[bit_nr
]->field
->type
!= insn_field_string
)
131 if (l
->bit
[bit_nr
]->field
->conditions
== NULL
)
133 if (r
->bit
[bit_nr
]->field
->conditions
== NULL
)
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
)
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 */
150 int cmp
= strcmp (l
->bit
[bit_nr
]->field
->conditions
->string
,
151 r
->bit
[bit_nr
]->field
->conditions
->string
);
157 if (l
->bit
[bit_nr
]->field
->conditions
->type
== insn_field_cond_field
)
159 if (r
->bit
[bit_nr
]->field
->conditions
->type
== insn_field_cond_field
)
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. */
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 */
180 insn_word_cmp (insn_word_entry
*l
, insn_word_entry
*r
)
185 if (l
== NULL
&& r
== NULL
)
186 return 0; /* all previous fields the same */
188 return -1; /* left shorter than right */
190 return +1; /* left longer than right */
192 bit_nr
< options
.insn_bit_size
;
195 if (l
->bit
[bit_nr
]->mask
< r
->bit
[bit_nr
]->mask
)
197 if (l
->bit
[bit_nr
]->mask
> r
->bit
[bit_nr
]->mask
)
199 if (l
->bit
[bit_nr
]->value
< r
->bit
[bit_nr
]->value
)
201 if (l
->bit
[bit_nr
]->value
> r
->bit
[bit_nr
]->value
)
211 opcode_bit_cmp (opcode_bits
*l
,
214 if (l
== NULL
&& r
== NULL
)
215 return 0; /* all previous bits the same */
217 return -1; /* left shorter than right */
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 */
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 */
236 if (l
->value
< r
->value
)
238 if (l
->value
> r
->value
)
246 opcode_bits_cmp (opcode_bits
*l
,
252 if (l
== NULL
&& r
== NULL
)
253 return 0; /* all previous bits the same */
254 cmp
= opcode_bit_cmp (l
, r
);
264 new_opcode_bits (opcode_bits
*old_bits
,
268 insn_field_entry
*field
,
269 opcode_field
*opcode
)
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
;
278 if (old_bits
!= NULL
)
280 opcode_bits
*new_list
;
281 opcode_bits
**last
= &new_list
;
282 new_list
= new_opcode_bits (old_bits
->next
,
288 while (*last
!= NULL
)
290 int cmp
= opcode_bit_cmp (new_bits
, *last
);
291 if (cmp
< 0) /* new < new_list */
297 ERROR ("Duplicated insn bits in list");
299 last
= &(*last
)->next
;
301 new_bits
->next
= *last
;
315 merge_duplicate_insns
,
316 report_duplicate_insns
,
317 } duplicate_insn_actions
;
320 insn_list_insert (insn_list
**cur_insn_ptr
,
323 opcode_bits
*expanded_bits
,
324 opcode_field
*opcodes
,
325 int nr_prefetched_words
,
326 duplicate_insn_actions duplicate_action
)
328 /* insert it according to the order of the fields & bits */
329 for (; (*cur_insn_ptr
) != NULL
; cur_insn_ptr
= &(*cur_insn_ptr
)->next
)
333 /* key#1 sort according to the constant fields of each instruction */
334 cmp
= insn_word_cmp (insn
->words
, (*cur_insn_ptr
)->insn
->words
);
340 /* key#2 sort according to the expanded bits of each instruction */
341 cmp
= opcode_bits_cmp (expanded_bits
, (*cur_insn_ptr
)->expanded_bits
);
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
);
354 /* duplicate keys, report problem */
355 switch (duplicate_action
)
357 case report_duplicate_insns
:
358 /* It would appear that we have two instructions with the
359 same constant field values across all words and bits.
360 This error can also occure when insn_field_cmp() is
361 failing to differentiate between two instructions that
362 differ only in their conditional fields. */
364 "Two instructions with identical constant fields\n");
365 error ((*cur_insn_ptr
)->insn
->line
,
366 "Location of duplicate instruction\n");
367 case merge_duplicate_insns
:
368 /* Add the opcode path to the instructions list */
371 insn_opcodes
**last
= &(*cur_insn_ptr
)->opcodes
;
372 while (*last
!= NULL
)
374 last
= &(*last
)->next
;
376 (*last
) = ZALLOC (insn_opcodes
);
377 (*last
)->opcode
= opcodes
;
379 /* Use the larger nr_prefetched_words */
380 if ((*cur_insn_ptr
)->nr_prefetched_words
< nr_prefetched_words
)
381 (*cur_insn_ptr
)->nr_prefetched_words
= nr_prefetched_words
;
382 return (*cur_insn_ptr
);
387 /* create a new list entry and insert it */
389 insn_list
*new_insn
= ZALLOC (insn_list
);
390 new_insn
->insn
= insn
;
391 new_insn
->expanded_bits
= expanded_bits
;
392 new_insn
->next
= (*cur_insn_ptr
);
393 new_insn
->nr_prefetched_words
= nr_prefetched_words
;
396 new_insn
->opcodes
= ZALLOC (insn_opcodes
);
397 new_insn
->opcodes
->opcode
= opcodes
;
399 (*cur_insn_ptr
) = new_insn
;
404 return (*cur_insn_ptr
);
409 gen_entry_traverse_tree (lf
*file
,
412 gen_entry_handler
*start
,
413 gen_entry_handler
*leaf
,
414 gen_entry_handler
*end
,
419 ASSERT (table
!= NULL
);
420 ASSERT (table
->opcode
!= NULL
);
421 ASSERT (table
->nr_entries
> 0);
422 ASSERT (table
->entries
!= 0);
425 if (start
!= NULL
&& depth
>= 0)
427 start (file
, table
, depth
, data
);
430 for (entry
= table
->entries
;
432 entry
= entry
->sibling
)
434 if (entry
->entries
!= NULL
&& depth
!= 0)
436 gen_entry_traverse_tree (file
, entry
, depth
+ 1,
437 start
, leaf
, end
, data
);
443 leaf (file
, entry
, depth
, data
);
448 if (end
!= NULL
&& depth
>= 0)
450 end (file
, table
, depth
, data
);
456 /* create a list element containing a single gen_table entry */
459 make_table (insn_table
*isa
,
464 gen_list
*entry
= ZALLOC (gen_list
);
465 entry
->table
= ZALLOC (gen_entry
);
466 entry
->table
->top
= entry
;
467 entry
->model
= model
;
469 for (insn
= isa
->insns
; insn
!= NULL
; insn
= insn
->next
)
472 || insn
->processors
== NULL
473 || filter_is_member (insn
->processors
, model
->name
))
475 insn_list_insert (&entry
->table
->insns
,
476 &entry
->table
->nr_insns
,
478 NULL
, /* expanded_bits - none yet */
479 NULL
, /* opcodes - none yet */
480 0, /* nr_prefetched_words - none yet */
481 report_duplicate_insns
);
484 entry
->table
->opcode_rule
= rules
;
490 make_gen_tables (insn_table
*isa
,
493 gen_table
*gen
= ZALLOC (gen_table
);
496 if (options
.gen
.multi_sim
)
498 gen_list
**last
= &gen
->tables
;
501 if (options
.model_filter
!= NULL
)
502 processors
= options
.model_filter
;
504 processors
= isa
->model
->processors
;
505 for (model
= isa
->model
->models
;
509 if (filter_is_member (processors
, model
->name
))
511 *last
= make_table (isa
, rules
, model
);
512 last
= &(*last
)->next
;
518 gen
->tables
= make_table (isa
, rules
, NULL
);
524 /****************************************************************/
528 field_is_not_constant
= 0,
529 field_constant_int
= 1,
530 field_constant_reserved
= 2,
531 field_constant_string
= 3
532 } constant_field_types
;
534 static constant_field_types
535 insn_field_is_constant (insn_field
*field
,
541 /* field is an integer */
542 return field_constant_int
;
543 case insn_field_reserved
:
544 /* field is `/' and treating that as a constant */
545 if (rule
->with_zero_reserved
)
546 return field_constant_reserved
;
548 return field_is_not_constant
;
549 case insn_field_wild
:
550 return field_is_not_constant
; /* never constant */
551 case insn_field_string
:
552 /* field, though variable, is on the list of forced constants */
553 if (filter_is_member (rule
->constant_field_names
, field
->val_string
))
554 return field_constant_string
;
556 return field_is_not_constant
;
558 ERROR ("Internal error");
559 return field_is_not_constant
;
564 /****************************************************************/
567 /* Is the bit, according to the decode rule, identical across all the
570 insns_bit_useless (insn_list
*insns
,
576 int is_useless
= 1; /* cleared if something actually found */
578 /* check the instructions for some constant value in at least one of
580 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
582 insn_word_entry
*word
= entry
->insn
->word
[rule
->word_nr
];
583 insn_bit_entry
*bit
= word
->bit
[bit_nr
];
584 switch (bit
->field
->type
)
586 case insn_field_invalid
:
589 case insn_field_wild
:
590 case insn_field_reserved
:
591 /* neither useless or useful - ignore */
594 switch (rule
->search
)
596 case decode_find_strings
:
597 /* an integer isn't a string */
599 case decode_find_constants
:
600 case decode_find_mixed
:
601 /* an integer is useful if its value isn't the same
602 between all instructions. The first time through the
603 value is saved, the second time through (if the
604 values differ) it is marked as useful. */
607 else if (value
!= bit
->value
)
612 case insn_field_string
:
613 switch (rule
->search
)
615 case decode_find_strings
:
616 /* at least one string, keep checking */
619 case decode_find_constants
:
620 case decode_find_mixed
:
621 if (filter_is_member (rule
->constant_field_names
,
622 bit
->field
->val_string
))
623 /* a string field forced to constant? */
625 else if (rule
->search
== decode_find_constants
)
626 /* the string field isn't constant */
633 /* Given only one constant value has been found, check through all
634 the instructions to see if at least one conditional makes it
636 if (value
>= 0 && is_useless
)
638 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
640 insn_word_entry
*word
= entry
->insn
->word
[rule
->word_nr
];
641 insn_bit_entry
*bit
= word
->bit
[bit_nr
];
642 switch (bit
->field
->type
)
644 case insn_field_invalid
:
647 case insn_field_wild
:
648 case insn_field_reserved
:
650 /* already processed */
652 case insn_field_string
:
653 switch (rule
->search
)
655 case decode_find_strings
:
656 case decode_find_constants
:
657 /* already processed */
659 case decode_find_mixed
:
660 /* string field with conditions. If this condition
661 eliminates the value then the compare is useful */
662 if (bit
->field
->conditions
!= NULL
)
664 insn_field_cond
*condition
;
665 int shift
= bit
->field
->last
- bit_nr
;
666 for (condition
= bit
->field
->conditions
;
668 condition
= condition
->next
)
670 switch (condition
->type
)
672 case insn_field_cond_value
:
673 switch (condition
->test
)
675 case insn_field_cond_ne
:
676 if (((condition
->value
>> shift
) & 1)
678 /* conditional field excludes the
682 case insn_field_cond_eq
:
683 if (((condition
->value
>> shift
) & 1)
685 /* conditional field requires the
691 case insn_field_cond_field
:
692 /* are these handled separatly? */
706 /* go through a gen-table's list of instruction formats looking for a
707 range of bits that meet the decode table RULEs requirements */
709 static opcode_field
*
710 gen_entry_find_opcode_field (insn_list
*insns
,
714 opcode_field curr_opcode
;
715 ASSERT (rule
!= NULL
);
717 memset (&curr_opcode
, 0, sizeof (curr_opcode
));
718 curr_opcode
.word_nr
= rule
->word_nr
;
719 curr_opcode
.first
= rule
->first
;
720 curr_opcode
.last
= rule
->last
;
722 /* Try to reduce the size of first..last in accordance with the
725 while (curr_opcode
.first
<= rule
->last
)
727 if (insns_bit_useless (insns
, rule
, curr_opcode
.first
))
728 curr_opcode
.first
++;
732 while (curr_opcode
.last
>= rule
->first
)
734 if (insns_bit_useless (insns
, rule
, curr_opcode
.last
))
742 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
744 insn_word_entry
*fields
= entry
->insn
->word
[rule
->word_nr
];
745 opcode_field new_opcode
;
747 ASSERT (fields
!= NULL
);
749 /* find a start point for the opcode field */
750 new_opcode
.first
= rule
->first
;
751 while (new_opcode
.first
<= rule
->last
753 || (insn_field_is_constant(fields
->bit
[new_opcode
.first
], rule
)
754 != field_constant_string
))
756 || (insn_field_is_constant(fields
->bit
[new_opcode
.first
], rule
)
757 == field_is_not_constant
)))
759 int new_first
= fields
->bit
[new_opcode
.first
]->last
+ 1;
760 ASSERT (new_first
> new_opcode
.first
);
761 new_opcode
.first
= new_first
;
763 ASSERT(new_opcode
.first
> rule
->last
765 && insn_field_is_constant(fields
->bit
[new_opcode
.first
],
766 rule
) == field_constant_string
)
768 && insn_field_is_constant(fields
->bit
[new_opcode
.first
],
771 /* find the end point for the opcode field */
772 new_opcode
.last
= rule
->last
;
773 while (new_opcode
.last
>= rule
->first
775 || insn_field_is_constant(fields
->bit
[new_opcode
.last
],
776 rule
) != field_constant_string
)
778 || !insn_field_is_constant(fields
->bit
[new_opcode
.last
],
781 int new_last
= fields
->bit
[new_opcode
.last
]->first
- 1;
782 ASSERT (new_last
< new_opcode
.last
);
783 new_opcode
.last
= new_last
;
785 ASSERT(new_opcode
.last
< rule
->first
787 && insn_field_is_constant(fields
->bit
[new_opcode
.last
],
788 rule
) == field_constant_string
)
790 && insn_field_is_constant(fields
->bit
[new_opcode
.last
],
793 /* now see if our current opcode needs expanding to include the
794 interesting fields within this instruction */
795 if (new_opcode
.first
<= rule
->last
796 && curr_opcode
.first
> new_opcode
.first
)
797 curr_opcode
.first
= new_opcode
.first
;
798 if (new_opcode
.last
>= rule
->first
799 && curr_opcode
.last
< new_opcode
.last
)
800 curr_opcode
.last
= new_opcode
.last
;
805 /* did the final opcode field end up being empty? */
806 if (curr_opcode
.first
> curr_opcode
.last
)
810 ASSERT (curr_opcode
.last
>= rule
->first
);
811 ASSERT (curr_opcode
.first
<= rule
->last
);
812 ASSERT (curr_opcode
.first
<= curr_opcode
.last
);
814 /* Ensure that, for the non string only case, the opcode includes
815 the range forced_first .. forced_last */
817 && curr_opcode
.first
> rule
->force_first
)
819 curr_opcode
.first
= rule
->force_first
;
822 && curr_opcode
.last
< rule
->force_last
)
824 curr_opcode
.last
= rule
->force_last
;
827 /* For the string only case, force just the lower bound (so that the
828 shift can be eliminated) */
830 && rule
->force_last
== options
.insn_bit_size
- 1)
832 curr_opcode
.last
= options
.insn_bit_size
- 1;
835 /* handle any special cases */
838 case normal_decode_rule
:
839 /* let the above apply */
840 curr_opcode
.nr_opcodes
=
841 (1 << (curr_opcode
.last
- curr_opcode
.first
+ 1));
844 curr_opcode
.is_boolean
= 1;
845 curr_opcode
.boolean_constant
= rule
->constant
;
846 curr_opcode
.nr_opcodes
= 2;
851 opcode_field
*new_field
= ZALLOC (opcode_field
);
852 memcpy (new_field
, &curr_opcode
, sizeof (opcode_field
));
859 gen_entry_insert_insn (gen_entry
*table
,
860 insn_entry
*old_insn
,
862 int new_nr_prefetched_words
,
864 opcode_bits
*new_bits
)
866 gen_entry
**entry
= &table
->entries
;
868 /* find the new table for this entry */
869 while ((*entry
) != NULL
&& (*entry
)->opcode_nr
< new_opcode_nr
)
871 entry
= &(*entry
)->sibling
;
874 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= new_opcode_nr
)
876 /* insert the missing entry */
877 gen_entry
*new_entry
= ZALLOC (gen_entry
);
878 new_entry
->sibling
= (*entry
);
879 (*entry
) = new_entry
;
882 new_entry
->top
= table
->top
;
883 new_entry
->opcode_nr
= new_opcode_nr
;
884 new_entry
->word_nr
= new_word_nr
;
885 new_entry
->expanded_bits
= new_bits
;
886 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
887 new_entry
->parent
= table
;
888 new_entry
->nr_prefetched_words
= new_nr_prefetched_words
;
890 /* ASSERT new_bits == cur_entry bits */
891 ASSERT ((*entry
) != NULL
&& (*entry
)->opcode_nr
== new_opcode_nr
);
892 insn_list_insert (&(*entry
)->insns
,
895 NULL
, /* expanded_bits - only in final list */
896 NULL
, /* opcodes - only in final list */
897 new_nr_prefetched_words
, /* for this table */
898 report_duplicate_insns
);
903 gen_entry_expand_opcode (gen_entry
*table
,
904 insn_entry
*instruction
,
909 if (bit_nr
> table
->opcode
->last
)
911 /* Only include the hardwired bit information with an entry IF
912 that entry (and hence its functions) are being duplicated. */
913 if (options
.trace
.insn_expansion
)
915 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
916 notify (NULL
, ": insert %d - %s.%s%s\n",
918 instruction
->format_name
,
920 (table
->opcode_rule
->with_duplicates
? " (duplicated)" : ""));
922 if (table
->opcode_rule
->with_duplicates
)
924 gen_entry_insert_insn (table
, instruction
,
925 table
->opcode
->word_nr
,
926 table
->nr_prefetched_words
,
931 gen_entry_insert_insn (table
, instruction
,
932 table
->opcode
->word_nr
,
933 table
->nr_prefetched_words
,
939 insn_word_entry
*word
= instruction
->word
[table
->opcode
->word_nr
];
940 insn_field_entry
*field
= word
->bit
[bit_nr
]->field
;
941 int last_pos
= ((field
->last
< table
->opcode
->last
)
943 : table
->opcode
->last
);
944 int first_pos
= ((field
->first
> table
->opcode
->first
)
946 : table
->opcode
->first
);
947 int width
= last_pos
- first_pos
+ 1;
953 val
= sub_val (field
->val_int
, field
->last
,
954 first_pos
, last_pos
);
955 gen_entry_expand_opcode (table
, instruction
,
957 ((opcode_nr
<< width
) | val
),
963 if (field
->type
== insn_field_reserved
)
964 gen_entry_expand_opcode (table
, instruction
,
966 ((opcode_nr
<< width
)),
971 int last_val
= (table
->opcode
->is_boolean
974 for (val
= 0; val
< last_val
; val
++)
976 /* check to see if the value has been precluded
977 (by a conditional) in some way */
979 insn_field_cond
*condition
;
980 for (condition
= field
->conditions
, is_precluded
= 0;
981 condition
!= NULL
&& !is_precluded
;
982 condition
= condition
->next
)
984 switch (condition
->type
)
986 case insn_field_cond_value
:
988 int value
= sub_val (condition
->value
, field
->last
,
989 first_pos
, last_pos
);
990 switch (condition
->test
)
992 case insn_field_cond_ne
:
996 case insn_field_cond_eq
:
1003 case insn_field_cond_field
:
1008 /* Try to find a value for the
1009 conditional by looking back through
1010 the previously defined bits for the
1011 specified conditional field */
1016 if (bit
->field
== condition
->field
1017 && (bit
->last
- bit
->first
+ 1 == condition
->field
->width
))
1019 /* the bit field fully specified
1020 the conditional field's value */
1021 value
= sub_val (bit
->value
, bit
->last
,
1022 first_pos
, last_pos
);
1026 /* Try to find a value by looking
1027 through this and previous tables */
1034 if (t
->parent
->opcode
->word_nr
!= condition
->field
->word_nr
)
1036 if (t
->parent
->opcode
->first
<= condition
->field
->first
1037 && t
->parent
->opcode
->last
>= condition
->field
->last
)
1039 /* the table entry fully
1040 specified the condition
1042 /* extract the field's value
1044 value
= sub_val (t
->opcode_nr
, t
->parent
->opcode
->last
,
1045 condition
->field
->first
, condition
->field
->last
);
1046 /* this is a requirement of
1048 refering to another field */
1049 ASSERT ((condition
->field
->first
- condition
->field
->last
)
1050 == (first_pos
- last_pos
));
1051 printf ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
1052 value
, t
->opcode_nr
, t
->parent
->opcode
->last
, condition
->field
->first
, condition
->field
->last
);
1056 if (bit
== NULL
&& t
== NULL
)
1057 error (instruction
->line
,
1058 "Conditional `%s' of field `%s' isn't expanded",
1059 condition
->string
, field
->val_string
);
1060 switch (condition
->test
)
1062 case insn_field_cond_ne
:
1066 case insn_field_cond_eq
:
1077 /* Only add additional hardwired bit
1078 information if the entry is not going to
1079 later be combined */
1080 if (table
->opcode_rule
->with_combine
)
1082 gen_entry_expand_opcode (table
, instruction
,
1084 ((opcode_nr
<< width
) | val
),
1089 opcode_bits
*new_bits
= new_opcode_bits (bits
, val
,
1090 first_pos
, last_pos
,
1093 gen_entry_expand_opcode (table
, instruction
,
1095 ((opcode_nr
<< width
) | val
),
1107 gen_entry_insert_expanding (gen_entry
*table
,
1108 insn_entry
*instruction
)
1110 gen_entry_expand_opcode (table
,
1112 table
->opcode
->first
,
1114 table
->expanded_bits
);
1119 insns_match_format_names (insn_list
*insns
,
1120 filter
*format_names
)
1122 if (format_names
!= NULL
)
1125 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1127 if ( i
->insn
->format_name
!= NULL
1128 && !filter_is_member (format_names
, i
->insn
->format_name
))
1136 table_matches_path (gen_entry
*table
,
1137 decode_path_list
*paths
)
1141 while (paths
!= NULL
)
1143 gen_entry
*entry
= table
;
1144 decode_path
*path
= paths
->path
;
1147 if (entry
== NULL
&& path
== NULL
)
1149 if (entry
== NULL
|| path
== NULL
)
1151 if (entry
->opcode_nr
!= path
->opcode_nr
)
1153 entry
= entry
->parent
;
1154 path
= path
->parent
;
1156 paths
= paths
->next
;
1163 insns_match_conditions (insn_list
*insns
,
1164 decode_cond
*conditions
)
1166 if (conditions
!= NULL
)
1169 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1172 for (cond
= conditions
; cond
!= NULL
; cond
= cond
->next
)
1175 if (i
->insn
->nr_words
<= cond
->word_nr
)
1177 for (bit_nr
= 0; bit_nr
< options
.insn_bit_size
; bit_nr
++)
1179 if (!cond
->mask
[bit_nr
])
1181 if (!i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->mask
)
1183 if ((i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->value
1184 == cond
->value
[bit_nr
])
1195 insns_match_nr_words (insn_list
*insns
,
1199 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1201 if (i
->insn
->nr_words
< nr_words
)
1208 insn_list_cmp (insn_list
*l
,
1214 if (l
== NULL
&& r
== NULL
)
1220 if (l
->insn
!= r
->insn
)
1221 return -1; /* somewhat arbitrary at present */
1222 /* skip this insn */
1224 while (l
!= NULL
&& l
->insn
== insn
)
1226 while (r
!= NULL
&& r
->insn
== insn
)
1234 gen_entry_expand_insns (gen_entry
*table
)
1236 decode_table
*opcode_rule
;
1238 ASSERT(table
->nr_insns
>= 1);
1240 /* determine a valid opcode */
1241 for (opcode_rule
= table
->opcode_rule
;
1242 opcode_rule
!= NULL
;
1243 opcode_rule
= opcode_rule
->next
)
1245 char *discard_reason
;
1246 if (table
->top
->model
!= NULL
1247 && opcode_rule
->model_names
!= NULL
1248 && !filter_is_member (opcode_rule
->model_names
,
1249 table
->top
->model
->name
))
1251 /* the rule isn't applicable to this processor */
1252 discard_reason
= "wrong model";
1254 else if (table
->nr_insns
== 1 && opcode_rule
->conditions
== NULL
)
1256 /* for safety, require a pre-codition when attempting to
1257 apply a rule to a single instruction */
1258 discard_reason
= "need pre-condition when nr-insn == 1";
1260 else if (table
->nr_insns
== 1 && !opcode_rule
->with_duplicates
)
1262 /* Little point in expanding a single instruction when we're
1263 not duplicating the semantic functions that this table
1265 discard_reason
= "need duplication with nr-insns == 1";
1267 else if (!insns_match_format_names (table
->insns
, opcode_rule
->format_names
))
1269 discard_reason
= "wrong format name";
1271 else if (!insns_match_nr_words (table
->insns
, opcode_rule
->word_nr
+ 1))
1273 discard_reason
= "wrong nr words";
1275 else if (!table_matches_path (table
, opcode_rule
->paths
))
1277 discard_reason
= "path failed";
1279 else if (!insns_match_conditions (table
->insns
, opcode_rule
->conditions
))
1281 discard_reason
= "condition failed";
1285 discard_reason
= "no opcode field";
1287 gen_entry_find_opcode_field (table
->insns
,
1289 table
->nr_insns
== 1/*string-only*/
1291 if (table
->opcode
!= NULL
)
1293 table
->opcode_rule
= opcode_rule
;
1298 if (options
.trace
.rule_rejection
)
1300 print_gen_entry_path (opcode_rule
->line
, table
, notify
);
1301 notify (NULL
, ": rule discarded - %s\n", discard_reason
);
1305 /* did we find anything */
1306 if (opcode_rule
== NULL
)
1308 /* the decode table failed, this set of instructions haven't
1309 been uniquely identified */
1310 if (table
->nr_insns
> 1)
1312 print_gen_entry_insns (table
, warning
,
1313 "was not uniquely decoded",
1314 "decodes to the same entry");
1320 /* Determine the number of words that must have been prefetched for
1321 this table to function */
1322 if (table
->parent
== NULL
)
1323 table
->nr_prefetched_words
= table
->opcode_rule
->word_nr
+ 1;
1324 else if (table
->opcode_rule
->word_nr
+ 1 > table
->parent
->nr_prefetched_words
)
1325 table
->nr_prefetched_words
= table
->opcode_rule
->word_nr
+ 1;
1327 table
->nr_prefetched_words
= table
->parent
->nr_prefetched_words
;
1329 /* back link what we found to its parent */
1330 if (table
->parent
!= NULL
)
1332 ASSERT(table
->parent
->opcode
!= NULL
);
1333 table
->opcode
->parent
= table
->parent
->opcode
;
1336 /* report the rule being used to expand the instructions */
1337 if (options
.trace
.rule_selection
)
1339 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1341 ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
1342 table
->opcode
->word_nr
,
1343 i2target (options
.hi_bit_nr
, table
->opcode
->first
),
1344 i2target (options
.hi_bit_nr
, table
->opcode
->last
),
1345 i2target (options
.hi_bit_nr
, table
->opcode_rule
->first
),
1346 i2target (options
.hi_bit_nr
, table
->opcode_rule
->last
),
1347 table
->opcode
->nr_opcodes
,
1351 /* expand the raw instructions according to the opcode */
1354 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
)
1356 if (options
.trace
.insn_expansion
)
1358 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1359 notify (NULL
, ": expand - %s.%s\n",
1360 entry
->insn
->format_name
,
1363 gen_entry_insert_expanding (table
, entry
->insn
);
1367 /* dump the results */
1368 if (options
.trace
.entries
)
1371 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1374 print_gen_entry_path (table
->opcode_rule
->line
, entry
, notify
);
1375 notify (NULL
, ": %d - entries %d -",
1378 for (l
= entry
->insns
; l
!= NULL
; l
= l
->next
)
1379 notify (NULL
, " %s.%s", l
->insn
->format_name
, l
->insn
->name
);
1380 notify (NULL
, "\n");
1384 /* perform a combine pass if needed */
1385 if (table
->opcode_rule
->with_combine
)
1388 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1390 if (entry
->combined_parent
== NULL
)
1392 gen_entry
**last
= &entry
->combined_next
;
1394 for (alt
= entry
->sibling
; alt
!= NULL
; alt
= alt
->sibling
)
1396 if (alt
->combined_parent
== NULL
1397 && insn_list_cmp (entry
->insns
, alt
->insns
) == 0)
1399 alt
->combined_parent
= entry
;
1401 last
= &alt
->combined_next
;
1406 if (options
.trace
.combine
)
1410 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1412 if (entry
->combined_parent
== NULL
)
1415 gen_entry
*duplicate
;
1417 print_gen_entry_path (table
->opcode_rule
->line
, entry
, notify
);
1418 for (duplicate
= entry
->combined_next
;
1420 duplicate
= duplicate
->combined_next
)
1422 notify (NULL
, "+%d", duplicate
->opcode_nr
);
1424 notify (NULL
, ": entries %d -", entry
->nr_insns
);
1425 for (l
= entry
->insns
; l
!= NULL
; l
= l
->next
)
1427 notify (NULL
, " %s.%s",
1428 l
->insn
->format_name
,
1431 notify (NULL
, "\n");
1434 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1435 notify (NULL
, ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
1436 table
->opcode
->word_nr
,
1437 i2target (options
.hi_bit_nr
, table
->opcode
->first
),
1438 i2target (options
.hi_bit_nr
, table
->opcode
->last
),
1439 i2target (options
.hi_bit_nr
, table
->opcode_rule
->first
),
1440 i2target (options
.hi_bit_nr
, table
->opcode_rule
->last
),
1441 table
->opcode
->nr_opcodes
,
1447 /* Check that the rule did more than re-arange the order of the
1451 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1453 if (entry
->combined_parent
== NULL
)
1455 if (insn_list_cmp (table
->insns
, entry
->insns
) == 0)
1457 print_gen_entry_path (table
->opcode_rule
->line
, table
, warning
);
1458 warning (NULL
, ": Applying rule just copied all instructions\n");
1459 print_gen_entry_insns (entry
, warning
, "Copied", NULL
);
1466 /* if some form of expanded table, fill in the missing dots */
1467 switch (table
->opcode_rule
->gen
)
1469 case padded_switch_gen
:
1471 case goto_switch_gen
:
1472 if (!table
->opcode
->is_boolean
)
1474 gen_entry
**entry
= &table
->entries
;
1475 gen_entry
*illegals
= NULL
;
1476 gen_entry
**last_illegal
= &illegals
;
1478 while (opcode_nr
< table
->opcode
->nr_opcodes
)
1480 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= opcode_nr
)
1482 /* missing - insert it under our feet at *entry */
1483 gen_entry_insert_insn (table
,
1484 table
->top
->isa
->illegal_insn
,
1485 table
->opcode
->word_nr
,
1486 0, /* nr_prefetched_words == 0 for invalid */
1488 ASSERT ((*entry
) != NULL
);
1489 ASSERT ((*entry
)->opcode_nr
== opcode_nr
);
1490 (*last_illegal
) = *entry
;
1491 (*last_illegal
)->combined_parent
= illegals
;
1492 last_illegal
= &(*last_illegal
)->combined_next
;
1494 entry
= &(*entry
)->sibling
;
1497 /* oops, will have pointed the first illegal insn back to
1498 its self. Fix this */
1499 if (illegals
!= NULL
)
1500 illegals
->combined_parent
= NULL
;
1509 /* and do the same for the newly created sub entries but *only*
1510 expand entries that haven't been combined. */
1513 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1515 if (entry
->combined_parent
== NULL
)
1517 gen_entry_expand_insns (entry
);
1524 gen_tables_expand_insns (gen_table
*gen
)
1527 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1529 gen_entry_expand_insns (entry
->table
);
1534 /* create a list of all the semantic functions that need to be
1535 generated. Eliminate any duplicates. Verify that the decode stage
1539 make_gen_semantics_list (lf
*file
,
1544 gen_table
*gen
= (gen_table
*) data
;
1546 /* Not interested in an entrie that have been combined into some
1547 other entry at the same level */
1548 if (entry
->combined_parent
!= NULL
)
1551 /* a leaf should contain exactly one instruction. If not the decode
1553 ASSERT (entry
->nr_insns
== 1);
1555 /* Enter this instruction into the list of semantic functions. */
1556 insn
= insn_list_insert (&gen
->semantics
, &gen
->nr_semantics
,
1558 entry
->expanded_bits
,
1559 entry
->parent
->opcode
,
1560 entry
->insns
->nr_prefetched_words
,
1561 merge_duplicate_insns
);
1562 /* point the table entry at the real semantic function */
1563 ASSERT (insn
!= NULL
);
1564 entry
->insns
->semantic
= insn
;
1569 gen_tables_expand_semantics (gen_table
*gen
)
1572 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1574 gen_entry_traverse_tree (NULL
,
1577 NULL
, /* start-handler */
1578 make_gen_semantics_list
, /* leaf-handler */
1579 NULL
, /* end-handler */
1590 dump_opcode_field (lf
*file
,
1592 opcode_field
*field
,
1596 lf_printf (file
, "%s(opcode_field *) 0x%lx", prefix
, (long) field
);
1597 if (levels
&& field
!= NULL
) {
1598 lf_indent (file
, +1);
1599 lf_printf (file
, "\n(first %d)", field
->first
);
1600 lf_printf (file
, "\n(last %d)", field
->last
);
1601 lf_printf (file
, "\n(nr_opcodes %d)", field
->nr_opcodes
);
1602 lf_printf (file
, "\n(is_boolean %d)", field
->is_boolean
);
1603 lf_printf (file
, "\n(boolean_constant %d)", field
->boolean_constant
);
1604 dump_opcode_field(file
, "\n(parent ", field
->parent
, ")", levels
- 1);
1605 lf_indent (file
, -1);
1607 lf_printf (file
, "%s", suffix
);
1612 dump_opcode_bits (lf
*file
,
1618 lf_printf (file
, "%s(opcode_bits *) 0x%lx", prefix
, (long) bits
);
1620 if (levels
&& bits
!= NULL
)
1622 lf_indent (file
, +1);
1623 lf_printf (file
, "\n(value %d)", bits
->value
);
1624 dump_opcode_field (file
, "\n(opcode ", bits
->opcode
, ")", 0);
1625 dump_insn_field (file
, "\n(field ", bits
->field
, ")");
1626 dump_opcode_bits (file
, "\n(next ", bits
->next
, ")", levels
- 1);
1627 lf_indent (file
, -1);
1629 lf_printf (file
, "%s", suffix
);
1635 dump_insn_list (lf
*file
,
1640 lf_printf (file
, "%s(insn_list *) 0x%lx", prefix
, (long) entry
);
1642 if (entry
!= NULL
) {
1643 lf_indent (file
, +1);
1644 dump_insn_entry (file
, "\n(insn ", entry
->insn
, ")");
1645 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1646 lf_indent (file
, -1);
1648 lf_printf (file
, "%s", suffix
);
1653 dump_insn_word_entry_list_entries (lf
*file
,
1658 lf_printf (file
, "%s", prefix
);
1659 while (entry
!= NULL
)
1661 dump_insn_list (file
, "\n(", entry
, ")");
1662 entry
= entry
->next
;
1664 lf_printf (file
, "%s", suffix
);
1669 dump_gen_entry (lf
*file
,
1676 lf_printf (file
, "%s(gen_entry *) 0x%lx", prefix
, (long) table
);
1678 if (levels
&& table
!= NULL
) {
1680 lf_indent (file
, +1);
1681 lf_printf (file
, "\n(opcode_nr %d)", table
->opcode_nr
);
1682 lf_printf (file
, "\n(word_nr %d)", table
->word_nr
);
1683 dump_opcode_bits (file
, "\n(expanded_bits ", table
->expanded_bits
, ")", -1);
1684 lf_printf (file
, "\n(nr_insns %d)", table
->nr_insns
);
1685 dump_insn_word_entry_list_entries (file
, "\n(insns ", table
->insns
, ")");
1686 dump_decode_rule (file
, "\n(opcode_rule ", table
->opcode_rule
, ")");
1687 dump_opcode_field (file
, "\n(opcode ", table
->opcode
, ")", 0);
1688 lf_printf (file
, "\n(nr_entries %d)", table
->nr_entries
);
1689 dump_gen_entry (file
, "\n(entries ", table
->entries
, ")", table
->nr_entries
);
1690 dump_gen_entry (file
, "\n(sibling ", table
->sibling
, ")", levels
- 1);
1691 dump_gen_entry (file
, "\n(parent ", table
->parent
, ")", 0);
1692 lf_indent (file
, -1);
1694 lf_printf (file
, "%s", suffix
);
1698 dump_gen_list (lf
*file
,
1704 while (entry
!= NULL
)
1706 lf_printf (file
, "%s(gen_list *) 0x%lx", prefix
, (long) entry
);
1707 dump_gen_entry (file
, "\n(", entry
->table
, ")", levels
);
1708 lf_printf (file
, "\n(next (gen_list *) 0x%lx)", (long) entry
->next
);
1709 lf_printf (file
, "%s", suffix
);
1715 dump_gen_table (lf
*file
,
1721 lf_printf (file
, "%s(gen_table *) 0x%lx", prefix
, (long) gen
);
1722 lf_printf (file
, "\n(isa (insn_table *) 0x%lx)", (long) gen
->isa
);
1723 lf_printf (file
, "\n(rules (decode_table *) 0x%lx)", (long) gen
->rules
);
1724 dump_gen_list (file
, "\n(", gen
->tables
, ")", levels
);
1725 lf_printf (file
, "%s", suffix
);
1729 igen_options options
;
1735 decode_table
*decode_rules
;
1736 insn_table
*instructions
;
1741 error (NULL
, "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
1743 INIT_OPTIONS (options
);
1745 filter_parse (&options
.flags_filter
, argv
[1]);
1747 options
.hi_bit_nr
= a2i(argv
[2]);
1748 options
.insn_bit_size
= a2i(argv
[3]);
1749 options
.insn_specifying_widths
= a2i(argv
[4]);
1750 ASSERT(options
.hi_bit_nr
< options
.insn_bit_size
);
1752 instructions
= load_insn_table (argv
[6], NULL
);
1753 decode_rules
= load_decode_table (argv
[5]);
1754 gen
= make_gen_tables (instructions
, decode_rules
);
1756 gen_tables_expand_insns (gen
);
1758 l
= lf_open ("-", "stdout", lf_omit_references
, lf_is_text
, "tmp-ld-insn");
1760 dump_gen_table (l
, "(", gen
, ")\n", -1);