1 /* The IGEN simulator generator for GDB, the GNU Debugger.
3 Copyright 2002 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
32 #include "ld-decode.h"
36 sub_val (insn_uint val
, int val_last_pos
, int first_pos
, int last_pos
)
38 return ((val
>> (val_last_pos
- last_pos
))
39 & (((insn_uint
) 1 << (last_pos
- first_pos
+ 1)) - 1));
43 update_depth (lf
*file
, gen_entry
*entry
, int depth
, void *data
)
45 int *max_depth
= (int *) data
;
46 if (*max_depth
< depth
)
52 gen_entry_depth (gen_entry
*table
)
55 gen_entry_traverse_tree (NULL
, table
, 1, NULL
, /*start */
56 update_depth
, NULL
, /*end */
63 print_gen_entry_path (line_ref
*line
, gen_entry
*table
, error_func
*print
)
65 if (table
->parent
== NULL
)
67 if (table
->top
->model
!= NULL
)
68 print (line
, "%s", table
->top
->model
->name
);
74 print_gen_entry_path (line
, table
->parent
, print
);
75 print (NULL
, ".%d", table
->opcode_nr
);
80 print_gen_entry_insns (gen_entry
*table
,
82 char *first_message
, char *next_message
)
86 message
= first_message
;
87 for (i
= table
->insns
; i
!= NULL
; i
= i
->next
)
89 insn_entry
*insn
= i
->insn
;
90 print_gen_entry_path (insn
->line
, table
, print
);
91 print (NULL
, ": %s.%s %s\n", insn
->format_name
, insn
->name
, message
);
92 if (next_message
!= NULL
)
93 message
= next_message
;
99 insn_field_cmp (insn_word_entry
*l
, insn_word_entry
*r
)
104 if (l
== NULL
&& r
== NULL
)
105 return 0; /* all previous fields the same */
107 return -1; /* left shorter than right */
109 return +1; /* left longer than right */
110 for (bit_nr
= 0; bit_nr
< options
.insn_bit_size
; bit_nr
++)
112 if (l
->bit
[bit_nr
]->field
->type
!= insn_field_string
)
114 if (r
->bit
[bit_nr
]->field
->type
!= insn_field_string
)
116 if (l
->bit
[bit_nr
]->field
->conditions
== NULL
)
118 if (r
->bit
[bit_nr
]->field
->conditions
== NULL
)
121 printf ("%s%s%s VS %s%s%s\n",
122 l
->bit
[bit_nr
]->field
->val_string
,
123 l
->bit
[bit_nr
]->field
->conditions
->test
==
124 insn_field_cond_eq
? "=" : "!",
125 l
->bit
[bit_nr
]->field
->conditions
->string
,
126 r
->bit
[bit_nr
]->field
->val_string
,
127 r
->bit
[bit_nr
]->field
->conditions
->test
==
128 insn_field_cond_eq
? "=" : "!",
129 r
->bit
[bit_nr
]->field
->conditions
->string
);
130 if (l
->bit
[bit_nr
]->field
->conditions
->test
== insn_field_cond_eq
131 && r
->bit
[bit_nr
]->field
->conditions
->test
==
134 if (l
->bit
[bit_nr
]->field
->conditions
->type
==
135 insn_field_cond_field
136 && r
->bit
[bit_nr
]->field
->conditions
->type
==
137 insn_field_cond_field
)
138 /* somewhat arbitrary */
140 int cmp
= strcmp (l
->bit
[bit_nr
]->field
->conditions
->string
,
141 r
->bit
[bit_nr
]->field
->conditions
->
148 if (l
->bit
[bit_nr
]->field
->conditions
->type
==
149 insn_field_cond_field
)
151 if (r
->bit
[bit_nr
]->field
->conditions
->type
==
152 insn_field_cond_field
)
154 /* The case of both fields having constant values should have
155 already have been handled because such fields are converted
156 into normal constant fields. */
159 if (l
->bit
[bit_nr
]->field
->conditions
->test
== insn_field_cond_eq
)
160 return +1; /* left = only */
161 if (r
->bit
[bit_nr
]->field
->conditions
->test
== insn_field_cond_eq
)
162 return -1; /* right = only */
163 /* FIXME: Need to some what arbitrarily order conditional lists */
173 insn_word_cmp (insn_word_entry
*l
, insn_word_entry
*r
)
178 if (l
== NULL
&& r
== NULL
)
179 return 0; /* all previous fields the same */
181 return -1; /* left shorter than right */
183 return +1; /* left longer than right */
184 for (bit_nr
= 0; bit_nr
< options
.insn_bit_size
; bit_nr
++)
186 if (l
->bit
[bit_nr
]->mask
< r
->bit
[bit_nr
]->mask
)
188 if (l
->bit
[bit_nr
]->mask
> r
->bit
[bit_nr
]->mask
)
190 if (l
->bit
[bit_nr
]->value
< r
->bit
[bit_nr
]->value
)
192 if (l
->bit
[bit_nr
]->value
> r
->bit
[bit_nr
]->value
)
202 opcode_bit_cmp (opcode_bits
*l
, opcode_bits
*r
)
204 if (l
== NULL
&& r
== NULL
)
205 return 0; /* all previous bits the same */
207 return -1; /* left shorter than right */
209 return +1; /* left longer than right */
210 /* most significant word */
211 if (l
->field
->word_nr
< r
->field
->word_nr
)
212 return +1; /* left has more significant word */
213 if (l
->field
->word_nr
> r
->field
->word_nr
)
214 return -1; /* right has more significant word */
215 /* most significant bit? */
216 if (l
->first
< r
->first
)
217 return +1; /* left as more significant bit */
218 if (l
->first
> r
->first
)
219 return -1; /* right as more significant bit */
221 if (l
->last
< r
->last
)
222 return +1; /* left as less bits */
223 if (l
->last
> r
->last
)
224 return -1; /* right as less bits */
226 if (l
->value
< r
->value
)
228 if (l
->value
> r
->value
)
236 opcode_bits_cmp (opcode_bits
*l
, opcode_bits
*r
)
241 if (l
== NULL
&& r
== NULL
)
242 return 0; /* all previous bits the same */
243 cmp
= opcode_bit_cmp (l
, r
);
253 new_opcode_bits (opcode_bits
*old_bits
,
256 int last
, insn_field_entry
*field
, opcode_field
*opcode
)
258 opcode_bits
*new_bits
= ZALLOC (opcode_bits
);
259 new_bits
->field
= field
;
260 new_bits
->value
= value
;
261 new_bits
->first
= first
;
262 new_bits
->last
= last
;
263 new_bits
->opcode
= opcode
;
265 if (old_bits
!= NULL
)
267 opcode_bits
*new_list
;
268 opcode_bits
**last
= &new_list
;
269 new_list
= new_opcode_bits (old_bits
->next
,
273 old_bits
->field
, old_bits
->opcode
);
274 while (*last
!= NULL
)
276 int cmp
= opcode_bit_cmp (new_bits
, *last
);
277 if (cmp
< 0) /* new < new_list */
283 ERROR ("Duplicated insn bits in list");
285 last
= &(*last
)->next
;
287 new_bits
->next
= *last
;
297 /* Same as strcmp(). */
299 name_cmp (const char *l
, const char *r
)
301 if (l
== NULL
&& r
== NULL
)
303 if (l
!= NULL
&& r
== NULL
)
305 if (l
== NULL
&& r
!= NULL
)
307 return strcmp (l
, r
);
313 merge_duplicate_insns
,
314 report_duplicate_insns
,
316 duplicate_insn_actions
;
319 insn_list_insert (insn_list
**cur_insn_ptr
,
322 opcode_bits
*expanded_bits
,
323 opcode_field
*opcodes
,
324 int nr_prefetched_words
,
325 duplicate_insn_actions duplicate_action
)
327 /* insert it according to the order of the fields & bits */
328 for (; (*cur_insn_ptr
) != NULL
; cur_insn_ptr
= &(*cur_insn_ptr
)->next
)
332 /* key#1 sort according to the constant fields of each instruction */
333 cmp
= insn_word_cmp (insn
->words
, (*cur_insn_ptr
)->insn
->words
);
339 /* key#2 sort according to the expanded bits of each instruction */
340 cmp
= opcode_bits_cmp (expanded_bits
, (*cur_insn_ptr
)->expanded_bits
);
346 /* key#3 sort according to the non-constant fields of each instruction */
347 cmp
= insn_field_cmp (insn
->words
, (*cur_insn_ptr
)->insn
->words
);
353 if (duplicate_action
== merge_duplicate_insns
)
355 /* key#4: If we're going to merge duplicates, also sort
356 according to the format_name. Two instructions with
357 identical decode patterns, but different names, are
358 considered different when merging. Duplicates are only
359 important when creating a decode table (implied by
360 report_duplicate_insns) as such a table only has the
361 instruction's bit code as a way of differentiating
362 between instructions. */
363 int cmp
= name_cmp (insn
->format_name
,
364 (*cur_insn_ptr
)->insn
->format_name
);
371 if (duplicate_action
== merge_duplicate_insns
)
373 /* key#5: If we're going to merge duplicates, also sort
374 according to the name. See comment above for
376 int cmp
= name_cmp (insn
->name
, (*cur_insn_ptr
)->insn
->name
);
383 /* duplicate keys, report problem */
384 switch (duplicate_action
)
386 case report_duplicate_insns
:
387 /* It would appear that we have two instructions with the
388 same constant field values across all words and bits.
389 This error can also occure when insn_field_cmp() is
390 failing to differentiate between two instructions that
391 differ only in their conditional fields. */
393 "Two instructions with identical constant fields\n");
394 error ((*cur_insn_ptr
)->insn
->line
,
395 "Location of duplicate instruction\n");
396 case merge_duplicate_insns
:
397 /* Add the opcode path to the instructions list */
398 if (options
.trace
.insn_insertion
)
400 notify ((*cur_insn_ptr
)->insn
->line
,
401 "%s.%s: insert merge %s.%s\n",
402 (*cur_insn_ptr
)->insn
->format_name
,
403 (*cur_insn_ptr
)->insn
->name
,
409 insn_opcodes
**last
= &(*cur_insn_ptr
)->opcodes
;
410 while (*last
!= NULL
)
412 last
= &(*last
)->next
;
414 (*last
) = ZALLOC (insn_opcodes
);
415 (*last
)->opcode
= opcodes
;
417 /* Use the larger nr_prefetched_words */
418 if ((*cur_insn_ptr
)->nr_prefetched_words
< nr_prefetched_words
)
419 (*cur_insn_ptr
)->nr_prefetched_words
= nr_prefetched_words
;
420 return (*cur_insn_ptr
);
425 /* create a new list entry and insert it */
427 insn_list
*new_insn
= ZALLOC (insn_list
);
428 if (options
.trace
.insn_insertion
)
431 "%s.%s: insert new\n",
435 new_insn
->insn
= insn
;
436 new_insn
->expanded_bits
= expanded_bits
;
437 new_insn
->next
= (*cur_insn_ptr
);
438 new_insn
->nr_prefetched_words
= nr_prefetched_words
;
441 new_insn
->opcodes
= ZALLOC (insn_opcodes
);
442 new_insn
->opcodes
->opcode
= opcodes
;
444 (*cur_insn_ptr
) = new_insn
;
449 return (*cur_insn_ptr
);
454 gen_entry_traverse_tree (lf
*file
,
457 gen_entry_handler
* start
,
458 gen_entry_handler
* leaf
,
459 gen_entry_handler
* end
, void *data
)
463 ASSERT (table
!=NULL
);
464 ASSERT (table
->opcode
!= NULL
);
465 ASSERT (table
->nr_entries
> 0);
466 ASSERT (table
->entries
!= 0);
469 if (start
!= NULL
&& depth
>= 0)
471 start (file
, table
, depth
, data
);
474 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
476 if (entry
->entries
!= NULL
&& depth
!= 0)
478 gen_entry_traverse_tree (file
, entry
, depth
+ 1,
479 start
, leaf
, end
, data
);
485 leaf (file
, entry
, depth
, data
);
490 if (end
!= NULL
&& depth
>= 0)
492 end (file
, table
, depth
, data
);
498 /* create a list element containing a single gen_table entry */
501 make_table (insn_table
*isa
, decode_table
*rules
, model_entry
*model
)
504 gen_list
*entry
= ZALLOC (gen_list
);
505 entry
->table
= ZALLOC (gen_entry
);
506 entry
->table
->top
= entry
;
507 entry
->model
= model
;
509 for (insn
= isa
->insns
; insn
!= NULL
; insn
= insn
->next
)
512 || insn
->processors
== NULL
513 || filter_is_member (insn
->processors
, model
->name
))
515 insn_list_insert (&entry
->table
->insns
, &entry
->table
->nr_insns
, insn
, NULL
, /* expanded_bits - none yet */
516 NULL
, /* opcodes - none yet */
517 0, /* nr_prefetched_words - none yet */
518 report_duplicate_insns
);
521 entry
->table
->opcode_rule
= rules
;
527 make_gen_tables (insn_table
*isa
, decode_table
*rules
)
529 gen_table
*gen
= ZALLOC (gen_table
);
532 if (options
.gen
.multi_sim
)
534 gen_list
**last
= &gen
->tables
;
537 if (options
.model_filter
!= NULL
)
538 processors
= options
.model_filter
;
540 processors
= isa
->model
->processors
;
541 for (model
= isa
->model
->models
; model
!= NULL
; model
= model
->next
)
543 if (filter_is_member (processors
, model
->name
))
545 *last
= make_table (isa
, rules
, model
);
546 last
= &(*last
)->next
;
552 gen
->tables
= make_table (isa
, rules
, NULL
);
558 /****************************************************************/
563 field_is_not_constant
= 0,
564 field_constant_int
= 1,
565 field_constant_reserved
= 2,
566 field_constant_string
= 3
568 constant_field_types
;
570 static constant_field_types
571 insn_field_is_constant (insn_field
* field
, decode_table
*rule
)
576 /* field is an integer */
577 return field_constant_int
;
578 case insn_field_reserved
:
579 /* field is `/' and treating that as a constant */
580 if (rule
->with_zero_reserved
)
581 return field_constant_reserved
;
583 return field_is_not_constant
;
584 case insn_field_wild
:
585 return field_is_not_constant
; /* never constant */
586 case insn_field_string
:
587 /* field, though variable, is on the list of forced constants */
588 if (filter_is_member (rule
->constant_field_names
, field
->val_string
))
589 return field_constant_string
;
591 return field_is_not_constant
;
593 ERROR ("Internal error");
594 return field_is_not_constant
;
599 /****************************************************************/
602 /* Is the bit, according to the decode rule, identical across all the
605 insns_bit_useless (insn_list
*insns
, decode_table
*rule
, int bit_nr
)
609 int is_useless
= 1; /* cleared if something actually found */
611 /* check the instructions for some constant value in at least one of
613 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
615 insn_word_entry
*word
= entry
->insn
->word
[rule
->word_nr
];
616 insn_bit_entry
*bit
= word
->bit
[bit_nr
];
617 switch (bit
->field
->type
)
619 case insn_field_invalid
:
622 case insn_field_wild
:
623 case insn_field_reserved
:
624 /* neither useless or useful - ignore */
627 switch (rule
->search
)
629 case decode_find_strings
:
630 /* an integer isn't a string */
632 case decode_find_constants
:
633 case decode_find_mixed
:
634 /* an integer is useful if its value isn't the same
635 between all instructions. The first time through the
636 value is saved, the second time through (if the
637 values differ) it is marked as useful. */
640 else if (value
!= bit
->value
)
645 case insn_field_string
:
646 switch (rule
->search
)
648 case decode_find_strings
:
649 /* at least one string, keep checking */
652 case decode_find_constants
:
653 case decode_find_mixed
:
654 if (filter_is_member (rule
->constant_field_names
,
655 bit
->field
->val_string
))
656 /* a string field forced to constant? */
658 else if (rule
->search
== decode_find_constants
)
659 /* the string field isn't constant */
666 /* Given only one constant value has been found, check through all
667 the instructions to see if at least one conditional makes it
669 if (value
>= 0 && is_useless
)
671 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
673 insn_word_entry
*word
= entry
->insn
->word
[rule
->word_nr
];
674 insn_bit_entry
*bit
= word
->bit
[bit_nr
];
675 switch (bit
->field
->type
)
677 case insn_field_invalid
:
680 case insn_field_wild
:
681 case insn_field_reserved
:
683 /* already processed */
685 case insn_field_string
:
686 switch (rule
->search
)
688 case decode_find_strings
:
689 case decode_find_constants
:
690 /* already processed */
692 case decode_find_mixed
:
693 /* string field with conditions. If this condition
694 eliminates the value then the compare is useful */
695 if (bit
->field
->conditions
!= NULL
)
697 insn_field_cond
*condition
;
698 int shift
= bit
->field
->last
- bit_nr
;
699 for (condition
= bit
->field
->conditions
;
700 condition
!= NULL
; condition
= condition
->next
)
702 switch (condition
->type
)
704 case insn_field_cond_value
:
705 switch (condition
->test
)
707 case insn_field_cond_ne
:
708 if (((condition
->value
>> shift
) & 1)
710 /* conditional field excludes the
714 case insn_field_cond_eq
:
715 if (((condition
->value
>> shift
) & 1)
717 /* conditional field requires the
723 case insn_field_cond_field
:
724 /* are these handled separatly? */
738 /* go through a gen-table's list of instruction formats looking for a
739 range of bits that meet the decode table RULEs requirements */
741 static opcode_field
*
742 gen_entry_find_opcode_field (insn_list
*insns
,
743 decode_table
*rule
, int string_only
)
745 opcode_field curr_opcode
;
746 ASSERT (rule
!= NULL
);
748 memset (&curr_opcode
, 0, sizeof (curr_opcode
));
749 curr_opcode
.word_nr
= rule
->word_nr
;
750 curr_opcode
.first
= rule
->first
;
751 curr_opcode
.last
= rule
->last
;
753 /* Try to reduce the size of first..last in accordance with the
756 while (curr_opcode
.first
<= rule
->last
)
758 if (insns_bit_useless (insns
, rule
, curr_opcode
.first
))
763 while (curr_opcode
.last
>= rule
->first
)
765 if (insns_bit_useless (insns
, rule
, curr_opcode
.last
))
773 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
)
775 insn_word_entry
*fields
= entry
->insn
->word
[rule
->word_nr
];
776 opcode_field new_opcode
;
778 ASSERT (fields
!= NULL
);
780 /* find a start point for the opcode field */
781 new_opcode
.first
= rule
->first
;
782 while (new_opcode
.first
<= rule
->last
785 (insn_field_is_constant (fields
->bit
[new_opcode
.first
], rule
)
786 != field_constant_string
)) && (string_only
788 (insn_field_is_constant
790 bit
[new_opcode
.first
],
792 field_is_not_constant
)))
794 int new_first
= fields
->bit
[new_opcode
.first
]->last
+ 1;
795 ASSERT (new_first
> new_opcode
.first
);
796 new_opcode
.first
= new_first
;
798 ASSERT (new_opcode
.first
> rule
->last
800 && insn_field_is_constant (fields
->bit
[new_opcode
.first
],
801 rule
) == field_constant_string
)
803 && insn_field_is_constant (fields
->bit
[new_opcode
.first
],
806 /* find the end point for the opcode field */
807 new_opcode
.last
= rule
->last
;
808 while (new_opcode
.last
>= rule
->first
810 || insn_field_is_constant (fields
->bit
[new_opcode
.last
],
811 rule
) != field_constant_string
)
813 || !insn_field_is_constant (fields
->bit
[new_opcode
.last
],
816 int new_last
= fields
->bit
[new_opcode
.last
]->first
- 1;
817 ASSERT (new_last
< new_opcode
.last
);
818 new_opcode
.last
= new_last
;
820 ASSERT (new_opcode
.last
< rule
->first
822 && insn_field_is_constant (fields
->bit
[new_opcode
.last
],
823 rule
) == field_constant_string
)
825 && insn_field_is_constant (fields
->bit
[new_opcode
.last
],
828 /* now see if our current opcode needs expanding to include the
829 interesting fields within this instruction */
830 if (new_opcode
.first
<= rule
->last
831 && curr_opcode
.first
> new_opcode
.first
)
832 curr_opcode
.first
= new_opcode
.first
;
833 if (new_opcode
.last
>= rule
->first
834 && curr_opcode
.last
< new_opcode
.last
)
835 curr_opcode
.last
= new_opcode
.last
;
840 /* did the final opcode field end up being empty? */
841 if (curr_opcode
.first
> curr_opcode
.last
)
845 ASSERT (curr_opcode
.last
>= rule
->first
);
846 ASSERT (curr_opcode
.first
<= rule
->last
);
847 ASSERT (curr_opcode
.first
<= curr_opcode
.last
);
849 /* Ensure that, for the non string only case, the opcode includes
850 the range forced_first .. forced_last */
851 if (!string_only
&& curr_opcode
.first
> rule
->force_first
)
853 curr_opcode
.first
= rule
->force_first
;
855 if (!string_only
&& curr_opcode
.last
< rule
->force_last
)
857 curr_opcode
.last
= rule
->force_last
;
860 /* For the string only case, force just the lower bound (so that the
861 shift can be eliminated) */
862 if (string_only
&& rule
->force_last
== options
.insn_bit_size
- 1)
864 curr_opcode
.last
= options
.insn_bit_size
- 1;
867 /* handle any special cases */
870 case normal_decode_rule
:
871 /* let the above apply */
872 curr_opcode
.nr_opcodes
=
873 (1 << (curr_opcode
.last
- curr_opcode
.first
+ 1));
876 curr_opcode
.is_boolean
= 1;
877 curr_opcode
.boolean_constant
= rule
->constant
;
878 curr_opcode
.nr_opcodes
= 2;
883 opcode_field
*new_field
= ZALLOC (opcode_field
);
884 memcpy (new_field
, &curr_opcode
, sizeof (opcode_field
));
891 gen_entry_insert_insn (gen_entry
*table
,
892 insn_entry
* old_insn
,
894 int new_nr_prefetched_words
,
895 int new_opcode_nr
, opcode_bits
*new_bits
)
897 gen_entry
**entry
= &table
->entries
;
899 /* find the new table for this entry */
900 while ((*entry
) != NULL
&& (*entry
)->opcode_nr
< new_opcode_nr
)
902 entry
= &(*entry
)->sibling
;
905 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= new_opcode_nr
)
907 /* insert the missing entry */
908 gen_entry
*new_entry
= ZALLOC (gen_entry
);
909 new_entry
->sibling
= (*entry
);
910 (*entry
) = new_entry
;
913 new_entry
->top
= table
->top
;
914 new_entry
->opcode_nr
= new_opcode_nr
;
915 new_entry
->word_nr
= new_word_nr
;
916 new_entry
->expanded_bits
= new_bits
;
917 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
918 new_entry
->parent
= table
;
919 new_entry
->nr_prefetched_words
= new_nr_prefetched_words
;
921 /* ASSERT new_bits == cur_entry bits */
922 ASSERT ((*entry
) != NULL
&& (*entry
)->opcode_nr
== new_opcode_nr
);
923 insn_list_insert (&(*entry
)->insns
, &(*entry
)->nr_insns
, old_insn
, NULL
, /* expanded_bits - only in final list */
924 NULL
, /* opcodes - only in final list */
925 new_nr_prefetched_words
, /* for this table */
926 report_duplicate_insns
);
931 gen_entry_expand_opcode (gen_entry
*table
,
932 insn_entry
* instruction
,
933 int bit_nr
, int opcode_nr
, opcode_bits
*bits
)
935 if (bit_nr
> table
->opcode
->last
)
937 /* Only include the hardwired bit information with an entry IF
938 that entry (and hence its functions) are being duplicated. */
939 if (options
.trace
.insn_expansion
)
941 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
942 notify (NULL
, ": insert %d - %s.%s%s\n",
944 instruction
->format_name
,
946 (table
->opcode_rule
->
947 with_duplicates
? " (duplicated)" : ""));
949 if (table
->opcode_rule
->with_duplicates
)
951 gen_entry_insert_insn (table
, instruction
,
952 table
->opcode
->word_nr
,
953 table
->nr_prefetched_words
, opcode_nr
, bits
);
957 gen_entry_insert_insn (table
, instruction
,
958 table
->opcode
->word_nr
,
959 table
->nr_prefetched_words
, opcode_nr
, NULL
);
964 insn_word_entry
*word
= instruction
->word
[table
->opcode
->word_nr
];
965 insn_field_entry
*field
= word
->bit
[bit_nr
]->field
;
966 int last_pos
= ((field
->last
< table
->opcode
->last
)
967 ? field
->last
: table
->opcode
->last
);
968 int first_pos
= ((field
->first
> table
->opcode
->first
)
969 ? field
->first
: table
->opcode
->first
);
970 int width
= last_pos
- first_pos
+ 1;
976 val
= sub_val (field
->val_int
, field
->last
, first_pos
, last_pos
);
977 gen_entry_expand_opcode (table
, instruction
,
979 ((opcode_nr
<< width
) | val
), bits
);
984 if (field
->type
== insn_field_reserved
)
985 gen_entry_expand_opcode (table
, instruction
,
987 ((opcode_nr
<< width
)), bits
);
991 int last_val
= (table
->opcode
->is_boolean
? 2 : (1 << width
));
992 for (val
= 0; val
< last_val
; val
++)
994 /* check to see if the value has been precluded
995 (by a conditional) in some way */
997 insn_field_cond
*condition
;
998 for (condition
= field
->conditions
, is_precluded
= 0;
999 condition
!= NULL
&& !is_precluded
;
1000 condition
= condition
->next
)
1002 switch (condition
->type
)
1004 case insn_field_cond_value
:
1007 sub_val (condition
->value
, field
->last
,
1008 first_pos
, last_pos
);
1009 switch (condition
->test
)
1011 case insn_field_cond_ne
:
1015 case insn_field_cond_eq
:
1022 case insn_field_cond_field
:
1026 gen_entry
*t
= NULL
;
1027 /* Try to find a value for the
1028 conditional by looking back through
1029 the previously defined bits for one
1030 that covers the designated
1031 conditional field */
1032 for (bit
= bits
; bit
!= NULL
; bit
= bit
->next
)
1034 if (bit
->field
->word_nr
==
1035 condition
->field
->word_nr
1036 && bit
->first
<= condition
->field
->first
1037 && bit
->last
>= condition
->field
->last
)
1039 /* the bit field fully specified
1040 the conditional field's value */
1041 value
= sub_val (bit
->value
, bit
->last
,
1048 /* Try to find a value by looking
1049 through this and previous tables */
1053 t
->parent
!= NULL
; t
= t
->parent
)
1055 if (t
->parent
->opcode
->word_nr
==
1056 condition
->field
->word_nr
1057 && t
->parent
->opcode
->first
<=
1058 condition
->field
->first
1059 && t
->parent
->opcode
->last
>=
1060 condition
->field
->last
)
1062 /* the table entry fully
1063 specified the condition
1065 /* extract the field's value
1068 sub_val (t
->opcode_nr
,
1069 t
->parent
->opcode
->last
,
1070 condition
->field
->first
,
1071 condition
->field
->last
);
1072 /* this is a requirement of
1074 refering to another field */
1075 ASSERT ((condition
->field
->first
-
1076 condition
->field
->last
) ==
1077 (first_pos
- last_pos
));
1079 ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n",
1080 value
, t
->opcode_nr
,
1081 t
->parent
->opcode
->last
,
1082 condition
->field
->first
,
1083 condition
->field
->last
);
1087 if (bit
== NULL
&& t
== NULL
)
1088 error (instruction
->line
,
1089 "Conditional `%s' of field `%s' isn't expanded",
1090 condition
->string
, field
->val_string
);
1091 switch (condition
->test
)
1093 case insn_field_cond_ne
:
1097 case insn_field_cond_eq
:
1108 /* Only add additional hardwired bit
1109 information if the entry is not going to
1110 later be combined */
1111 if (table
->opcode_rule
->with_combine
)
1113 gen_entry_expand_opcode (table
, instruction
,
1115 ((opcode_nr
<< width
) |
1120 opcode_bits
*new_bits
=
1121 new_opcode_bits (bits
, val
,
1122 first_pos
, last_pos
,
1125 gen_entry_expand_opcode (table
, instruction
,
1127 ((opcode_nr
<< width
) |
1139 gen_entry_insert_expanding (gen_entry
*table
, insn_entry
* instruction
)
1141 gen_entry_expand_opcode (table
,
1143 table
->opcode
->first
, 0, table
->expanded_bits
);
1148 insns_match_format_names (insn_list
*insns
, filter
*format_names
)
1150 if (format_names
!= NULL
)
1153 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1155 if (i
->insn
->format_name
!= NULL
1156 && !filter_is_member (format_names
, i
->insn
->format_name
))
1164 table_matches_path (gen_entry
*table
, decode_path_list
*paths
)
1168 while (paths
!= NULL
)
1170 gen_entry
*entry
= table
;
1171 decode_path
*path
= paths
->path
;
1174 if (entry
== NULL
&& path
== NULL
)
1176 if (entry
== NULL
|| path
== NULL
)
1178 if (entry
->opcode_nr
!= path
->opcode_nr
)
1180 entry
= entry
->parent
;
1181 path
= path
->parent
;
1183 paths
= paths
->next
;
1190 insns_match_conditions (insn_list
*insns
, decode_cond
*conditions
)
1192 if (conditions
!= NULL
)
1195 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1198 for (cond
= conditions
; cond
!= NULL
; cond
= cond
->next
)
1201 if (i
->insn
->nr_words
<= cond
->word_nr
)
1203 for (bit_nr
= 0; bit_nr
< options
.insn_bit_size
; bit_nr
++)
1205 if (!cond
->mask
[bit_nr
])
1207 if (!i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->mask
)
1209 if ((i
->insn
->word
[cond
->word_nr
]->bit
[bit_nr
]->value
1210 == cond
->value
[bit_nr
]) == !cond
->is_equal
)
1220 insns_match_nr_words (insn_list
*insns
, int nr_words
)
1223 for (i
= insns
; i
!= NULL
; i
= i
->next
)
1225 if (i
->insn
->nr_words
< nr_words
)
1232 insn_list_cmp (insn_list
*l
, insn_list
*r
)
1237 if (l
== NULL
&& r
== NULL
)
1243 if (l
->insn
!= r
->insn
)
1244 return -1; /* somewhat arbitrary at present */
1245 /* skip this insn */
1247 while (l
!= NULL
&& l
->insn
== insn
)
1249 while (r
!= NULL
&& r
->insn
== insn
)
1257 gen_entry_expand_insns (gen_entry
*table
)
1259 decode_table
*opcode_rule
;
1261 ASSERT (table
->nr_insns
>= 1);
1263 /* determine a valid opcode */
1264 for (opcode_rule
= table
->opcode_rule
;
1265 opcode_rule
!= NULL
; opcode_rule
= opcode_rule
->next
)
1267 char *discard_reason
;
1268 if (table
->top
->model
!= NULL
1269 && opcode_rule
->model_names
!= NULL
1270 && !filter_is_member (opcode_rule
->model_names
,
1271 table
->top
->model
->name
))
1273 /* the rule isn't applicable to this processor */
1274 discard_reason
= "wrong model";
1276 else if (table
->nr_insns
== 1 && opcode_rule
->conditions
== NULL
)
1278 /* for safety, require a pre-codition when attempting to
1279 apply a rule to a single instruction */
1280 discard_reason
= "need pre-condition when nr-insn == 1";
1282 else if (table
->nr_insns
== 1 && !opcode_rule
->with_duplicates
)
1284 /* Little point in expanding a single instruction when we're
1285 not duplicating the semantic functions that this table
1287 discard_reason
= "need duplication with nr-insns == 1";
1290 if (!insns_match_format_names
1291 (table
->insns
, opcode_rule
->format_names
))
1293 discard_reason
= "wrong format name";
1295 else if (!insns_match_nr_words (table
->insns
, opcode_rule
->word_nr
+ 1))
1297 discard_reason
= "wrong nr words";
1299 else if (!table_matches_path (table
, opcode_rule
->paths
))
1301 discard_reason
= "path failed";
1304 if (!insns_match_conditions (table
->insns
, opcode_rule
->conditions
))
1306 discard_reason
= "condition failed";
1310 discard_reason
= "no opcode field";
1311 table
->opcode
= gen_entry_find_opcode_field (table
->insns
,
1313 table
->nr_insns
== 1 /*string-only */
1315 if (table
->opcode
!= NULL
)
1317 table
->opcode_rule
= opcode_rule
;
1322 if (options
.trace
.rule_rejection
)
1324 print_gen_entry_path (opcode_rule
->line
, table
, notify
);
1325 notify (NULL
, ": rule discarded - %s\n", discard_reason
);
1329 /* did we find anything */
1330 if (opcode_rule
== NULL
)
1332 /* the decode table failed, this set of instructions haven't
1333 been uniquely identified */
1334 if (table
->nr_insns
> 1)
1336 print_gen_entry_insns (table
, warning
,
1337 "was not uniquely decoded",
1338 "decodes to the same entry");
1344 /* Determine the number of words that must have been prefetched for
1345 this table to function */
1346 if (table
->parent
== NULL
)
1347 table
->nr_prefetched_words
= table
->opcode_rule
->word_nr
+ 1;
1348 else if (table
->opcode_rule
->word_nr
+ 1 >
1349 table
->parent
->nr_prefetched_words
)
1350 table
->nr_prefetched_words
= table
->opcode_rule
->word_nr
+ 1;
1352 table
->nr_prefetched_words
= table
->parent
->nr_prefetched_words
;
1354 /* back link what we found to its parent */
1355 if (table
->parent
!= NULL
)
1357 ASSERT (table
->parent
->opcode
!= NULL
);
1358 table
->opcode
->parent
= table
->parent
->opcode
;
1361 /* report the rule being used to expand the instructions */
1362 if (options
.trace
.rule_selection
)
1364 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1366 ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n",
1367 table
->opcode
->word_nr
,
1368 i2target (options
.hi_bit_nr
, table
->opcode
->first
),
1369 i2target (options
.hi_bit_nr
, table
->opcode
->last
),
1370 i2target (options
.hi_bit_nr
, table
->opcode_rule
->first
),
1371 i2target (options
.hi_bit_nr
, table
->opcode_rule
->last
),
1372 table
->opcode
->nr_opcodes
, table
->nr_entries
);
1375 /* expand the raw instructions according to the opcode */
1378 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
)
1380 if (options
.trace
.insn_expansion
)
1382 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1383 notify (NULL
, ": expand - %s.%s\n",
1384 entry
->insn
->format_name
, entry
->insn
->name
);
1386 gen_entry_insert_expanding (table
, entry
->insn
);
1390 /* dump the results */
1391 if (options
.trace
.entries
)
1394 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1397 print_gen_entry_path (table
->opcode_rule
->line
, entry
, notify
);
1398 notify (NULL
, ": %d - entries %d -",
1399 entry
->opcode_nr
, entry
->nr_insns
);
1400 for (l
= entry
->insns
; l
!= NULL
; l
= l
->next
)
1401 notify (NULL
, " %s.%s", l
->insn
->format_name
, l
->insn
->name
);
1402 notify (NULL
, "\n");
1406 /* perform a combine pass if needed */
1407 if (table
->opcode_rule
->with_combine
)
1410 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1412 if (entry
->combined_parent
== NULL
)
1414 gen_entry
**last
= &entry
->combined_next
;
1416 for (alt
= entry
->sibling
; alt
!= NULL
; alt
= alt
->sibling
)
1418 if (alt
->combined_parent
== NULL
1419 && insn_list_cmp (entry
->insns
, alt
->insns
) == 0)
1421 alt
->combined_parent
= entry
;
1423 last
= &alt
->combined_next
;
1428 if (options
.trace
.combine
)
1432 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1434 if (entry
->combined_parent
== NULL
)
1437 gen_entry
*duplicate
;
1439 print_gen_entry_path (table
->opcode_rule
->line
, entry
,
1441 for (duplicate
= entry
->combined_next
; duplicate
!= NULL
;
1442 duplicate
= duplicate
->combined_next
)
1444 notify (NULL
, "+%d", duplicate
->opcode_nr
);
1446 notify (NULL
, ": entries %d -", entry
->nr_insns
);
1447 for (l
= entry
->insns
; l
!= NULL
; l
= l
->next
)
1449 notify (NULL
, " %s.%s",
1450 l
->insn
->format_name
, l
->insn
->name
);
1452 notify (NULL
, "\n");
1455 print_gen_entry_path (table
->opcode_rule
->line
, table
, notify
);
1457 ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n",
1458 table
->opcode
->word_nr
, i2target (options
.hi_bit_nr
,
1459 table
->opcode
->first
),
1460 i2target (options
.hi_bit_nr
, table
->opcode
->last
),
1461 i2target (options
.hi_bit_nr
, table
->opcode_rule
->first
),
1462 i2target (options
.hi_bit_nr
, table
->opcode_rule
->last
),
1463 table
->opcode
->nr_opcodes
, table
->nr_entries
, nr_unique
);
1467 /* Check that the rule did more than re-arange the order of the
1471 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1473 if (entry
->combined_parent
== NULL
)
1475 if (insn_list_cmp (table
->insns
, entry
->insns
) == 0)
1477 print_gen_entry_path (table
->opcode_rule
->line
, table
,
1480 ": Applying rule just copied all instructions\n");
1481 print_gen_entry_insns (entry
, warning
, "Copied", NULL
);
1488 /* if some form of expanded table, fill in the missing dots */
1489 switch (table
->opcode_rule
->gen
)
1491 case padded_switch_gen
:
1493 case goto_switch_gen
:
1494 if (!table
->opcode
->is_boolean
)
1496 gen_entry
**entry
= &table
->entries
;
1497 gen_entry
*illegals
= NULL
;
1498 gen_entry
**last_illegal
= &illegals
;
1500 while (opcode_nr
< table
->opcode
->nr_opcodes
)
1502 if ((*entry
) == NULL
|| (*entry
)->opcode_nr
!= opcode_nr
)
1504 /* missing - insert it under our feet at *entry */
1505 gen_entry_insert_insn (table
, table
->top
->isa
->illegal_insn
, table
->opcode
->word_nr
, 0, /* nr_prefetched_words == 0 for invalid */
1507 ASSERT ((*entry
) != NULL
);
1508 ASSERT ((*entry
)->opcode_nr
== opcode_nr
);
1509 (*last_illegal
) = *entry
;
1510 (*last_illegal
)->combined_parent
= illegals
;
1511 last_illegal
= &(*last_illegal
)->combined_next
;
1513 entry
= &(*entry
)->sibling
;
1516 /* oops, will have pointed the first illegal insn back to
1517 its self. Fix this */
1518 if (illegals
!= NULL
)
1519 illegals
->combined_parent
= NULL
;
1528 /* and do the same for the newly created sub entries but *only*
1529 expand entries that haven't been combined. */
1532 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
)
1534 if (entry
->combined_parent
== NULL
)
1536 gen_entry_expand_insns (entry
);
1543 gen_tables_expand_insns (gen_table
*gen
)
1546 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1548 gen_entry_expand_insns (entry
->table
);
1553 /* create a list of all the semantic functions that need to be
1554 generated. Eliminate any duplicates. Verify that the decode stage
1558 make_gen_semantics_list (lf
*file
, gen_entry
*entry
, int depth
, void *data
)
1560 gen_table
*gen
= (gen_table
*) data
;
1562 /* Not interested in an entrie that have been combined into some
1563 other entry at the same level */
1564 if (entry
->combined_parent
!= NULL
)
1567 /* a leaf should contain exactly one instruction. If not the decode
1569 ASSERT (entry
->nr_insns
== 1);
1571 /* Enter this instruction into the list of semantic functions. */
1572 insn
= insn_list_insert (&gen
->semantics
, &gen
->nr_semantics
,
1574 entry
->expanded_bits
,
1575 entry
->parent
->opcode
,
1576 entry
->insns
->nr_prefetched_words
,
1577 merge_duplicate_insns
);
1578 /* point the table entry at the real semantic function */
1579 ASSERT (insn
!= NULL
);
1580 entry
->insns
->semantic
= insn
;
1585 gen_tables_expand_semantics (gen_table
*gen
)
1588 for (entry
= gen
->tables
; entry
!= NULL
; entry
= entry
->next
)
1590 gen_entry_traverse_tree (NULL
, entry
->table
, 1, /* depth */
1591 NULL
, /* start-handler */
1592 make_gen_semantics_list
, /* leaf-handler */
1593 NULL
, /* end-handler */
1604 dump_opcode_field (lf
*file
,
1606 opcode_field
*field
, char *suffix
, int levels
)
1608 lf_printf (file
, "%s(opcode_field *) 0x%lx", prefix
, (long) field
);
1609 if (levels
&& field
!= NULL
)
1611 lf_indent (file
, +1);
1612 lf_printf (file
, "\n(first %d)", field
->first
);
1613 lf_printf (file
, "\n(last %d)", field
->last
);
1614 lf_printf (file
, "\n(nr_opcodes %d)", field
->nr_opcodes
);
1615 lf_printf (file
, "\n(is_boolean %d)", field
->is_boolean
);
1616 lf_printf (file
, "\n(boolean_constant %d)", field
->boolean_constant
);
1617 dump_opcode_field (file
, "\n(parent ", field
->parent
, ")", levels
- 1);
1618 lf_indent (file
, -1);
1620 lf_printf (file
, "%s", suffix
);
1625 dump_opcode_bits (lf
*file
,
1626 char *prefix
, opcode_bits
*bits
, char *suffix
, int levels
)
1628 lf_printf (file
, "%s(opcode_bits *) 0x%lx", prefix
, (long) bits
);
1630 if (levels
&& bits
!= NULL
)
1632 lf_indent (file
, +1);
1633 lf_printf (file
, "\n(value %d)", bits
->value
);
1634 dump_opcode_field (file
, "\n(opcode ", bits
->opcode
, ")", 0);
1635 dump_insn_field (file
, "\n(field ", bits
->field
, ")");
1636 dump_opcode_bits (file
, "\n(next ", bits
->next
, ")", levels
- 1);
1637 lf_indent (file
, -1);
1639 lf_printf (file
, "%s", suffix
);
1645 dump_insn_list (lf
*file
, char *prefix
, insn_list
*entry
, char *suffix
)
1647 lf_printf (file
, "%s(insn_list *) 0x%lx", prefix
, (long) entry
);
1651 lf_indent (file
, +1);
1652 dump_insn_entry (file
, "\n(insn ", entry
->insn
, ")");
1653 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1654 lf_indent (file
, -1);
1656 lf_printf (file
, "%s", suffix
);
1661 dump_insn_word_entry_list_entries (lf
*file
,
1663 insn_list
*entry
, char *suffix
)
1665 lf_printf (file
, "%s", prefix
);
1666 while (entry
!= NULL
)
1668 dump_insn_list (file
, "\n(", entry
, ")");
1669 entry
= entry
->next
;
1671 lf_printf (file
, "%s", suffix
);
1676 dump_gen_entry (lf
*file
,
1677 char *prefix
, gen_entry
*table
, char *suffix
, int levels
)
1680 lf_printf (file
, "%s(gen_entry *) 0x%lx", prefix
, (long) table
);
1682 if (levels
&& table
!=NULL
)
1685 lf_indent (file
, +1);
1686 lf_printf (file
, "\n(opcode_nr %d)", table
->opcode_nr
);
1687 lf_printf (file
, "\n(word_nr %d)", table
->word_nr
);
1688 dump_opcode_bits (file
, "\n(expanded_bits ", table
->expanded_bits
, ")",
1690 lf_printf (file
, "\n(nr_insns %d)", table
->nr_insns
);
1691 dump_insn_word_entry_list_entries (file
, "\n(insns ", table
->insns
,
1693 dump_decode_rule (file
, "\n(opcode_rule ", table
->opcode_rule
, ")");
1694 dump_opcode_field (file
, "\n(opcode ", table
->opcode
, ")", 0);
1695 lf_printf (file
, "\n(nr_entries %d)", table
->nr_entries
);
1696 dump_gen_entry (file
, "\n(entries ", table
->entries
, ")",
1698 dump_gen_entry (file
, "\n(sibling ", table
->sibling
, ")", levels
- 1);
1699 dump_gen_entry (file
, "\n(parent ", table
->parent
, ")", 0);
1700 lf_indent (file
, -1);
1702 lf_printf (file
, "%s", suffix
);
1706 dump_gen_list (lf
*file
,
1707 char *prefix
, gen_list
*entry
, char *suffix
, int levels
)
1709 while (entry
!= NULL
)
1711 lf_printf (file
, "%s(gen_list *) 0x%lx", prefix
, (long) entry
);
1712 dump_gen_entry (file
, "\n(", entry
->table
, ")", levels
);
1713 lf_printf (file
, "\n(next (gen_list *) 0x%lx)", (long) entry
->next
);
1714 lf_printf (file
, "%s", suffix
);
1720 dump_gen_table (lf
*file
,
1721 char *prefix
, gen_table
*gen
, char *suffix
, int levels
)
1723 lf_printf (file
, "%s(gen_table *) 0x%lx", prefix
, (long) gen
);
1724 lf_printf (file
, "\n(isa (insn_table *) 0x%lx)", (long) gen
->isa
);
1725 lf_printf (file
, "\n(rules (decode_table *) 0x%lx)", (long) gen
->rules
);
1726 dump_gen_list (file
, "\n(", gen
->tables
, ")", levels
);
1727 lf_printf (file
, "%s", suffix
);
1731 igen_options options
;
1734 main (int argc
, char **argv
)
1736 decode_table
*decode_rules
;
1737 insn_table
*instructions
;
1743 "Usage: insn <filter-in> <hi-bit-nr> <insn-bit-size> <widths> <decode-table> <insn-table>\n");
1745 INIT_OPTIONS (options
);
1747 filter_parse (&options
.flags_filter
, argv
[1]);
1749 options
.hi_bit_nr
= a2i (argv
[2]);
1750 options
.insn_bit_size
= a2i (argv
[3]);
1751 options
.insn_specifying_widths
= a2i (argv
[4]);
1752 ASSERT (options
.hi_bit_nr
< options
.insn_bit_size
);
1754 instructions
= load_insn_table (argv
[6], NULL
);
1755 decode_rules
= load_decode_table (argv
[5]);
1756 gen
= make_gen_tables (instructions
, decode_rules
);
1758 gen_tables_expand_insns (gen
);
1760 l
= lf_open ("-", "stdout", lf_omit_references
, lf_is_text
, "tmp-ld-insn");
1762 dump_gen_table (l
, "(", gen
, ")\n", -1);