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 /* two instructions with the same constant field
359 values across all words and bits */
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 */
368 insn_opcodes
**last
= &(*cur_insn_ptr
)->opcodes
;
369 while (*last
!= NULL
)
371 last
= &(*last
)->next
;
373 (*last
) = ZALLOC (insn_opcodes
);
374 (*last
)->opcode
= opcodes
;
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
);
384 /* create a new list entry and insert it */
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
;
393 new_insn
->opcodes
= ZALLOC (insn_opcodes
);
394 new_insn
->opcodes
->opcode
= opcodes
;
396 (*cur_insn_ptr
) = new_insn
;
401 return (*cur_insn_ptr
);
406 gen_entry_traverse_tree (lf
*file
,
409 gen_entry_handler
*start
,
410 gen_entry_handler
*leaf
,
411 gen_entry_handler
*end
,
416 ASSERT (table
!= NULL
);
417 ASSERT (table
->opcode
!= NULL
);
418 ASSERT (table
->nr_entries
> 0);
419 ASSERT (table
->entries
!= 0);
422 if (start
!= NULL
&& depth
>= 0)
424 start (file
, table
, depth
, data
);
427 for (entry
= table
->entries
;
429 entry
= entry
->sibling
)
431 if (entry
->entries
!= NULL
&& depth
!= 0)
433 gen_entry_traverse_tree (file
, entry
, depth
+ 1,
434 start
, leaf
, end
, data
);
440 leaf (file
, entry
, depth
, data
);
445 if (end
!= NULL
&& depth
>= 0)
447 end (file
, table
, depth
, data
);
453 /* create a list element containing a single gen_table entry */
456 make_table (insn_table
*isa
,
461 gen_list
*entry
= ZALLOC (gen_list
);
462 entry
->table
= ZALLOC (gen_entry
);
463 entry
->table
->top
= entry
;
464 entry
->model
= model
;
466 for (insn
= isa
->insns
; insn
!= NULL
; insn
= insn
->next
)
469 || insn
->processors
== NULL
470 || filter_is_member (insn
->processors
, model
->name
))
472 insn_list_insert (&entry
->table
->insns
,
473 &entry
->table
->nr_insns
,
475 NULL
, /* expanded_bits - none yet */
476 NULL
, /* opcodes - none yet */
477 0, /* nr_prefetched_words - none yet */
478 report_duplicate_insns
);
481 entry
->table
->opcode_rule
= rules
;
487 make_gen_tables (insn_table
*isa
,
490 gen_table
*gen
= ZALLOC (gen_table
);
493 if (options
.gen
.multi_sim
)
495 gen_list
**last
= &gen
->tables
;
498 if (options
.model_filter
!= NULL
)
499 processors
= options
.model_filter
;
501 processors
= isa
->model
->processors
;
502 for (model
= isa
->model
->models
;
506 if (filter_is_member (processors
, model
->name
))
508 *last
= make_table (isa
, rules
, model
);
509 last
= &(*last
)->next
;
515 gen
->tables
= make_table (isa
, rules
, NULL
);
521 /****************************************************************/
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
;
531 static constant_field_types
532 insn_field_is_constant (insn_field
*field
,
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
;
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
;
553 return field_is_not_constant
;
555 ERROR ("Internal error");
556 return field_is_not_constant
;
561 /****************************************************************/
564 /* Is the bit, according to the decode rule, identical across all the
567 insns_bit_useless (insn_list
*insns
,
573 int is_useless
= 1; /* cleared if something actually found */
575 /* check the instructions for some constant value in at least one of
577 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
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
)
583 case insn_field_invalid
:
586 case insn_field_wild
:
587 case insn_field_reserved
:
588 /* neither useless or useful - ignore */
591 switch (rule
->search
)
593 case decode_find_strings
:
594 /* an integer isn't a string */
596 case decode_find_constants
:
597 case decode_find_mixed
:
598 /* an integer is useful if its value isn't the same
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. */
604 else if (value
!= bit
->value
)
609 case insn_field_string
:
610 switch (rule
->search
)
612 case decode_find_strings
:
613 /* at least one string, keep checking */
616 case decode_find_constants
:
617 case decode_find_mixed
:
618 if (filter_is_member (rule
->constant_field_names
,
619 bit
->field
->val_string
))
620 /* a string field forced to constant? */
622 else if (rule
->search
== decode_find_constants
)
623 /* the string field isn't constant */
630 /* Given only one constant value has been found, check through all
631 the instructions to see if at least one conditional makes it
633 if (value
>= 0 && is_useless
)
635 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
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
)
641 case insn_field_invalid
:
644 case insn_field_wild
:
645 case insn_field_reserved
:
647 /* already processed */
649 case insn_field_string
:
650 switch (rule
->search
)
652 case decode_find_strings
:
653 case decode_find_constants
:
654 /* already processed */
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
)
661 insn_field_cond
*condition
;
662 int shift
= bit
->field
->last
- bit_nr
;
663 for (condition
= bit
->field
->conditions
;
665 condition
= condition
->next
)
667 switch (condition
->type
)
669 case insn_field_cond_value
:
670 switch (condition
->test
)
672 case insn_field_cond_ne
:
673 if (((condition
->value
>> shift
) & 1)
675 /* conditional field excludes the
679 case insn_field_cond_eq
:
680 if (((condition
->value
>> shift
) & 1)
682 /* conditional field requires the
688 case insn_field_cond_field
:
689 /* are these handled separatly? */
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 */
706 static opcode_field
*
707 gen_entry_find_opcode_field (insn_list
*insns
,
711 opcode_field curr_opcode
;
712 ASSERT (rule
!= NULL
);
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
;
719 /* Try to reduce the size of first..last in accordance with the
722 while (curr_opcode
.first
<= rule
->last
)
724 if (insns_bit_useless (insns
, rule
, curr_opcode
.first
))
725 curr_opcode
.first
++;
729 while (curr_opcode
.last
>= rule
->first
)
731 if (insns_bit_useless (insns
, rule
, curr_opcode
.last
))
739 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
741 insn_word_entry
*fields
= entry
->insn
->word
[rule
->word_nr
];
742 opcode_field new_opcode
;
744 ASSERT (fields
!= NULL
);
746 /* find a start point for the opcode field */
747 new_opcode
.first
= rule
->first
;
748 while (new_opcode
.first
<= rule
->last
750 || (insn_field_is_constant(fields
->bit
[new_opcode
.first
], rule
)
751 != field_constant_string
))
753 || (insn_field_is_constant(fields
->bit
[new_opcode
.first
], rule
)
754 == field_is_not_constant
)))
756 int new_first
= fields
->bit
[new_opcode
.first
]->last
+ 1;
757 ASSERT (new_first
> new_opcode
.first
);
758 new_opcode
.first
= new_first
;
760 ASSERT(new_opcode
.first
> rule
->last
762 && insn_field_is_constant(fields
->bit
[new_opcode
.first
],
763 rule
) == field_constant_string
)
765 && insn_field_is_constant(fields
->bit
[new_opcode
.first
],
768 /* find the end point for the opcode field */
769 new_opcode
.last
= rule
->last
;
770 while (new_opcode
.last
>= rule
->first
772 || insn_field_is_constant(fields
->bit
[new_opcode
.last
],
773 rule
) != field_constant_string
)
775 || !insn_field_is_constant(fields
->bit
[new_opcode
.last
],
778 int new_last
= fields
->bit
[new_opcode
.last
]->first
- 1;
779 ASSERT (new_last
< new_opcode
.last
);
780 new_opcode
.last
= new_last
;
782 ASSERT(new_opcode
.last
< rule
->first
784 && insn_field_is_constant(fields
->bit
[new_opcode
.last
],
785 rule
) == field_constant_string
)
787 && insn_field_is_constant(fields
->bit
[new_opcode
.last
],
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
;
802 /* did the final opcode field end up being empty? */
803 if (curr_opcode
.first
> curr_opcode
.last
)
807 ASSERT (curr_opcode
.last
>= rule
->first
);
808 ASSERT (curr_opcode
.first
<= rule
->last
);
809 ASSERT (curr_opcode
.first
<= curr_opcode
.last
);
811 /* Ensure that, for the non string only case, the opcode includes
812 the range forced_first .. forced_last */
814 && curr_opcode
.first
> rule
->force_first
)
816 curr_opcode
.first
= rule
->force_first
;
819 && curr_opcode
.last
< rule
->force_last
)
821 curr_opcode
.last
= rule
->force_last
;
824 /* For the string only case, force just the lower bound (so that the
825 shift can be eliminated) */
827 && rule
->force_last
== options
.insn_bit_size
- 1)
829 curr_opcode
.last
= options
.insn_bit_size
- 1;
832 /* handle any special cases */
835 case normal_decode_rule
:
836 /* let the above apply */
837 curr_opcode
.nr_opcodes
=
838 (1 << (curr_opcode
.last
- curr_opcode
.first
+ 1));
841 curr_opcode
.is_boolean
= 1;
842 curr_opcode
.boolean_constant
= rule
->constant
;
843 curr_opcode
.nr_opcodes
= 2;
848 opcode_field
*new_field
= ZALLOC (opcode_field
);
849 memcpy (new_field
, &curr_opcode
, sizeof (opcode_field
));
856 gen_entry_insert_insn (gen_entry
*table
,
857 insn_entry
*old_insn
,
859 int new_nr_prefetched_words
,
861 opcode_bits
*new_bits
)
863 gen_entry
**entry
= &table
->entries
;
865 /* find the new table for this entry */
866 while ((*entry
) != NULL
&& (*entry
)->opcode_nr
< new_opcode_nr
)
868 entry
= &(*entry
)->sibling
;
871 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= new_opcode_nr
)
873 /* insert the missing entry */
874 gen_entry
*new_entry
= ZALLOC (gen_entry
);
875 new_entry
->sibling
= (*entry
);
876 (*entry
) = new_entry
;
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
;
887 /* ASSERT new_bits == cur_entry bits */
888 ASSERT ((*entry
) != NULL
&& (*entry
)->opcode_nr
== new_opcode_nr
);
889 insn_list_insert (&(*entry
)->insns
,
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
);
900 gen_entry_expand_opcode (gen_entry
*table
,
901 insn_entry
*instruction
,
906 if (bit_nr
> table
->opcode
->last
)
908 /* Only include the hardwired bit information with an entry IF
909 that entry (and hence its functions) are being duplicated. */
910 if (options
.trace
.insn_expansion
)
912 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
913 notify (NULL
, ": insert %d - %s.%s%s\n",
915 instruction
->format_name
,
917 (table
->opcode_rule
->with_duplicates
? " (duplicated)" : ""));
919 if (table
->opcode_rule
->with_duplicates
)
921 gen_entry_insert_insn (table
, instruction
,
922 table
->opcode
->word_nr
,
923 table
->nr_prefetched_words
,
928 gen_entry_insert_insn (table
, instruction
,
929 table
->opcode
->word_nr
,
930 table
->nr_prefetched_words
,
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
)
940 : table
->opcode
->last
);
941 int first_pos
= ((field
->first
> table
->opcode
->first
)
943 : table
->opcode
->first
);
944 int width
= last_pos
- first_pos
+ 1;
950 val
= sub_val (field
->val_int
, field
->last
,
951 first_pos
, last_pos
);
952 gen_entry_expand_opcode (table
, instruction
,
954 ((opcode_nr
<< width
) | val
),
960 if (field
->type
== insn_field_reserved
)
961 gen_entry_expand_opcode (table
, instruction
,
963 ((opcode_nr
<< width
)),
968 int last_val
= (table
->opcode
->is_boolean
971 for (val
= 0; val
< last_val
; val
++)
973 /* check to see if the value has been precluded
974 (by a conditional) in some way */
976 insn_field_cond
*condition
;
977 for (condition
= field
->conditions
, is_precluded
= 0;
978 condition
!= NULL
&& !is_precluded
;
979 condition
= condition
->next
)
981 switch (condition
->type
)
983 case insn_field_cond_value
:
985 int value
= sub_val (condition
->value
, field
->last
,
986 first_pos
, last_pos
);
987 switch (condition
->test
)
989 case insn_field_cond_ne
:
993 case insn_field_cond_eq
:
1000 case insn_field_cond_field
:
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 */
1013 if (bit
->field
== condition
->field
1014 && (bit
->last
- bit
->first
+ 1 == condition
->field
->width
))
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
);
1023 /* Try to find a value by looking
1024 through this and previous tables */
1031 if (t
->parent
->opcode
->word_nr
!= condition
->field
->word_nr
)
1033 if (t
->parent
->opcode
->first
<= condition
->field
->first
1034 && t
->parent
->opcode
->last
>= condition
->field
->last
)
1036 /* the table entry fully
1037 specified the condition
1039 value
= sub_val (t
->opcode_nr
, t
->parent
->opcode
->last
,
1040 first_pos
, last_pos
);
1044 if (bit
== NULL
&& t
== NULL
)
1045 error (instruction
->line
,
1046 "Conditional `%s' of field `%s' isn't expanded",
1047 condition
->string
, field
->val_string
);
1048 switch (condition
->test
)
1050 case insn_field_cond_ne
:
1054 case insn_field_cond_eq
:
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
)
1070 gen_entry_expand_opcode (table
, instruction
,
1072 ((opcode_nr
<< width
) | val
),
1077 opcode_bits
*new_bits
= new_opcode_bits (bits
, val
,
1078 first_pos
, last_pos
,
1081 gen_entry_expand_opcode (table
, instruction
,
1083 ((opcode_nr
<< width
) | val
),
1095 gen_entry_insert_expanding (gen_entry
*table
,
1096 insn_entry
*instruction
)
1098 gen_entry_expand_opcode (table
,
1100 table
->opcode
->first
,
1102 table
->expanded_bits
);
1107 insns_match_format_names (insn_list
*insns
,
1108 filter
*format_names
)
1110 if (format_names
!= NULL
)
1113 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1115 if ( i
->insn
->format_name
!= NULL
1116 && !filter_is_member (format_names
, i
->insn
->format_name
))
1124 table_matches_path (gen_entry
*table
,
1125 decode_path_list
*paths
)
1129 while (paths
!= NULL
)
1131 gen_entry
*entry
= table
;
1132 decode_path
*path
= paths
->path
;
1135 if (entry
== NULL
&& path
== NULL
)
1137 if (entry
== NULL
|| path
== NULL
)
1139 if (entry
->opcode_nr
!= path
->opcode_nr
)
1141 entry
= entry
->parent
;
1142 path
= path
->parent
;
1144 paths
= paths
->next
;
1151 insns_match_conditions (insn_list
*insns
,
1152 decode_cond
*conditions
)
1154 if (conditions
!= NULL
)
1157 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1160 for (cond
= conditions
; cond
!= NULL
; cond
= cond
->next
)
1163 if (i
->insn
->nr_words
<= cond
->word_nr
)
1165 for (bit_nr
= 0; bit_nr
< options
.insn_bit_size
; bit_nr
++)
1167 if (!cond
->mask
[bit_nr
])
1169 if (!i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->mask
)
1171 if ((i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->value
1172 == cond
->value
[bit_nr
])
1183 insns_match_nr_words (insn_list
*insns
,
1187 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1189 if (i
->insn
->nr_words
< nr_words
)
1196 insn_list_cmp (insn_list
*l
,
1202 if (l
== NULL
&& r
== NULL
)
1208 if (l
->insn
!= r
->insn
)
1209 return -1; /* somewhat arbitrary at present */
1210 /* skip this insn */
1212 while (l
!= NULL
&& l
->insn
== insn
)
1214 while (r
!= NULL
&& r
->insn
== insn
)
1222 gen_entry_expand_insns (gen_entry
*table
)
1224 decode_table
*opcode_rule
;
1226 ASSERT(table
->nr_insns
>= 1);
1228 /* determine a valid opcode */
1229 for (opcode_rule
= table
->opcode_rule
;
1230 opcode_rule
!= NULL
;
1231 opcode_rule
= opcode_rule
->next
)
1233 char *discard_reason
;
1234 if (table
->top
->model
!= NULL
1235 && opcode_rule
->model_names
!= NULL
1236 && !filter_is_member (opcode_rule
->model_names
,
1237 table
->top
->model
->name
))
1239 /* the rule isn't applicable to this processor */
1240 discard_reason
= "wrong model";
1242 else if (table
->nr_insns
== 1 && opcode_rule
->conditions
== NULL
)
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";
1248 else if (table
->nr_insns
== 1 && !opcode_rule
->with_duplicates
)
1250 /* Little point in expanding a single instruction when we're
1251 not duplicating the semantic functions that this table
1253 discard_reason
= "need duplication with nr-insns == 1";
1255 else if (!insns_match_format_names (table
->insns
, opcode_rule
->format_names
))
1257 discard_reason
= "wrong format name";
1259 else if (!insns_match_nr_words (table
->insns
, opcode_rule
->word_nr
+ 1))
1261 discard_reason
= "wrong nr words";
1263 else if (!table_matches_path (table
, opcode_rule
->paths
))
1265 discard_reason
= "path failed";
1267 else if (!insns_match_conditions (table
->insns
, opcode_rule
->conditions
))
1269 discard_reason
= "condition failed";
1273 discard_reason
= "no opcode field";
1275 gen_entry_find_opcode_field (table
->insns
,
1277 table
->nr_insns
== 1/*string-only*/
1279 if (table
->opcode
!= NULL
)
1281 table
->opcode_rule
= opcode_rule
;
1286 if (options
.trace
.rule_rejection
)
1288 print_gen_entry_path (opcode_rule
->line
, table
, notify
);
1289 notify (NULL
, ": rule discarded - %s\n", discard_reason
);
1293 /* did we find anything */
1294 if (opcode_rule
== NULL
)
1296 /* the decode table failed, this set of instructions haven't
1297 been uniquely identified */
1298 if (table
->nr_insns
> 1)
1300 print_gen_entry_insns (table
, warning
,
1301 "was not uniquely decoded",
1302 "decodes to the same entry");
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;
1315 table
->nr_prefetched_words
= table
->parent
->nr_prefetched_words
;
1317 /* back link what we found to its parent */
1318 if (table
->parent
!= NULL
)
1320 ASSERT(table
->parent
->opcode
!= NULL
);
1321 table
->opcode
->parent
= table
->parent
->opcode
;
1324 /* report the rule being used to expand the instructions */
1325 if (options
.trace
.rule_selection
)
1327 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
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
,
1339 /* expand the raw instructions according to the opcode */
1342 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
)
1344 if (options
.trace
.insn_expansion
)
1346 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1347 notify (NULL
, ": expand - %s.%s\n",
1348 entry
->insn
->format_name
,
1351 gen_entry_insert_expanding (table
, entry
->insn
);
1355 /* dump the results */
1356 if (options
.trace
.entries
)
1359 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1362 print_gen_entry_path (table
->opcode_rule
->line
, entry
, notify
);
1363 notify (NULL
, ": %d - entries %d -",
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");
1372 /* perform a combine pass if needed */
1373 if (table
->opcode_rule
->with_combine
)
1376 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1378 if (entry
->combined_parent
== NULL
)
1380 gen_entry
**last
= &entry
->combined_next
;
1382 for (alt
= entry
->sibling
; alt
!= NULL
; alt
= alt
->sibling
)
1384 if (alt
->combined_parent
== NULL
1385 && insn_list_cmp (entry
->insns
, alt
->insns
) == 0)
1387 alt
->combined_parent
= entry
;
1389 last
= &alt
->combined_next
;
1394 if (options
.trace
.combine
)
1398 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1400 if (entry
->combined_parent
== NULL
)
1403 gen_entry
*duplicate
;
1405 print_gen_entry_path (table
->opcode_rule
->line
, entry
, notify
);
1406 for (duplicate
= entry
->combined_next
;
1408 duplicate
= duplicate
->combined_next
)
1410 notify (NULL
, "+%d", duplicate
->opcode_nr
);
1412 notify (NULL
, ": entries %d -", entry
->nr_insns
);
1413 for (l
= entry
->insns
; l
!= NULL
; l
= l
->next
)
1415 notify (NULL
, " %s.%s",
1416 l
->insn
->format_name
,
1419 notify (NULL
, "\n");
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
,
1435 /* Check that the rule did more than re-arange the order of the
1439 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1441 if (entry
->combined_parent
== NULL
)
1443 if (insn_list_cmp (table
->insns
, entry
->insns
) == 0)
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
);
1454 /* if some form of expanded table, fill in the missing dots */
1455 switch (table
->opcode_rule
->gen
)
1457 case padded_switch_gen
:
1459 case goto_switch_gen
:
1460 if (!table
->opcode
->is_boolean
)
1462 gen_entry
**entry
= &table
->entries
;
1463 gen_entry
*illegals
= NULL
;
1464 gen_entry
**last_illegal
= &illegals
;
1466 while (opcode_nr
< table
->opcode
->nr_opcodes
)
1468 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= opcode_nr
)
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 */
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
;
1482 entry
= &(*entry
)->sibling
;
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
;
1497 /* and do the same for the newly created sub entries but *only*
1498 expand entries that haven't been combined. */
1501 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1503 if (entry
->combined_parent
== NULL
)
1505 gen_entry_expand_insns (entry
);
1512 gen_tables_expand_insns (gen_table
*gen
)
1515 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1517 gen_entry_expand_insns (entry
->table
);
1522 /* create a list of all the semantic functions that need to be
1523 generated. Eliminate any duplicates. Verify that the decode stage
1527 make_gen_semantics_list (lf
*file
,
1532 gen_table
*gen
= (gen_table
*) data
;
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
)
1539 /* a leaf should contain exactly one instruction. If not the decode
1541 ASSERT (entry
->nr_insns
== 1);
1543 /* Enter this instruction into the list of semantic functions. */
1544 insn
= insn_list_insert (&gen
->semantics
, &gen
->nr_semantics
,
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
;
1557 gen_tables_expand_semantics (gen_table
*gen
)
1560 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1562 gen_entry_traverse_tree (NULL
,
1565 NULL
, /* start-handler */
1566 make_gen_semantics_list
, /* leaf-handler */
1567 NULL
, /* end-handler */
1578 dump_opcode_field (lf
*file
,
1580 opcode_field
*field
,
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);
1595 lf_printf (file
, "%s", suffix
);
1600 dump_opcode_bits (lf
*file
,
1606 lf_printf (file
, "%s(opcode_bits *) 0x%lx", prefix
, (long) bits
);
1608 if (levels
&& bits
!= NULL
)
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);
1617 lf_printf (file
, "%s", suffix
);
1623 dump_insn_list (lf
*file
,
1628 lf_printf (file
, "%s(insn_list *) 0x%lx", prefix
, (long) entry
);
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);
1636 lf_printf (file
, "%s", suffix
);
1641 dump_insn_word_entry_list_entries (lf
*file
,
1646 lf_printf (file
, "%s", prefix
);
1647 while (entry
!= NULL
)
1649 dump_insn_list (file
, "\n(", entry
, ")");
1650 entry
= entry
->next
;
1652 lf_printf (file
, "%s", suffix
);
1657 dump_gen_entry (lf
*file
,
1664 lf_printf (file
, "%s(gen_entry *) 0x%lx", prefix
, (long) table
);
1666 if (levels
&& table
!= NULL
) {
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);
1682 lf_printf (file
, "%s", suffix
);
1686 dump_gen_list (lf
*file
,
1692 while (entry
!= NULL
)
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
);
1703 dump_gen_table (lf
*file
,
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
);
1717 igen_options options
;
1723 decode_table
*decode_rules
;
1724 insn_table
*instructions
;
1729 error (NULL
, "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
1731 INIT_OPTIONS (options
);
1733 filter_parse (&options
.flags_filter
, argv
[1]);
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
);
1740 instructions
= load_insn_table (argv
[6], NULL
);
1741 decode_rules
= load_decode_table (argv
[5]);
1742 gen
= make_gen_tables (instructions
, decode_rules
);
1744 gen_tables_expand_insns (gen
);
1746 l
= lf_open ("-", "stdout", lf_omit_references
, lf_is_text
, "tmp-ld-insn");
1748 dump_gen_table (l
, "(", gen
, ")\n", -1);