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
,
34 insn_field_entry
*field
,
38 return ((val
>> (field
->last
- 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
;
113 insn_word_cmp (insn_word_entry
*l
, insn_word_entry
*r
)
118 if (l
== NULL
&& r
== NULL
)
119 return 0; /* all previous fields the same */
121 return -1; /* left shorter than right */
123 return +1; /* left longer than right */
125 bit_nr
< options
.insn_bit_size
;
128 if (l
->bit
[bit_nr
]->mask
< r
->bit
[bit_nr
]->mask
)
130 if (l
->bit
[bit_nr
]->mask
> r
->bit
[bit_nr
]->mask
)
132 if (l
->bit
[bit_nr
]->value
< r
->bit
[bit_nr
]->value
)
134 if (l
->bit
[bit_nr
]->value
> r
->bit
[bit_nr
]->value
)
143 opcode_bit_cmp (opcode_bits
*l
,
146 if (l
== NULL
&& r
== NULL
)
147 return 0; /* all previous bits the same */
149 return -1; /* left shorter than right */
151 return +1; /* left longer than right */
152 /* most significant word */
153 if (l
->field
->word_nr
< r
->field
->word_nr
)
154 return +1; /* left has more significant word */
155 if (l
->field
->word_nr
> r
->field
->word_nr
)
156 return -1; /* right has more significant word */
157 /* most significant bit? */
158 if (l
->first
< r
->first
)
159 return +1; /* left as more significant bit */
160 if (l
->first
> r
->first
)
161 return -1; /* right as more significant bit */
163 if (l
->last
< r
->last
)
164 return +1; /* left as less bits */
165 if (l
->last
> r
->last
)
166 return -1; /* right as less bits */
168 if (l
->value
< r
->value
)
170 if (l
->value
> r
->value
)
176 opcode_bits_cmp (opcode_bits
*l
,
182 if (l
== NULL
&& r
== NULL
)
183 return 0; /* all previous bits the same */
184 cmp
= opcode_bit_cmp (l
, r
);
193 new_opcode_bits (opcode_bits
*old_bits
,
197 insn_field_entry
*field
,
198 opcode_field
*opcode
)
200 opcode_bits
*new_bits
= ZALLOC (opcode_bits
);
201 new_bits
->field
= field
;
202 new_bits
->value
= value
;
203 new_bits
->first
= first
;
204 new_bits
->last
= last
;
205 new_bits
->opcode
= opcode
;
207 if (old_bits
!= NULL
)
209 opcode_bits
*new_list
;
210 opcode_bits
**last
= &new_list
;
211 new_list
= new_opcode_bits (old_bits
->next
,
217 while (*last
!= NULL
)
219 int cmp
= opcode_bit_cmp (new_bits
, *last
);
220 if (cmp
< 0) /* new < new_list */
226 ERROR ("Duplicated insn bits in list");
228 last
= &(*last
)->next
;
230 new_bits
->next
= *last
;
244 merge_duplicate_insns
,
245 report_duplicate_insns
,
246 } duplicate_insn_actions
;
249 insn_list_insert (insn_list
**cur_insn_ptr
,
252 opcode_bits
*expanded_bits
,
253 opcode_field
*opcodes
,
254 int nr_prefetched_words
,
255 duplicate_insn_actions duplicate_action
)
257 /* insert it according to the order of the fields & bits */
258 while ((*cur_insn_ptr
) != NULL
)
260 int word_cmp
= insn_word_cmp (insn
->words
,
261 (*cur_insn_ptr
)->insn
->words
);
264 /* found insertion point - new_insn < cur_insn->next */
267 else if (word_cmp
== 0)
269 /* words same, try for bit fields */
270 int bit_cmp
= opcode_bits_cmp (expanded_bits
,
271 (*cur_insn_ptr
)->expanded_bits
);
274 /* found insertion point - new_insn < cur_insn->next */
277 else if (bit_cmp
== 0)
279 switch (duplicate_action
)
281 case report_duplicate_insns
:
282 /* two instructions with the same constant field
283 values across all words and bits */
285 "Two instructions with identical constant fields\n");
286 error ((*cur_insn_ptr
)->insn
->line
,
287 "Location of second (duplicated?) instruction\n");
288 case merge_duplicate_insns
:
289 /* Add the opcode path to the instructions list */
292 insn_opcodes
**last
= &(*cur_insn_ptr
)->opcodes
;
293 while (*last
!= NULL
)
295 last
= &(*last
)->next
;
297 (*last
) = ZALLOC (insn_opcodes
);
298 (*last
)->opcode
= opcodes
;
300 /* Use the larger nr_prefetched_words */
301 if ((*cur_insn_ptr
)->nr_prefetched_words
< nr_prefetched_words
)
302 (*cur_insn_ptr
)->nr_prefetched_words
= nr_prefetched_words
;
303 return (*cur_insn_ptr
);
307 /* keep looking - new_insn > cur_insn->next */
308 cur_insn_ptr
= &(*cur_insn_ptr
)->next
;
311 /* create a new list entry and insert it */
313 insn_list
*new_insn
= ZALLOC (insn_list
);
314 new_insn
->insn
= insn
;
315 new_insn
->expanded_bits
= expanded_bits
;
316 new_insn
->next
= (*cur_insn_ptr
);
317 new_insn
->nr_prefetched_words
= nr_prefetched_words
;
320 new_insn
->opcodes
= ZALLOC (insn_opcodes
);
321 new_insn
->opcodes
->opcode
= opcodes
;
323 (*cur_insn_ptr
) = new_insn
;
328 return (*cur_insn_ptr
);
333 gen_entry_traverse_tree (lf
*file
,
336 gen_entry_handler
*start
,
337 gen_entry_handler
*leaf
,
338 gen_entry_handler
*end
,
343 ASSERT (table
!= NULL
);
344 ASSERT (table
->opcode
!= NULL
);
345 ASSERT (table
->nr_entries
> 0);
346 ASSERT (table
->entries
!= 0);
349 if (start
!= NULL
&& depth
>= 0)
351 start (file
, table
, depth
, data
);
354 for (entry
= table
->entries
;
356 entry
= entry
->sibling
)
358 if (entry
->entries
!= NULL
&& depth
!= 0)
360 gen_entry_traverse_tree (file
, entry
, depth
+ 1,
361 start
, leaf
, end
, data
);
367 leaf (file
, entry
, depth
, data
);
372 if (end
!= NULL
&& depth
>= 0)
374 end (file
, table
, depth
, data
);
380 /* create a list element containing a single gen_table entry */
383 make_table (insn_table
*isa
,
388 gen_list
*entry
= ZALLOC (gen_list
);
389 entry
->table
= ZALLOC (gen_entry
);
390 entry
->table
->top
= entry
;
391 entry
->model
= model
;
393 for (insn
= isa
->insns
; insn
!= NULL
; insn
= insn
->next
)
396 || insn
->processors
== NULL
397 || filter_is_member (insn
->processors
, model
->name
))
399 insn_list_insert (&entry
->table
->insns
,
400 &entry
->table
->nr_insns
,
402 NULL
, /* expanded_bits - none yet */
403 NULL
, /* opcodes - none yet */
404 0, /* nr_prefetched_words - none yet */
405 report_duplicate_insns
);
408 entry
->table
->opcode_rule
= rules
;
414 make_gen_tables (insn_table
*isa
,
417 gen_table
*gen
= ZALLOC (gen_table
);
420 if (options
.gen
.multi_sim
)
422 gen_list
**last
= &gen
->tables
;
425 if (options
.model_filter
!= NULL
)
426 processors
= options
.model_filter
;
428 processors
= isa
->model
->processors
;
429 for (model
= isa
->model
->models
;
433 if (filter_is_member (processors
, model
->name
))
435 *last
= make_table (isa
, rules
, model
);
436 last
= &(*last
)->next
;
442 gen
->tables
= make_table (isa
, rules
, NULL
);
448 /****************************************************************/
452 field_is_not_constant
= 0,
453 field_constant_int
= 1,
454 field_constant_reserved
= 2,
455 field_constant_string
= 3
456 } constant_field_types
;
458 static constant_field_types
459 insn_field_is_constant (insn_field
*field
,
465 /* field is an integer */
466 return field_constant_int
;
467 case insn_field_reserved
:
468 /* field is `/' and treating that as a constant */
469 if (rule
->with_zero_reserved
)
470 return field_constant_reserved
;
472 return field_is_not_constant
;
473 case insn_field_wild
:
474 return field_is_not_constant
; /* never constant */
475 case insn_field_string
:
476 /* field, though variable, is on the list of forced constants */
477 if (filter_is_member (rule
->constant_field_names
, field
->val_string
))
478 return field_constant_string
;
480 return field_is_not_constant
;
482 ERROR ("Internal error");
483 return field_is_not_constant
;
488 /****************************************************************/
491 /* Is the bit, according to the decode rule, identical across all the
494 insns_bit_useless (insn_list
*insns
,
500 int is_useless
= 1; /* cleared if something actually found */
502 /* check the instructions for some constant value in at least one of
504 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
506 insn_word_entry
*word
= entry
->insn
->word
[rule
->word_nr
];
507 insn_bit_entry
*bit
= word
->bit
[bit_nr
];
508 switch (bit
->field
->type
)
510 case insn_field_invalid
:
513 case insn_field_wild
:
514 case insn_field_reserved
:
515 /* neither useless or useful - ignore */
518 switch (rule
->search
)
520 case decode_find_strings
:
521 /* an integer isn't a string */
523 case decode_find_constants
:
524 case decode_find_mixed
:
525 /* an integer is useful if its value isn't the same
526 between all instructions. The first time through the
527 value is saved, the second time through (if the
528 values differ) it is marked as useful. */
531 else if (value
!= bit
->value
)
536 case insn_field_string
:
537 switch (rule
->search
)
539 case decode_find_strings
:
540 /* at least one string, keep checking */
543 case decode_find_constants
:
544 case decode_find_mixed
:
545 if (filter_is_member (rule
->constant_field_names
,
546 bit
->field
->val_string
))
547 /* a string field forced to constant? */
549 else if (rule
->search
== decode_find_constants
)
550 /* the string field isn't constant */
557 /* Given only one constant value has been found, check through all
558 the instructions to see if at least one conditional makes it
560 if (value
>= 0 && is_useless
)
562 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
564 insn_word_entry
*word
= entry
->insn
->word
[rule
->word_nr
];
565 insn_bit_entry
*bit
= word
->bit
[bit_nr
];
566 switch (bit
->field
->type
)
568 case insn_field_invalid
:
571 case insn_field_wild
:
572 case insn_field_reserved
:
574 /* already processed */
576 case insn_field_string
:
577 switch (rule
->search
)
579 case decode_find_strings
:
580 case decode_find_constants
:
581 /* already processed */
583 case decode_find_mixed
:
584 /* string field with conditions. If this condition
585 eliminates the value then the compare is useful */
586 if (bit
->field
->conditions
!= NULL
)
588 insn_field_cond
*condition
;
589 int shift
= bit
->field
->last
- bit_nr
;
590 for (condition
= bit
->field
->conditions
;
592 condition
= condition
->next
)
594 printf ("useless %s%s\n",
595 (condition
->type
== insn_field_cond_eq
? "=" : "!"),
597 switch (condition
->type
)
599 case insn_field_cond_value
:
600 switch (condition
->test
)
602 case insn_field_cond_ne
:
603 if (((condition
->value
>> shift
) & 1) == value
)
604 /* conditional field excludes the
608 case insn_field_cond_eq
:
609 if (((condition
->value
>> shift
) & 1) != value
)
610 /* conditional field requires the
616 case insn_field_cond_field
:
617 /* are these handled separatly? */
631 /* go through a gen-table's list of instruction formats looking for a
632 range of bits that meet the decode table RULEs requirements */
634 static opcode_field
*
635 gen_entry_find_opcode_field (insn_list
*insns
,
639 opcode_field curr_opcode
;
640 ASSERT (rule
!= NULL
);
642 memset (&curr_opcode
, 0, sizeof (curr_opcode
));
643 curr_opcode
.word_nr
= rule
->word_nr
;
644 curr_opcode
.first
= rule
->first
;
645 curr_opcode
.last
= rule
->last
;
647 /* Try to reduce the size of first..last in accordance with the
650 while (curr_opcode
.first
<= rule
->last
)
652 if (insns_bit_useless (insns
, rule
, curr_opcode
.first
))
653 curr_opcode
.first
++;
657 while (curr_opcode
.last
>= rule
->first
)
659 if (insns_bit_useless (insns
, rule
, curr_opcode
.last
))
667 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
669 insn_word_entry
*fields
= entry
->insn
->word
[rule
->word_nr
];
670 opcode_field new_opcode
;
672 ASSERT (fields
!= NULL
);
674 /* find a start point for the opcode field */
675 new_opcode
.first
= rule
->first
;
676 while (new_opcode
.first
<= rule
->last
678 || (insn_field_is_constant(fields
->bit
[new_opcode
.first
], rule
)
679 != field_constant_string
))
681 || (insn_field_is_constant(fields
->bit
[new_opcode
.first
], rule
)
682 == field_is_not_constant
)))
684 int new_first
= fields
->bit
[new_opcode
.first
]->last
+ 1;
685 ASSERT (new_first
> new_opcode
.first
);
686 new_opcode
.first
= new_first
;
688 ASSERT(new_opcode
.first
> rule
->last
690 && insn_field_is_constant(fields
->bit
[new_opcode
.first
],
691 rule
) == field_constant_string
)
693 && insn_field_is_constant(fields
->bit
[new_opcode
.first
],
696 /* find the end point for the opcode field */
697 new_opcode
.last
= rule
->last
;
698 while (new_opcode
.last
>= rule
->first
700 || insn_field_is_constant(fields
->bit
[new_opcode
.last
],
701 rule
) != field_constant_string
)
703 || !insn_field_is_constant(fields
->bit
[new_opcode
.last
],
706 int new_last
= fields
->bit
[new_opcode
.last
]->first
- 1;
707 ASSERT (new_last
< new_opcode
.last
);
708 new_opcode
.last
= new_last
;
710 ASSERT(new_opcode
.last
< rule
->first
712 && insn_field_is_constant(fields
->bit
[new_opcode
.last
],
713 rule
) == field_constant_string
)
715 && insn_field_is_constant(fields
->bit
[new_opcode
.last
],
718 /* now see if our current opcode needs expanding to include the
719 interesting fields within this instruction */
720 if (new_opcode
.first
<= rule
->last
721 && curr_opcode
.first
> new_opcode
.first
)
722 curr_opcode
.first
= new_opcode
.first
;
723 if (new_opcode
.last
>= rule
->first
724 && curr_opcode
.last
< new_opcode
.last
)
725 curr_opcode
.last
= new_opcode
.last
;
730 /* did the final opcode field end up being empty? */
731 if (curr_opcode
.first
> curr_opcode
.last
)
735 ASSERT (curr_opcode
.last
>= rule
->first
);
736 ASSERT (curr_opcode
.first
<= rule
->last
);
737 ASSERT (curr_opcode
.first
<= curr_opcode
.last
);
739 /* Ensure that, for the non string only case, the opcode includes
740 the range forced_first .. forced_last */
742 && curr_opcode
.first
> rule
->force_first
)
744 curr_opcode
.first
= rule
->force_first
;
747 && curr_opcode
.last
< rule
->force_last
)
749 curr_opcode
.last
= rule
->force_last
;
752 /* For the string only case, force just the lower bound (so that the
753 shift can be eliminated) */
755 && rule
->force_last
== options
.insn_bit_size
- 1)
757 curr_opcode
.last
= options
.insn_bit_size
- 1;
760 /* handle any special cases */
763 case normal_decode_rule
:
764 /* let the above apply */
765 curr_opcode
.nr_opcodes
=
766 (1 << (curr_opcode
.last
- curr_opcode
.first
+ 1));
769 curr_opcode
.is_boolean
= 1;
770 curr_opcode
.boolean_constant
= rule
->constant
;
771 curr_opcode
.nr_opcodes
= 2;
776 opcode_field
*new_field
= ZALLOC (opcode_field
);
777 memcpy (new_field
, &curr_opcode
, sizeof (opcode_field
));
784 gen_entry_insert_insn (gen_entry
*table
,
785 insn_entry
*old_insn
,
787 int new_nr_prefetched_words
,
789 opcode_bits
*new_bits
)
791 gen_entry
**entry
= &table
->entries
;
793 /* find the new table for this entry */
794 while ((*entry
) != NULL
&& (*entry
)->opcode_nr
< new_opcode_nr
)
796 entry
= &(*entry
)->sibling
;
799 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= new_opcode_nr
)
801 /* insert the missing entry */
802 gen_entry
*new_entry
= ZALLOC (gen_entry
);
803 new_entry
->sibling
= (*entry
);
804 (*entry
) = new_entry
;
807 new_entry
->top
= table
->top
;
808 new_entry
->opcode_nr
= new_opcode_nr
;
809 new_entry
->word_nr
= new_word_nr
;
810 new_entry
->expanded_bits
= new_bits
;
811 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
812 new_entry
->parent
= table
;
813 new_entry
->nr_prefetched_words
= new_nr_prefetched_words
;
815 /* ASSERT new_bits == cur_entry bits */
816 ASSERT ((*entry
) != NULL
&& (*entry
)->opcode_nr
== new_opcode_nr
);
817 insn_list_insert (&(*entry
)->insns
,
820 NULL
, /* expanded_bits - only in final list */
821 NULL
, /* opcodes - only in final list */
822 new_nr_prefetched_words
, /* for this table */
823 report_duplicate_insns
);
828 gen_entry_expand_opcode (gen_entry
*table
,
829 insn_entry
*instruction
,
834 if (bit_nr
> table
->opcode
->last
)
836 /* Only include the hardwired bit information with an entry IF
837 that entry (and hence its functions) are being duplicated. */
838 if (options
.trace
.insn_expansion
)
840 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
841 notify (NULL
, ": insert %d - %s.%s%s\n",
843 instruction
->format_name
,
845 (table
->opcode_rule
->with_duplicates
? " (duplicated)" : ""));
847 if (table
->opcode_rule
->with_duplicates
)
849 gen_entry_insert_insn (table
, instruction
,
850 table
->opcode
->word_nr
,
851 table
->nr_prefetched_words
,
856 if (options
.trace
.insn_insertion
)
860 gen_entry_insert_insn (table
, instruction
,
861 table
->opcode
->word_nr
,
862 table
->nr_prefetched_words
,
868 insn_word_entry
*word
= instruction
->word
[table
->opcode
->word_nr
];
869 insn_field_entry
*field
= word
->bit
[bit_nr
]->field
;
870 int last_pos
= ((field
->last
< table
->opcode
->last
)
872 : table
->opcode
->last
);
873 int first_pos
= ((field
->first
> table
->opcode
->first
)
875 : table
->opcode
->first
);
876 int width
= last_pos
- first_pos
+ 1;
882 val
= sub_val (field
->val_int
, field
, first_pos
, last_pos
);
883 gen_entry_expand_opcode (table
, instruction
,
885 ((opcode_nr
<< width
) | val
),
891 if (field
->type
== insn_field_reserved
)
892 gen_entry_expand_opcode (table
, instruction
,
894 ((opcode_nr
<< width
)),
899 int last_val
= (table
->opcode
->is_boolean
902 for (val
= 0; val
< last_val
; val
++)
904 /* check to see if the value has been precluded
905 (by a conditional) in some way */
907 insn_field_cond
*condition
;
908 for (condition
= field
->conditions
, is_precluded
= 0;
909 condition
!= NULL
&& !is_precluded
;
910 condition
= condition
->next
)
912 switch (condition
->type
)
914 case insn_field_cond_value
:
916 int value
= sub_val (condition
->value
, field
,
917 first_pos
, last_pos
);
918 switch (condition
->test
)
920 case insn_field_cond_ne
:
924 case insn_field_cond_eq
:
931 case insn_field_cond_field
:
934 /* Find a value for the conditional by
935 looking back through the previously
936 defined bits for the specified
938 opcode_bits
*bit
= bits
;
943 if (bit
->field
== condition
->field
944 && (bit
->last
- bit
->first
+ 1 == condition
->field
->width
))
945 /* the bit field fully specified
946 the conditional field's value */
950 error (instruction
->line
,
951 "Conditional `%s' of field `%s' isn't expanded",
952 condition
->string
, field
->val_string
);
953 value
= sub_val (bit
->value
, field
,
954 first_pos
, last_pos
);
955 switch (condition
->test
)
957 case insn_field_cond_ne
:
961 case insn_field_cond_eq
:
972 /* Only add additional hardwired bit
973 information if the entry is not going to
975 if (table
->opcode_rule
->with_combine
)
977 gen_entry_expand_opcode (table
, instruction
,
979 ((opcode_nr
<< width
) | val
),
984 opcode_bits
*new_bits
= new_opcode_bits (bits
, val
,
988 gen_entry_expand_opcode (table
, instruction
,
990 ((opcode_nr
<< width
) | val
),
1002 gen_entry_insert_expanding (gen_entry
*table
,
1003 insn_entry
*instruction
)
1005 gen_entry_expand_opcode (table
,
1007 table
->opcode
->first
,
1009 table
->expanded_bits
);
1014 insns_match_format_names (insn_list
*insns
,
1015 filter
*format_names
)
1017 if (format_names
!= NULL
)
1020 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1022 if ( i
->insn
->format_name
!= NULL
1023 && !filter_is_member (format_names
, i
->insn
->format_name
))
1031 table_matches_path (gen_entry
*table
,
1032 decode_path_list
*paths
)
1036 while (paths
!= NULL
)
1038 gen_entry
*entry
= table
;
1039 decode_path
*path
= paths
->path
;
1042 if (entry
== NULL
&& path
== NULL
)
1044 if (entry
== NULL
|| path
== NULL
)
1046 if (entry
->opcode_nr
!= path
->opcode_nr
)
1048 entry
= entry
->parent
;
1049 path
= path
->parent
;
1051 paths
= paths
->next
;
1058 insns_match_conditions (insn_list
*insns
,
1059 decode_cond
*conditions
)
1061 if (conditions
!= NULL
)
1064 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1067 for (cond
= conditions
; cond
!= NULL
; cond
= cond
->next
)
1070 if (i
->insn
->nr_words
<= cond
->word_nr
)
1072 for (bit_nr
= 0; bit_nr
< options
.insn_bit_size
; bit_nr
++)
1074 if (!cond
->mask
[bit_nr
])
1076 if (!i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->mask
)
1078 if ((i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->value
1079 == cond
->value
[bit_nr
])
1090 insns_match_nr_words (insn_list
*insns
,
1094 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1096 if (i
->insn
->nr_words
< nr_words
)
1103 insn_list_cmp (insn_list
*l
,
1109 if (l
== NULL
&& r
== NULL
)
1115 if (l
->insn
!= r
->insn
)
1116 return -1; /* somewhat arbitrary at present */
1117 /* skip this insn */
1119 while (l
!= NULL
&& l
->insn
== insn
)
1121 while (r
!= NULL
&& r
->insn
== insn
)
1129 gen_entry_expand_insns (gen_entry
*table
)
1131 decode_table
*opcode_rule
;
1133 ASSERT(table
->nr_insns
>= 1);
1135 /* determine a valid opcode */
1136 for (opcode_rule
= table
->opcode_rule
;
1137 opcode_rule
!= NULL
;
1138 opcode_rule
= opcode_rule
->next
)
1140 char *discard_reason
;
1141 if (table
->top
->model
!= NULL
1142 && opcode_rule
->model_names
!= NULL
1143 && !filter_is_member (opcode_rule
->model_names
,
1144 table
->top
->model
->name
))
1146 /* the rule isn't applicable to this processor */
1147 discard_reason
= "wrong model";
1149 else if (table
->nr_insns
== 1 && opcode_rule
->conditions
== NULL
)
1151 /* for safety, require a pre-codition when attempting to
1152 apply a rule to a single instruction */
1153 discard_reason
= "need pre-condition when nr-insn == 1";
1155 else if (table
->nr_insns
== 1 && !opcode_rule
->with_duplicates
)
1157 /* Little point in expanding a single instruction when we're
1158 not duplicating the semantic functions that this table
1160 discard_reason
= "need duplication with nr-insns == 1";
1162 else if (!insns_match_format_names (table
->insns
, opcode_rule
->format_names
))
1164 discard_reason
= "wrong format name";
1166 else if (!insns_match_nr_words (table
->insns
, opcode_rule
->word_nr
+ 1))
1168 discard_reason
= "wrong nr words";
1170 else if (!table_matches_path (table
, opcode_rule
->paths
))
1172 discard_reason
= "path failed";
1174 else if (!insns_match_conditions (table
->insns
, opcode_rule
->conditions
))
1176 discard_reason
= "condition failed";
1180 discard_reason
= "no opcode field";
1182 gen_entry_find_opcode_field (table
->insns
,
1184 table
->nr_insns
== 1/*string-only*/
1186 if (table
->opcode
!= NULL
)
1188 table
->opcode_rule
= opcode_rule
;
1193 if (options
.trace
.rule_rejection
)
1195 print_gen_entry_path (opcode_rule
->line
, table
, notify
);
1196 notify (NULL
, ": rule discarded - %s\n", discard_reason
);
1200 /* did we find anything */
1201 if (opcode_rule
== NULL
)
1203 /* the decode table failed, this set of instructions haven't
1204 been uniquely identified */
1205 if (table
->nr_insns
> 1)
1207 print_gen_entry_insns (table
, warning
,
1208 "was not uniquely decoded",
1209 "decodes to the same entry");
1215 /* Determine the number of words that must have been prefetched for
1216 this table to function */
1217 if (table
->parent
== NULL
)
1218 table
->nr_prefetched_words
= table
->opcode_rule
->word_nr
+ 1;
1219 else if (table
->opcode_rule
->word_nr
+ 1 > table
->parent
->nr_prefetched_words
)
1220 table
->nr_prefetched_words
= table
->opcode_rule
->word_nr
+ 1;
1222 table
->nr_prefetched_words
= table
->parent
->nr_prefetched_words
;
1224 /* back link what we found to its parent */
1225 if (table
->parent
!= NULL
)
1227 ASSERT(table
->parent
->opcode
!= NULL
);
1228 table
->opcode
->parent
= table
->parent
->opcode
;
1231 /* report the rule being used to expand the instructions */
1232 if (options
.trace
.rule_selection
)
1234 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1236 ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
1237 table
->opcode
->word_nr
,
1238 i2target (options
.hi_bit_nr
, table
->opcode
->first
),
1239 i2target (options
.hi_bit_nr
, table
->opcode
->last
),
1240 i2target (options
.hi_bit_nr
, table
->opcode_rule
->first
),
1241 i2target (options
.hi_bit_nr
, table
->opcode_rule
->last
),
1242 table
->opcode
->nr_opcodes
,
1246 /* expand the raw instructions according to the opcode */
1249 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
)
1251 if (options
.trace
.insn_expansion
)
1253 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1254 notify (NULL
, ": expand - %s.%s\n",
1255 entry
->insn
->format_name
,
1258 gen_entry_insert_expanding (table
, entry
->insn
);
1262 /* dump the results */
1263 if (options
.trace
.entries
)
1266 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1269 print_gen_entry_path (table
->opcode_rule
->line
, entry
, notify
);
1270 notify (NULL
, ": %d - entries %d -",
1273 for (l
= entry
->insns
; l
!= NULL
; l
= l
->next
)
1274 notify (NULL
, " %s.%s", l
->insn
->format_name
, l
->insn
->name
);
1275 notify (NULL
, "\n");
1279 /* perform a combine pass if needed */
1280 if (table
->opcode_rule
->with_combine
)
1283 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1285 if (entry
->combined_parent
== NULL
)
1287 gen_entry
**last
= &entry
->combined_next
;
1289 for (alt
= entry
->sibling
; alt
!= NULL
; alt
= alt
->sibling
)
1291 if (alt
->combined_parent
== NULL
1292 && insn_list_cmp (entry
->insns
, alt
->insns
) == 0)
1294 alt
->combined_parent
= entry
;
1296 last
= &alt
->combined_next
;
1301 if (options
.trace
.combine
)
1305 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1307 if (entry
->combined_parent
== NULL
)
1310 gen_entry
*duplicate
;
1312 print_gen_entry_path (table
->opcode_rule
->line
, entry
, notify
);
1313 for (duplicate
= entry
->combined_next
;
1315 duplicate
= duplicate
->combined_next
)
1317 notify (NULL
, "+%d", duplicate
->opcode_nr
);
1319 notify (NULL
, ": entries %d -", entry
->nr_insns
);
1320 for (l
= entry
->insns
; l
!= NULL
; l
= l
->next
)
1322 notify (NULL
, " %s.%s",
1323 l
->insn
->format_name
,
1326 notify (NULL
, "\n");
1329 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1330 notify (NULL
, ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
1331 table
->opcode
->word_nr
,
1332 i2target (options
.hi_bit_nr
, table
->opcode
->first
),
1333 i2target (options
.hi_bit_nr
, table
->opcode
->last
),
1334 i2target (options
.hi_bit_nr
, table
->opcode_rule
->first
),
1335 i2target (options
.hi_bit_nr
, table
->opcode_rule
->last
),
1336 table
->opcode
->nr_opcodes
,
1342 /* Check that the rule did more than re-arange the order of the
1346 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1348 if (entry
->combined_parent
== NULL
)
1350 if (insn_list_cmp (table
->insns
, entry
->insns
) == 0)
1352 print_gen_entry_path (table
->opcode_rule
->line
, table
, warning
);
1353 warning (NULL
, ": Applying rule just copied all instructions\n");
1354 print_gen_entry_insns (entry
, warning
, "Copied", NULL
);
1361 /* if some form of expanded table, fill in the missing dots */
1362 switch (table
->opcode_rule
->gen
)
1364 case padded_switch_gen
:
1366 case goto_switch_gen
:
1367 if (!table
->opcode
->is_boolean
)
1369 gen_entry
**entry
= &table
->entries
;
1370 gen_entry
*illegals
= NULL
;
1371 gen_entry
**last_illegal
= &illegals
;
1373 while (opcode_nr
< table
->opcode
->nr_opcodes
)
1375 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= opcode_nr
)
1377 /* missing - insert it under our feet at *entry */
1378 gen_entry_insert_insn (table
,
1379 table
->top
->isa
->illegal_insn
,
1380 table
->opcode
->word_nr
,
1381 0, /* nr_prefetched_words == 0 for invalid */
1383 ASSERT ((*entry
) != NULL
);
1384 ASSERT ((*entry
)->opcode_nr
== opcode_nr
);
1385 (*last_illegal
) = *entry
;
1386 (*last_illegal
)->combined_parent
= illegals
;
1387 last_illegal
= &(*last_illegal
)->combined_next
;
1389 entry
= &(*entry
)->sibling
;
1392 /* oops, will have pointed the first illegal insn back to
1393 its self. Fix this */
1394 if (illegals
!= NULL
)
1395 illegals
->combined_parent
= NULL
;
1404 /* and do the same for the newly created sub entries but *only*
1405 expand entries that haven't been combined. */
1408 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1410 if (entry
->combined_parent
== NULL
)
1412 gen_entry_expand_insns (entry
);
1419 gen_tables_expand_insns (gen_table
*gen
)
1422 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1424 gen_entry_expand_insns (entry
->table
);
1429 /* create a list of all the semantic functions that need to be
1430 generated. Eliminate any duplicates. Verify that the decode stage
1434 make_gen_semantics_list (lf
*file
,
1439 gen_table
*gen
= (gen_table
*) data
;
1441 /* Not interested in an entrie that have been combined into some
1442 other entry at the same level */
1443 if (entry
->combined_parent
!= NULL
)
1446 /* a leaf should contain exactly one instruction. If not the decode
1448 ASSERT (entry
->nr_insns
== 1);
1450 /* Enter this instruction into the list of semantic functions. */
1451 insn
= insn_list_insert (&gen
->semantics
, &gen
->nr_semantics
,
1453 entry
->expanded_bits
,
1454 entry
->parent
->opcode
,
1455 entry
->insns
->nr_prefetched_words
,
1456 merge_duplicate_insns
);
1457 /* point the table entry at the real semantic function */
1458 ASSERT (insn
!= NULL
);
1459 entry
->insns
->semantic
= insn
;
1464 gen_tables_expand_semantics (gen_table
*gen
)
1467 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1469 gen_entry_traverse_tree (NULL
,
1472 NULL
, /* start-handler */
1473 make_gen_semantics_list
, /* leaf-handler */
1474 NULL
, /* end-handler */
1485 dump_opcode_field (lf
*file
,
1487 opcode_field
*field
,
1491 lf_printf (file
, "%s(opcode_field *) 0x%lx", prefix
, (long) field
);
1492 if (levels
&& field
!= NULL
) {
1493 lf_indent (file
, +1);
1494 lf_printf (file
, "\n(first %d)", field
->first
);
1495 lf_printf (file
, "\n(last %d)", field
->last
);
1496 lf_printf (file
, "\n(nr_opcodes %d)", field
->nr_opcodes
);
1497 lf_printf (file
, "\n(is_boolean %d)", field
->is_boolean
);
1498 lf_printf (file
, "\n(boolean_constant %d)", field
->boolean_constant
);
1499 dump_opcode_field(file
, "\n(parent ", field
->parent
, ")", levels
- 1);
1500 lf_indent (file
, -1);
1502 lf_printf (file
, "%s", suffix
);
1507 dump_opcode_bits (lf
*file
,
1513 lf_printf (file
, "%s(opcode_bits *) 0x%lx", prefix
, (long) bits
);
1515 if (levels
&& bits
!= NULL
)
1517 lf_indent (file
, +1);
1518 lf_printf (file
, "\n(value %d)", bits
->value
);
1519 dump_opcode_field (file
, "\n(opcode ", bits
->opcode
, ")", 0);
1520 dump_insn_field (file
, "\n(field ", bits
->field
, ")");
1521 dump_opcode_bits (file
, "\n(next ", bits
->next
, ")", levels
- 1);
1522 lf_indent (file
, -1);
1524 lf_printf (file
, "%s", suffix
);
1530 dump_insn_list (lf
*file
,
1535 lf_printf (file
, "%s(insn_list *) 0x%lx", prefix
, (long) entry
);
1537 if (entry
!= NULL
) {
1538 lf_indent (file
, +1);
1539 dump_insn_entry (file
, "\n(insn ", entry
->insn
, ")");
1540 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1541 lf_indent (file
, -1);
1543 lf_printf (file
, "%s", suffix
);
1548 dump_insn_word_entry_list_entries (lf
*file
,
1553 lf_printf (file
, "%s", prefix
);
1554 while (entry
!= NULL
)
1556 dump_insn_list (file
, "\n(", entry
, ")");
1557 entry
= entry
->next
;
1559 lf_printf (file
, "%s", suffix
);
1564 dump_gen_entry (lf
*file
,
1571 lf_printf (file
, "%s(gen_entry *) 0x%lx", prefix
, (long) table
);
1573 if (levels
&& table
!= NULL
) {
1575 lf_indent (file
, +1);
1576 lf_printf (file
, "\n(opcode_nr %d)", table
->opcode_nr
);
1577 lf_printf (file
, "\n(word_nr %d)", table
->word_nr
);
1578 dump_opcode_bits (file
, "\n(expanded_bits ", table
->expanded_bits
, ")", -1);
1579 lf_printf (file
, "\n(nr_insns %d)", table
->nr_insns
);
1580 dump_insn_word_entry_list_entries (file
, "\n(insns ", table
->insns
, ")");
1581 dump_decode_rule (file
, "\n(opcode_rule ", table
->opcode_rule
, ")");
1582 dump_opcode_field (file
, "\n(opcode ", table
->opcode
, ")", 0);
1583 lf_printf (file
, "\n(nr_entries %d)", table
->nr_entries
);
1584 dump_gen_entry (file
, "\n(entries ", table
->entries
, ")", table
->nr_entries
);
1585 dump_gen_entry (file
, "\n(sibling ", table
->sibling
, ")", levels
- 1);
1586 dump_gen_entry (file
, "\n(parent ", table
->parent
, ")", 0);
1587 lf_indent (file
, -1);
1589 lf_printf (file
, "%s", suffix
);
1593 dump_gen_list (lf
*file
,
1599 while (entry
!= NULL
)
1601 lf_printf (file
, "%s(gen_list *) 0x%lx", prefix
, (long) entry
);
1602 dump_gen_entry (file
, "\n(", entry
->table
, ")", levels
);
1603 lf_printf (file
, "\n(next (gen_list *) 0x%lx)", (long) entry
->next
);
1604 lf_printf (file
, "%s", suffix
);
1610 dump_gen_table (lf
*file
,
1616 lf_printf (file
, "%s(gen_table *) 0x%lx", prefix
, (long) gen
);
1617 lf_printf (file
, "\n(isa (insn_table *) 0x%lx)", (long) gen
->isa
);
1618 lf_printf (file
, "\n(rules (decode_table *) 0x%lx)", (long) gen
->rules
);
1619 dump_gen_list (file
, "\n(", gen
->tables
, ")", levels
);
1620 lf_printf (file
, "%s", suffix
);
1624 igen_options options
;
1630 decode_table
*decode_rules
;
1631 insn_table
*instructions
;
1636 error (NULL
, "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
1638 INIT_OPTIONS (options
);
1640 filter_parse (&options
.flags_filter
, argv
[1]);
1642 options
.hi_bit_nr
= a2i(argv
[2]);
1643 options
.insn_bit_size
= a2i(argv
[3]);
1644 options
.insn_specifying_widths
= a2i(argv
[4]);
1645 ASSERT(options
.hi_bit_nr
< options
.insn_bit_size
);
1647 instructions
= load_insn_table (argv
[6], NULL
);
1648 decode_rules
= load_decode_table (argv
[5]);
1649 gen
= make_gen_tables (instructions
, decode_rules
);
1651 gen_tables_expand_insns (gen
);
1653 l
= lf_open ("-", "stdout", lf_omit_references
, lf_is_text
, "tmp-ld-insn");
1655 dump_gen_table (l
, "(", gen
, ")\n", -1);