1 /* This file is part of the program psim.
3 Copyright 1994, 1995, 1996, 2003 Andrew Cagney
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 3 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, see <http://www.gnu.org/licenses/>.
25 #include "ld-decode.h"
32 update_depth(insn_table
*entry
,
38 int *max_depth
= (int*)data
;
39 if (*max_depth
< depth
)
45 insn_table_depth(insn_table
*table
)
48 insn_table_traverse_tree(table
,
61 parse_insn_format(table_entry
*entry
,
65 insn_fields
*fields
= ZALLOC(insn_fields
);
67 /* create a leading sentinal */
68 fields
->first
= ZALLOC(insn_field
);
69 fields
->first
->first
= -1;
70 fields
->first
->last
= -1;
71 fields
->first
->width
= 0;
73 /* and a trailing sentinal */
74 fields
->last
= ZALLOC(insn_field
);
75 fields
->last
->first
= insn_bit_size
;
76 fields
->last
->last
= insn_bit_size
;
77 fields
->last
->width
= 0;
79 /* link them together */
80 fields
->first
->next
= fields
->last
;
81 fields
->last
->prev
= fields
->first
;
83 /* now work through the formats */
86 while (*chp
!= '\0') {
91 insn_field
*new_field
;
95 error("%s:%d: missing position field at `%s'\n",
96 entry
->file_name
, entry
->line_nr
, chp
);
99 /* break out the bit position */
101 while (isdigit(*chp
))
103 strlen_pos
= chp
- start_pos
;
104 if (*chp
== '.' && strlen_pos
> 0)
107 error("%s:%d: missing field value at %s\n",
108 entry
->file_name
, entry
->line_nr
, chp
);
112 /* break out the value */
114 while ((*start_val
== '/' && *chp
== '/')
115 || (isdigit(*start_val
) && isdigit(*chp
))
116 || (isalpha(*start_val
) && (isalnum(*chp
) || *chp
== '_')))
118 strlen_val
= chp
- start_val
;
121 else if (*chp
!= '\0' || strlen_val
== 0) {
122 error("%s:%d: missing field terminator at %s\n",
123 entry
->file_name
, entry
->line_nr
, chp
);
127 /* create a new field and insert it */
128 new_field
= ZALLOC(insn_field
);
129 new_field
->next
= fields
->last
;
130 new_field
->prev
= fields
->last
->prev
;
131 new_field
->next
->prev
= new_field
;
132 new_field
->prev
->next
= new_field
;
135 new_field
->val_string
= (char*)zalloc(strlen_val
+1);
136 strncpy(new_field
->val_string
, start_val
, strlen_val
);
137 if (isdigit(*new_field
->val_string
)) {
138 new_field
->val_int
= a2i(new_field
->val_string
);
139 new_field
->is_int
= 1;
141 else if (new_field
->val_string
[0] == '/') {
142 new_field
->is_slash
= 1;
145 new_field
->is_string
= 1;
149 new_field
->pos_string
= (char*)zalloc(strlen_pos
+1);
150 strncpy(new_field
->pos_string
, start_pos
, strlen_pos
);
151 new_field
->first
= target_a2i(hi_bit_nr
, new_field
->pos_string
);
152 new_field
->last
= new_field
->next
->first
- 1; /* guess */
153 new_field
->width
= new_field
->last
- new_field
->first
+ 1; /* guess */
154 new_field
->prev
->last
= new_field
->first
-1; /*fix*/
155 new_field
->prev
->width
= new_field
->first
- new_field
->prev
->first
; /*fix*/
158 /* fiddle first/last so that the sentinals `disapear' */
159 ASSERT(fields
->first
->last
< 0);
160 ASSERT(fields
->last
->first
>= insn_bit_size
);
161 fields
->first
= fields
->first
->next
;
162 fields
->last
= fields
->last
->prev
;
164 /* now go over this again, pointing each bit position at a field
169 field
= fields
->first
;
170 for (i
= 0; i
< insn_bit_size
; i
++) {
171 while (field
->last
< i
)
173 fields
->bits
[i
] = field
;
177 /* go over each of the fields, and compute a `value' for the insn */
181 for (field
= fields
->first
;
182 field
->last
< insn_bit_size
;
183 field
= field
->next
) {
184 fields
->value
<<= field
->width
;
186 fields
->value
|= field
->val_int
;
194 parse_include_entry (table
*file
,
195 table_entry
*file_entry
,
197 table_include
*includes
)
199 /* parse the include file_entry */
200 if (file_entry
->nr_fields
< 4)
201 error ("Incorrect nr fields for include record\n");
203 if (!is_filtered_out(file_entry
->fields
[include_flags
], filters
))
205 table_push (file
, includes
,
206 file_entry
->fields
[include_path
],
207 file_entry
->nr_fields
, file_entry
->nr_fields
);
212 model_table_insert(insn_table
*table
,
213 table_entry
*file_entry
)
217 /* create a new model */
218 model
*new_model
= ZALLOC(model
);
220 new_model
->name
= file_entry
->fields
[model_identifer
];
221 new_model
->printable_name
= file_entry
->fields
[model_name
];
222 new_model
->insn_default
= file_entry
->fields
[model_default
];
224 while (*new_model
->insn_default
&& isspace(*new_model
->insn_default
))
225 new_model
->insn_default
++;
227 len
= strlen(new_model
->insn_default
);
228 if (max_model_fields_len
< len
)
229 max_model_fields_len
= len
;
231 /* append it to the end of the model list */
233 last_model
->next
= new_model
;
236 last_model
= new_model
;
240 model_table_insert_specific(insn_table
*table
,
241 table_entry
*file_entry
,
245 insn
*ptr
= ZALLOC(insn
);
246 ptr
->file_entry
= file_entry
;
248 (*end_ptr
)->next
= ptr
;
256 insn_table_insert_function(insn_table
*table
,
257 table_entry
*file_entry
)
259 /* create a new function */
260 insn
*new_function
= ZALLOC(insn
);
261 new_function
->file_entry
= file_entry
;
263 /* append it to the end of the function list */
264 if (table
->last_function
)
265 table
->last_function
->next
= new_function
;
267 table
->functions
= new_function
;
268 table
->last_function
= new_function
;
272 insn_table_insert_insn(insn_table
*table
,
273 table_entry
*file_entry
,
276 insn
**ptr_to_cur_insn
= &table
->insns
;
277 insn
*cur_insn
= *ptr_to_cur_insn
;
278 table_model_entry
*insn_model_ptr
;
281 /* create a new instruction */
282 insn
*new_insn
= ZALLOC(insn
);
283 new_insn
->file_entry
= file_entry
;
284 new_insn
->fields
= fields
;
286 /* Check out any model information returned to make sure the model
288 for(insn_model_ptr
= file_entry
->model_first
; insn_model_ptr
; insn_model_ptr
= insn_model_ptr
->next
) {
289 char *name
= insn_model_ptr
->fields
[insn_model_name
];
290 int len
= strlen (insn_model_ptr
->fields
[insn_model_fields
]);
292 while (len
> 0 && isspace(*insn_model_ptr
->fields
[insn_model_fields
])) {
294 insn_model_ptr
->fields
[insn_model_fields
]++;
297 if (max_model_fields_len
< len
)
298 max_model_fields_len
= len
;
300 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
301 if (strcmp(name
, model_ptr
->printable_name
) == 0) {
303 /* Replace the name field with that of the global model, so that when we
304 want to print it out, we can just compare pointers. */
305 insn_model_ptr
->fields
[insn_model_name
] = model_ptr
->printable_name
;
311 error("%s:%d: machine model `%s' was not known about\n",
312 file_entry
->file_name
, file_entry
->line_nr
, name
);
315 /* insert it according to the order of the fields */
316 while (cur_insn
!= NULL
317 && new_insn
->fields
->value
>= cur_insn
->fields
->value
) {
318 ptr_to_cur_insn
= &cur_insn
->next
;
319 cur_insn
= *ptr_to_cur_insn
;
322 new_insn
->next
= cur_insn
;
323 *ptr_to_cur_insn
= new_insn
;
331 load_insn_table(const char *file_name
,
332 decode_table
*decode_rules
,
334 table_include
*includes
,
335 cache_table
**cache_rules
)
337 table
*file
= table_open(file_name
, nr_insn_table_fields
, nr_insn_model_table_fields
);
338 insn_table
*table
= ZALLOC(insn_table
);
339 table_entry
*file_entry
;
340 table
->opcode_rule
= decode_rules
;
342 while ((file_entry
= table_entry_read(file
)) != NULL
) {
343 if (it_is("function", file_entry
->fields
[insn_flags
])
344 || it_is("internal", file_entry
->fields
[insn_flags
])) {
345 insn_table_insert_function(table
, file_entry
);
347 else if ((it_is("function", file_entry
->fields
[insn_form
])
348 || it_is("internal", file_entry
->fields
[insn_form
]))
349 && !is_filtered_out(file_entry
->fields
[insn_flags
], filters
)) {
350 /* Ok, this is evil. Need to convert a new style function into
351 an old style function. Construct an old style table and then
353 char *fields
[nr_insn_table_fields
];
354 memset (fields
, 0, sizeof fields
);
355 fields
[insn_flags
] = file_entry
->fields
[insn_form
];
356 fields
[function_type
] = file_entry
->fields
[insn_name
];
357 fields
[function_name
] = file_entry
->fields
[insn_comment
];
358 fields
[function_param
] = file_entry
->fields
[insn_field_6
];
359 memcpy (file_entry
->fields
, fields
,
360 sizeof (fields
[0]) * file_entry
->nr_fields
);
361 insn_table_insert_function(table
, file_entry
);
368 [ ":" <parameter
-list
> ]
374 else if (it_is("model", file_entry
->fields
[insn_flags
])) {
375 model_table_insert(table
, file_entry
);
377 else if (it_is("model-macro", file_entry
->fields
[insn_flags
])) {
378 model_table_insert_specific(table
, file_entry
, &model_macros
, &last_model_macro
);
380 else if (it_is("model-function", file_entry
->fields
[insn_flags
])) {
381 model_table_insert_specific(table
, file_entry
, &model_functions
, &last_model_function
);
383 else if (it_is("model-internal", file_entry
->fields
[insn_flags
])) {
384 model_table_insert_specific(table
, file_entry
, &model_internal
, &last_model_internal
);
386 else if (it_is("model-static", file_entry
->fields
[insn_flags
])) {
387 model_table_insert_specific(table
, file_entry
, &model_static
, &last_model_static
);
389 else if (it_is("model-data", file_entry
->fields
[insn_flags
])) {
390 model_table_insert_specific(table
, file_entry
, &model_data
, &last_model_data
);
392 else if (it_is("include", file_entry
->fields
[insn_form
])
393 && !is_filtered_out(file_entry
->fields
[insn_flags
], filters
)) {
394 parse_include_entry (file
, file_entry
, filters
, includes
);
396 else if ((it_is("cache", file_entry
->fields
[insn_form
])
397 || it_is("compute", file_entry
->fields
[insn_form
])
398 || it_is("scratch", file_entry
->fields
[insn_form
]))
399 && !is_filtered_out(file_entry
->fields
[insn_flags
], filters
)) {
400 append_cache_rule (cache_rules
,
401 file_entry
->fields
[insn_form
], /* type */
402 file_entry
->fields
[cache_name
],
403 file_entry
->fields
[cache_derived_name
],
404 file_entry
->fields
[cache_type_def
],
405 file_entry
->fields
[cache_expression
],
410 /* skip instructions that aren't relevant to the mode */
411 if (is_filtered_out(file_entry
->fields
[insn_flags
], filters
)) {
412 fprintf(stderr
, "Dropping %s - %s\n",
413 file_entry
->fields
[insn_name
],
414 file_entry
->fields
[insn_flags
]);
417 /* create/insert the new instruction */
418 fields
= parse_insn_format(file_entry
,
419 file_entry
->fields
[insn_format
]);
420 insn_table_insert_insn(table
, file_entry
, fields
);
429 insn_table_traverse_tree(insn_table
*table
,
436 padding_handler
*padding
)
442 && table
->opcode
!= NULL
443 && table
->nr_entries
> 0
444 && table
->entries
!= 0);
446 if (start
!= NULL
&& depth
>= 0)
447 start(table
, file
, data
, depth
);
449 for (entry_nr
= 0, entry
= table
->entries
;
450 entry_nr
< (table
->opcode
->is_boolean
452 : (1 << (table
->opcode
->last
- table
->opcode
->first
+ 1)));
455 || (!table
->opcode
->is_boolean
456 && entry_nr
< entry
->opcode_nr
)) {
457 if (padding
!= NULL
&& depth
>= 0)
458 padding(table
, file
, data
, depth
, entry_nr
);
461 ASSERT(entry
!= NULL
&& (entry
->opcode_nr
== entry_nr
462 || table
->opcode
->is_boolean
));
463 if (entry
->opcode
!= NULL
&& depth
!= 0) {
464 insn_table_traverse_tree(entry
, file
, data
, depth
+1,
465 start
, leaf
, end
, padding
);
467 else if (depth
>= 0) {
469 leaf(entry
, file
, data
, entry
->insns
, depth
);
471 entry
= entry
->sibling
;
474 if (end
!= NULL
&& depth
>= 0)
475 end(table
, file
, data
, depth
);
480 insn_table_traverse_function(insn_table
*table
,
483 function_handler
*leaf
)
486 for (function
= table
->functions
;
488 function
= function
->next
) {
489 leaf(table
, file
, data
, function
->file_entry
);
494 insn_table_traverse_insn(insn_table
*table
,
497 insn_handler
*handler
)
500 for (instruction
= table
->insns
;
502 instruction
= instruction
->next
) {
503 handler(table
, file
, data
, instruction
, 0);
508 /****************************************************************/
511 field_constant_int
= 1,
512 field_constant_slash
= 2,
513 field_constant_string
= 3
514 } constant_field_types
;
518 insn_field_is_constant(insn_field
*field
,
521 /* field is an integer */
523 return field_constant_int
;
524 /* field is `/' and treating that as a constant */
525 if (field
->is_slash
&& rule
->force_slash
)
526 return field_constant_slash
;
527 /* field, though variable is on the list */
528 if (field
->is_string
&& rule
->force_expansion
!= NULL
) {
529 char *forced_fields
= rule
->force_expansion
;
530 while (*forced_fields
!= '\0') {
532 char *end
= strchr(forced_fields
, ',');
534 field_len
= strlen(forced_fields
);
536 field_len
= end
-forced_fields
;
537 if (strncmp(forced_fields
, field
->val_string
, field_len
) == 0
538 && field
->val_string
[field_len
] == '\0')
539 return field_constant_string
;
540 forced_fields
+= field_len
;
541 if (*forced_fields
== ',')
549 static opcode_field
*
550 insn_table_find_opcode_field(insn
*insns
,
554 opcode_field
*curr_opcode
= ZALLOC(opcode_field
);
558 curr_opcode
->first
= insn_bit_size
;
559 curr_opcode
->last
= -1;
560 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
) {
561 insn_fields
*fields
= entry
->fields
;
562 opcode_field new_opcode
;
564 /* find a start point for the opcode field */
565 new_opcode
.first
= rule
->first
;
566 while (new_opcode
.first
<= rule
->last
568 || insn_field_is_constant(fields
->bits
[new_opcode
.first
],
569 rule
) != field_constant_string
)
571 || !insn_field_is_constant(fields
->bits
[new_opcode
.first
],
573 new_opcode
.first
= fields
->bits
[new_opcode
.first
]->last
+ 1;
574 ASSERT(new_opcode
.first
> rule
->last
576 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
577 rule
) == field_constant_string
)
579 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
582 /* find the end point for the opcode field */
583 new_opcode
.last
= rule
->last
;
584 while (new_opcode
.last
>= rule
->first
586 || insn_field_is_constant(fields
->bits
[new_opcode
.last
],
587 rule
) != field_constant_string
)
589 || !insn_field_is_constant(fields
->bits
[new_opcode
.last
],
591 new_opcode
.last
= fields
->bits
[new_opcode
.last
]->first
- 1;
592 ASSERT(new_opcode
.last
< rule
->first
594 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
595 rule
) == field_constant_string
)
597 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
600 /* now see if our current opcode needs expanding */
601 if (new_opcode
.first
<= rule
->last
602 && curr_opcode
->first
> new_opcode
.first
)
603 curr_opcode
->first
= new_opcode
.first
;
604 if (new_opcode
.last
>= rule
->first
605 && curr_opcode
->last
< new_opcode
.last
)
606 curr_opcode
->last
= new_opcode
.last
;
610 /* was any thing interesting found? */
611 if (curr_opcode
->first
> rule
->last
) {
612 ASSERT(curr_opcode
->last
< rule
->first
);
615 ASSERT(curr_opcode
->last
>= rule
->first
);
616 ASSERT(curr_opcode
->first
<= rule
->last
);
618 /* if something was found, check it includes the forced field range */
620 && curr_opcode
->first
> rule
->force_first
) {
621 curr_opcode
->first
= rule
->force_first
;
624 && curr_opcode
->last
< rule
->force_last
) {
625 curr_opcode
->last
= rule
->force_last
;
627 /* handle special case elminating any need to do shift after mask */
629 && rule
->force_last
== insn_bit_size
-1) {
630 curr_opcode
->last
= insn_bit_size
-1;
633 /* handle any special cases */
634 switch (rule
->type
) {
635 case normal_decode_rule
:
636 /* let the above apply */
638 case expand_forced_rule
:
639 /* expand a limited nr of bits, ignoring the rest */
640 curr_opcode
->first
= rule
->force_first
;
641 curr_opcode
->last
= rule
->force_last
;
644 curr_opcode
->is_boolean
= 1;
645 curr_opcode
->boolean_constant
= rule
->special_constant
;
648 error("Something is going wrong\n");
656 insn_table_insert_expanded(insn_table
*table
,
661 insn_table
**ptr_to_cur_entry
= &table
->entries
;
662 insn_table
*cur_entry
= *ptr_to_cur_entry
;
664 /* find the new table for this entry */
665 while (cur_entry
!= NULL
666 && cur_entry
->opcode_nr
< new_opcode_nr
) {
667 ptr_to_cur_entry
= &cur_entry
->sibling
;
668 cur_entry
= *ptr_to_cur_entry
;
671 if (cur_entry
== NULL
|| cur_entry
->opcode_nr
!= new_opcode_nr
) {
672 insn_table
*new_entry
= ZALLOC(insn_table
);
673 new_entry
->opcode_nr
= new_opcode_nr
;
674 new_entry
->expanded_bits
= new_bits
;
675 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
676 new_entry
->sibling
= cur_entry
;
677 new_entry
->parent
= table
;
678 *ptr_to_cur_entry
= new_entry
;
679 cur_entry
= new_entry
;
682 /* ASSERT new_bits == cur_entry bits */
683 ASSERT(cur_entry
!= NULL
&& cur_entry
->opcode_nr
== new_opcode_nr
);
684 insn_table_insert_insn(cur_entry
,
685 old_insn
->file_entry
,
690 insn_table_expand_opcode(insn_table
*table
,
697 if (field_nr
> table
->opcode
->last
) {
698 insn_table_insert_expanded(table
, instruction
, opcode_nr
, bits
);
701 insn_field
*field
= instruction
->fields
->bits
[field_nr
];
702 if (field
->is_int
|| field
->is_slash
) {
703 ASSERT(field
->first
>= table
->opcode
->first
704 && field
->last
<= table
->opcode
->last
);
705 insn_table_expand_opcode(table
, instruction
, field
->last
+1,
706 ((opcode_nr
<< field
->width
) + field
->val_int
),
711 int last_pos
= ((field
->last
< table
->opcode
->last
)
712 ? field
->last
: table
->opcode
->last
);
713 int first_pos
= ((field
->first
> table
->opcode
->first
)
714 ? field
->first
: table
->opcode
->first
);
715 int width
= last_pos
- first_pos
+ 1;
716 int last_val
= (table
->opcode
->is_boolean
718 for (val
= 0; val
< last_val
; val
++) {
719 insn_bits
*new_bits
= ZALLOC(insn_bits
);
720 new_bits
->field
= field
;
721 new_bits
->value
= val
;
722 new_bits
->last
= bits
;
723 new_bits
->opcode
= table
->opcode
;
724 insn_table_expand_opcode(table
, instruction
, last_pos
+1,
725 ((opcode_nr
<< width
) | val
),
733 insn_table_insert_expanding(insn_table
*table
,
736 insn_table_expand_opcode(table
,
738 table
->opcode
->first
,
740 table
->expanded_bits
);
745 insn_table_expand_insns(insn_table
*table
)
748 ASSERT(table
->nr_insn
>= 1);
750 /* determine a valid opcode */
751 while (table
->opcode_rule
) {
752 /* specials only for single instructions */
753 if ((table
->nr_insn
> 1
754 && table
->opcode_rule
->special_mask
== 0
755 && table
->opcode_rule
->type
== normal_decode_rule
)
756 || (table
->nr_insn
== 1
757 && table
->opcode_rule
->special_mask
!= 0
758 && ((table
->insns
->fields
->value
759 & table
->opcode_rule
->special_mask
)
760 == table
->opcode_rule
->special_value
))
761 || (generate_expanded_instructions
762 && table
->opcode_rule
->special_mask
== 0
763 && table
->opcode_rule
->type
== normal_decode_rule
))
765 insn_table_find_opcode_field(table
->insns
,
767 table
->nr_insn
== 1/*string*/
769 if (table
->opcode
!= NULL
)
771 table
->opcode_rule
= table
->opcode_rule
->next
;
774 /* did we find anything */
775 if (table
->opcode
== NULL
) {
778 ASSERT(table
->opcode
!= NULL
);
780 /* back link what we found to its parent */
781 if (table
->parent
!= NULL
) {
782 ASSERT(table
->parent
->opcode
!= NULL
);
783 table
->opcode
->parent
= table
->parent
->opcode
;
786 /* expand the raw instructions according to the opcode */
789 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
) {
790 insn_table_insert_expanding(table
, entry
);
794 /* and do the same for the sub entries */
797 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
) {
798 insn_table_expand_insns(entry
);
809 dump_insn_field(insn_field
*field
,
813 printf("(insn_field*)0x%x\n", (unsigned)field
);
815 dumpf(indent
, "(first %d)\n", field
->first
);
817 dumpf(indent
, "(last %d)\n", field
->last
);
819 dumpf(indent
, "(width %d)\n", field
->width
);
822 dumpf(indent
, "(is_int %d)\n", field
->val_int
);
825 dumpf(indent
, "(is_slash)\n");
827 if (field
->is_string
)
828 dumpf(indent
, "(is_string `%s')\n", field
->val_string
);
830 dumpf(indent
, "(next 0x%x)\n", field
->next
);
832 dumpf(indent
, "(prev 0x%x)\n", field
->prev
);
838 dump_insn_fields(insn_fields
*fields
,
843 printf("(insn_fields*)%p\n", fields
);
845 dumpf(indent
, "(first 0x%x)\n", fields
->first
);
846 dumpf(indent
, "(last 0x%x)\n", fields
->last
);
848 dumpf(indent
, "(value 0x%x)\n", fields
->value
);
850 for (i
= 0; i
< insn_bit_size
; i
++) {
851 dumpf(indent
, "(bits[%d] ", i
, fields
->bits
[i
]);
852 dump_insn_field(fields
->bits
[i
], indent
+1);
853 dumpf(indent
, " )\n");
860 dump_opcode_field(opcode_field
*field
, int indent
, int levels
)
862 printf("(opcode_field*)%p\n", field
);
863 if (levels
&& field
!= NULL
) {
864 dumpf(indent
, "(first %d)\n", field
->first
);
865 dumpf(indent
, "(last %d)\n", field
->last
);
866 dumpf(indent
, "(is_boolean %d)\n", field
->is_boolean
);
867 dumpf(indent
, "(parent ");
868 dump_opcode_field(field
->parent
, indent
, levels
-1);
874 dump_insn_bits(insn_bits
*bits
, int indent
, int levels
)
876 printf("(insn_bits*)%p\n", bits
);
878 if (levels
&& bits
!= NULL
) {
879 dumpf(indent
, "(value %d)\n", bits
->value
);
880 dumpf(indent
, "(opcode ");
881 dump_opcode_field(bits
->opcode
, indent
+1, 0);
882 dumpf(indent
, " )\n");
883 dumpf(indent
, "(field ");
884 dump_insn_field(bits
->field
, indent
+1);
885 dumpf(indent
, " )\n");
886 dumpf(indent
, "(last ");
887 dump_insn_bits(bits
->last
, indent
+1, levels
-1);
894 dump_insn(insn
*entry
, int indent
, int levels
)
896 printf("(insn*)%p\n", entry
);
898 if (levels
&& entry
!= NULL
) {
900 dumpf(indent
, "(file_entry ");
901 dump_table_entry(entry
->file_entry
, indent
+1);
902 dumpf(indent
, " )\n");
904 dumpf(indent
, "(fields ");
905 dump_insn_fields(entry
->fields
, indent
+1);
906 dumpf(indent
, " )\n");
908 dumpf(indent
, "(next ");
909 dump_insn(entry
->next
, indent
+1, levels
-1);
910 dumpf(indent
, " )\n");
918 dump_insn_table(insn_table
*table
,
919 int indent
, int levels
)
922 printf("(insn_table*)%p\n", table
);
924 if (levels
&& table
!= NULL
) {
926 dumpf(indent
, "(opcode_nr %d)\n", table
->opcode_nr
);
928 dumpf(indent
, "(expanded_bits ");
929 dump_insn_bits(table
->expanded_bits
, indent
+1, -1);
930 dumpf(indent
, " )\n");
932 dumpf(indent
, "(int nr_insn %d)\n", table
->nr_insn
);
934 dumpf(indent
, "(insns ");
935 dump_insn(table
->insns
, indent
+1, table
->nr_insn
);
936 dumpf(indent
, " )\n");
938 dumpf(indent
, "(opcode_rule ");
939 dump_decode_rule(table
->opcode_rule
, indent
+1);
940 dumpf(indent
, " )\n");
942 dumpf(indent
, "(opcode ");
943 dump_opcode_field(table
->opcode
, indent
+1, 1);
944 dumpf(indent
, " )\n");
946 dumpf(indent
, "(nr_entries %d)\n", table
->entries
);
947 dumpf(indent
, "(entries ");
948 dump_insn_table(table
->entries
, indent
+1, table
->nr_entries
);
949 dumpf(indent
, " )\n");
951 dumpf(indent
, "(sibling ", table
->sibling
);
952 dump_insn_table(table
->sibling
, indent
+1, levels
-1);
953 dumpf(indent
, " )\n");
955 dumpf(indent
, "(parent ", table
->parent
);
956 dump_insn_table(table
->parent
, indent
+1, 0);
957 dumpf(indent
, " )\n");
962 int insn_bit_size
= max_insn_bit_size
;
964 int generate_expanded_instructions
;
967 main(int argc
, char **argv
)
969 filter
*filters
= NULL
;
970 decode_table
*decode_rules
= NULL
;
971 insn_table
*instructions
= NULL
;
972 cache_table
*cache_rules
= NULL
;
975 error("Usage: insn <filter> <hi-bit-nr> <decode-table> <insn-table>\n");
977 filters
= new_filter(argv
[1], filters
);
978 hi_bit_nr
= a2i(argv
[2]);
979 ASSERT(hi_bit_nr
< insn_bit_size
);
980 decode_rules
= load_decode_table(argv
[3], hi_bit_nr
);
981 instructions
= load_insn_table(argv
[4], decode_rules
, filters
, NULL
,
983 insn_table_expand_insns(instructions
);
985 dump_insn_table(instructions
, 0, -1);