1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, 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.
40 /****************************************************************/
47 int insn_size
= max_insn_size
;
48 int idecode_expand_semantics
= 0;
49 int idecode_cache
= 0;
53 /****************************************************************/
56 char *cache_idecode_formal
= "cpu *processor,\n instruction_word instruction,\n unsigned_word cia,\n idecode_cache *cache_entry";
57 char *cache_idecode_actual
= "processor, instruction, cia, cache_entry";
59 char *cache_semantic_formal
= "cpu *processor,\n idecode_cache *cache_entry,\n unsigned_word cia";
60 char *cache_semantic_actual
= "processor, entry, cia";
62 char *semantic_formal
= "cpu *processor,\n instruction_word instruction,\n unsigned_word cia";
63 char *semantic_actual
= "processor, instruction, cia";
67 /****************************************************************/
70 typedef struct _filter filter
;
75 filter
*filters
= NULL
;
78 /****************************************************************/
81 typedef struct _cache_rules cache_rules
;
90 cache_rules
*cache_table
;
103 load_cache_rules(char *file_name
)
105 table
*file
= table_open(file_name
, nr_cache_rule_fields
);
107 cache_rules
*table
= NULL
;
108 cache_rules
**curr_rule
= &table
;
109 while ((entry
= table_entry_read(file
)) != NULL
) {
110 cache_rules
*new_rule
= ZALLOC(cache_rules
);
111 new_rule
->valid
= target_a2i(hi_bit_nr
, entry
->fields
[ca_valid
]);
112 new_rule
->old_name
= entry
->fields
[ca_old_name
];
113 new_rule
->new_name
= entry
->fields
[ca_new_name
];
114 new_rule
->type
= (strlen(entry
->fields
[ca_type
])
115 ? entry
->fields
[ca_type
]
117 new_rule
->expression
= (strlen(entry
->fields
[ca_expression
]) > 0
118 ? entry
->fields
[ca_expression
]
120 *curr_rule
= new_rule
;
121 curr_rule
= &new_rule
->next
;
129 dump_cache_rule(cache_rules
* rule
,
132 dumpf(indent
, "((cache_rules*)0x%x\n", rule
);
133 dumpf(indent
, " (valid %d)\n", rule
->valid
);
134 dumpf(indent
, " (old_name \"%s\")\n", rule
->old_name
);
135 dumpf(indent
, " (new_name \"%s\")\n", rule
->new_name
);
136 dumpf(indent
, " (type \"%s\")\n", rule
->type
);
137 dumpf(indent
, " (expression \"%s\")\n", rule
->expression
);
138 dumpf(indent
, " (next 0x%x)\n", rule
->next
);
139 dumpf(indent
, " )\n");
144 dump_cache_rules(cache_rules
* rule
, int indent
)
147 dump_cache_rule(rule
, indent
);
153 /****************************************************************/
156 typedef struct _opcode_rules opcode_rules
;
157 struct _opcode_rules
{
163 char *force_expansion
;
165 unsigned special_mask
;
166 unsigned special_value
;
167 unsigned special_rule
;
170 opcode_rules
*opcode_table
;
188 static opcode_rules
*
189 load_opcode_rules(char *file_name
)
191 table
*file
= table_open(file_name
, nr_opcode_fields
);
193 opcode_rules
*table
= NULL
;
194 opcode_rules
**curr_rule
= &table
;
195 while ((entry
= table_entry_read(file
)) != NULL
) {
196 opcode_rules
*new_rule
= ZALLOC(opcode_rules
);
197 new_rule
->first
= target_a2i(hi_bit_nr
, entry
->fields
[op_first
]);
198 new_rule
->last
= target_a2i(hi_bit_nr
, entry
->fields
[op_last
]);
199 new_rule
->force_first
= target_a2i(hi_bit_nr
, entry
->fields
[op_force_first
]);
200 new_rule
->force_last
= target_a2i(hi_bit_nr
, entry
->fields
[op_force_last
]);
201 new_rule
->force_slash
= a2i(entry
->fields
[op_force_slash
]);
202 new_rule
->force_expansion
= entry
->fields
[op_force_expansion
];
203 new_rule
->use_switch
= a2i(entry
->fields
[op_use_switch
]);
204 new_rule
->special_mask
= a2i(entry
->fields
[op_special_mask
]);
205 new_rule
->special_value
= a2i(entry
->fields
[op_special_value
]);
206 new_rule
->special_rule
= a2i(entry
->fields
[op_special_rule
]);
207 *curr_rule
= new_rule
;
208 curr_rule
= &new_rule
->next
;
215 dump_opcode_rule(opcode_rules
*rule
,
218 dumpf(indent
, "((opcode_rules*)%p\n", rule
);
220 dumpf(indent
, " (first %d)\n", rule
->first
);
221 dumpf(indent
, " (last %d)\n", rule
->last
);
222 dumpf(indent
, " (force_first %d)\n", rule
->force_first
);
223 dumpf(indent
, " (force_last %d)\n", rule
->force_last
);
224 dumpf(indent
, " (force_slash %d)\n", rule
->force_slash
);
225 dumpf(indent
, " (force_expansion \"%s\")\n", rule
->force_expansion
);
226 dumpf(indent
, " (use_switch %d)\n", rule
->use_switch
);
227 dumpf(indent
, " (special_mask 0x%x)\n", rule
->special_mask
);
228 dumpf(indent
, " (special_value 0x%x)\n", rule
->special_value
);
229 dumpf(indent
, " (special_rule 0x%x)\n", rule
->special_rule
);
230 dumpf(indent
, " (next 0x%x)\n", rule
->next
);
232 dumpf(indent
, " )\n");
237 dump_opcode_rules(opcode_rules
*rule
,
241 dump_opcode_rule(rule
, indent
);
247 /****************************************************************/
249 typedef struct _insn_field insn_field
;
264 typedef struct _insn_fields insn_fields
;
265 struct _insn_fields
{
266 insn_field
*bits
[max_insn_size
];
273 parse_insn_format(table_entry
*entry
,
277 insn_fields
*fields
= ZALLOC(insn_fields
);
279 /* create a leading sentinal */
280 fields
->first
= ZALLOC(insn_field
);
281 fields
->first
->first
= -1;
282 fields
->first
->last
= -1;
283 fields
->first
->width
= 0;
285 /* and a trailing sentinal */
286 fields
->last
= ZALLOC(insn_field
);
287 fields
->last
->first
= insn_size
;
288 fields
->last
->last
= insn_size
;
289 fields
->last
->width
= 0;
291 /* link them together */
292 fields
->first
->next
= fields
->last
;
293 fields
->last
->prev
= fields
->first
;
295 /* now work through the formats */
298 while (*chp
!= '\0') {
303 insn_field
*new_field
;
306 if (!isdigit(*chp
)) {
307 error("%s:%d: missing position field at `%s'\n",
308 entry
->file_name
, entry
->line_nr
, chp
);
311 /* break out the bit position */
313 while (isdigit(*chp
))
315 strlen_pos
= chp
- start_pos
;
316 if (*chp
== '.' && strlen_pos
> 0)
319 error("%s:%d: missing field value at %s\n",
320 entry
->file_name
, entry
->line_nr
, chp
);
324 /* break out the value */
326 while ((*start_val
== '/' && *chp
== '/')
327 || (isdigit(*start_val
) && isdigit(*chp
))
328 || (isalpha(*start_val
) && (isalnum(*chp
) || *chp
== '_')))
330 strlen_val
= chp
- start_val
;
333 else if (*chp
!= '\0' || strlen_val
== 0) {
334 error("%s:%d: missing field terminator at %s\n",
335 entry
->file_name
, entry
->line_nr
, chp
);
339 /* create a new field and insert it */
340 new_field
= ZALLOC(insn_field
);
341 new_field
->next
= fields
->last
;
342 new_field
->prev
= fields
->last
->prev
;
343 new_field
->next
->prev
= new_field
;
344 new_field
->prev
->next
= new_field
;
347 new_field
->val_string
= (char*)zalloc(strlen_val
+1);
348 strncpy(new_field
->val_string
, start_val
, strlen_val
);
349 if (isdigit(*new_field
->val_string
)) {
350 new_field
->val_int
= a2i(new_field
->val_string
);
351 new_field
->is_int
= 1;
353 else if (new_field
->val_string
[0] == '/') {
354 new_field
->is_slash
= 1;
357 new_field
->is_string
= 1;
361 new_field
->pos_string
= (char*)zalloc(strlen_pos
+1);
362 strncpy(new_field
->pos_string
, start_pos
, strlen_pos
);
363 new_field
->first
= target_a2i(hi_bit_nr
, new_field
->pos_string
);
364 new_field
->last
= new_field
->next
->first
- 1; /* guess */
365 new_field
->width
= new_field
->last
- new_field
->first
+ 1; /* guess */
366 new_field
->prev
->last
= new_field
->first
-1; /*fix*/
367 new_field
->prev
->width
= new_field
->first
- new_field
->prev
->first
; /*fix*/
370 /* fiddle first/last so that the sentinals `disapear' */
371 ASSERT(fields
->first
->last
< 0);
372 ASSERT(fields
->last
->first
>= insn_size
);
373 fields
->first
= fields
->first
->next
;
374 fields
->last
= fields
->last
->prev
;
376 /* now go over this again, pointing each bit position at a field
381 field
= fields
->first
;
382 for (i
= 0; i
< insn_size
; i
++) {
383 while (field
->last
< i
)
385 fields
->bits
[i
] = field
;
389 /* go over each of the fields, and compute a `value' for the insn */
393 for (field
= fields
->first
;
394 field
->last
< insn_size
;
395 field
= field
->next
) {
396 fields
->value
<<= field
->width
;
398 fields
->value
|= field
->val_int
;
406 field_constant_int
= 1,
407 field_constant_slash
= 2,
408 field_constant_string
= 3
409 } constant_field_types
;
413 insn_field_is_constant(insn_field
*field
,
416 /* field is an integer */
418 return field_constant_int
;
419 /* field is `/' and treating that as a constant */
420 if (field
->is_slash
&& rule
->force_slash
)
421 return field_constant_slash
;
422 /* field, though variable is on the list */
423 if (field
->is_string
&& rule
->force_expansion
!= NULL
) {
424 char *forced_fields
= rule
->force_expansion
;
425 while (*forced_fields
!= '\0') {
427 char *end
= strchr(forced_fields
, ',');
429 field_len
= strlen(forced_fields
);
431 field_len
= end
-forced_fields
;
432 if (strncmp(forced_fields
, field
->val_string
, field_len
) == 0
433 && field
->val_string
[field_len
] == '\0')
434 return field_constant_string
;
435 forced_fields
+= field_len
;
436 if (*forced_fields
== ',')
445 dump_insn_field(insn_field
*field
,
449 printf("(insn_field*)0x%x\n", (unsigned)field
);
451 dumpf(indent
, "(first %d)\n", field
->first
);
453 dumpf(indent
, "(last %d)\n", field
->last
);
455 dumpf(indent
, "(width %d)\n", field
->width
);
458 dumpf(indent
, "(is_int %d)\n", field
->val_int
);
461 dumpf(indent
, "(is_slash)\n");
463 if (field
->is_string
)
464 dumpf(indent
, "(is_string `%s')\n", field
->val_string
);
466 dumpf(indent
, "(next 0x%x)\n", field
->next
);
468 dumpf(indent
, "(prev 0x%x)\n", field
->prev
);
474 dump_insn_fields(insn_fields
*fields
,
479 printf("(insn_fields*)%p\n", fields
);
481 dumpf(indent
, "(first 0x%x)\n", fields
->first
);
482 dumpf(indent
, "(last 0x%x)\n", fields
->last
);
484 dumpf(indent
, "(value 0x%x)\n", fields
->value
);
486 for (i
= 0; i
< insn_size
; i
++) {
487 dumpf(indent
, "(bits[%d] ", i
, fields
->bits
[i
]);
488 dump_insn_field(fields
->bits
[i
], indent
+1);
489 dumpf(indent
, " )\n");
495 /****************************************************************/
497 typedef struct _opcode_field opcode_field
;
498 struct _opcode_field
{
502 opcode_field
*parent
;
505 static opcode_field
*
506 opcode_field_new(void)
508 opcode_field
*new_field
= (opcode_field
*)zalloc(sizeof(opcode_field
));
509 ASSERT(new_field
!= NULL
);
510 new_field
->first
= insn_size
;
511 new_field
->last
= -1;
516 dump_opcode_field(opcode_field
*field
, int indent
, int levels
)
518 printf("(opcode_field*)%p\n", field
);
519 if (levels
&& field
!= NULL
) {
520 dumpf(indent
, "(first %d)\n", field
->first
);
521 dumpf(indent
, "(last %d)\n", field
->last
);
522 dumpf(indent
, "(is_boolean %d)\n", field
->is_boolean
);
523 dumpf(indent
, "(parent ");
524 dump_opcode_field(field
->parent
, indent
, levels
-1);
529 /****************************************************************/
531 typedef struct _insn_bits insn_bits
;
536 opcode_field
*opcode
;
542 dump_insn_bits(insn_bits
*bits
, int indent
, int levels
)
544 printf("(insn_bits*)%p\n", bits
);
546 if (levels
&& bits
!= NULL
) {
547 dumpf(indent
, "(value %d)\n", bits
->value
);
548 dumpf(indent
, "(opcode ");
549 dump_opcode_field(bits
->opcode
, indent
+1, 0);
550 dumpf(indent
, " )\n");
551 dumpf(indent
, "(field ");
552 dump_insn_field(bits
->field
, indent
+1);
553 dumpf(indent
, " )\n");
554 dumpf(indent
, "(last ");
555 dump_insn_bits(bits
->last
, indent
+1, levels
-1);
560 /****************************************************************/
570 nr_insn_table_fields
,
572 char *insn_field_name
[nr_insn_table_fields
] = {
573 "format", "form", "flags", "nmemonic", "name", "comments"
577 function_type
= insn_format
,
578 function_name
= insn_name
,
579 function_param
= insn_comment
,
580 } function_table_fields
;
583 typedef struct _insn insn
;
585 table_entry
*file_entry
;
590 typedef struct _insn_table insn_table
;
593 insn_bits
*expanded_bits
;
597 opcode_rules
*opcode_rule
;
598 opcode_field
*opcode
;
608 insn_table_insert_function(insn_table
*table
,
609 table_entry
*file_entry
)
611 insn
**ptr_to_cur_function
= &table
->functions
;
613 /* create a new function */
614 insn
*new_function
= ZALLOC(insn
);
615 new_function
->file_entry
= file_entry
;
617 /* append it to the end of the function list */
618 while (*ptr_to_cur_function
!= NULL
) {
619 ptr_to_cur_function
= &(*ptr_to_cur_function
)->next
;
621 *ptr_to_cur_function
= new_function
;
626 insn_table_insert_insn(insn_table
*table
,
627 table_entry
*file_entry
,
630 insn
**ptr_to_cur_insn
= &table
->insns
;
631 insn
*cur_insn
= *ptr_to_cur_insn
;
633 /* create a new instruction */
634 insn
*new_insn
= ZALLOC(insn
);
635 new_insn
->file_entry
= file_entry
;
636 new_insn
->fields
= fields
;
638 /* insert it according to the order of the fields */
639 while (cur_insn
!= NULL
640 && new_insn
->fields
->value
>= cur_insn
->fields
->value
) {
641 ptr_to_cur_insn
= &cur_insn
->next
;
642 cur_insn
= *ptr_to_cur_insn
;
645 new_insn
->next
= cur_insn
;
646 *ptr_to_cur_insn
= new_insn
;
652 static opcode_field
*
653 insn_table_find_opcode_field(insn
*insns
,
657 opcode_field
*curr_opcode
= opcode_field_new();
662 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
) {
663 insn_fields
*fields
= entry
->fields
;
664 opcode_field new_opcode
;
666 /* find a start point for the opcode field */
667 new_opcode
.first
= rule
->first
;
668 while (new_opcode
.first
<= rule
->last
670 || insn_field_is_constant(fields
->bits
[new_opcode
.first
],
671 rule
) != field_constant_string
)
673 || !insn_field_is_constant(fields
->bits
[new_opcode
.first
],
675 new_opcode
.first
= fields
->bits
[new_opcode
.first
]->last
+ 1;
676 ASSERT(new_opcode
.first
> rule
->last
678 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
679 rule
) == field_constant_string
)
681 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
684 /* find the end point for the opcode field */
685 new_opcode
.last
= rule
->last
;
686 while (new_opcode
.last
>= rule
->first
688 || insn_field_is_constant(fields
->bits
[new_opcode
.last
],
689 rule
) != field_constant_string
)
691 || !insn_field_is_constant(fields
->bits
[new_opcode
.last
],
693 new_opcode
.last
= fields
->bits
[new_opcode
.last
]->first
- 1;
694 ASSERT(new_opcode
.last
< rule
->first
696 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
697 rule
) == field_constant_string
)
699 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
702 /* now see if our current opcode needs expanding */
703 if (new_opcode
.first
<= rule
->last
704 && curr_opcode
->first
> new_opcode
.first
)
705 curr_opcode
->first
= new_opcode
.first
;
706 if (new_opcode
.last
>= rule
->first
707 && curr_opcode
->last
< new_opcode
.last
)
708 curr_opcode
->last
= new_opcode
.last
;
712 /* was any thing interesting found? */
713 if (curr_opcode
->first
> rule
->last
) {
714 ASSERT(curr_opcode
->last
< rule
->first
);
717 ASSERT(curr_opcode
->last
>= rule
->first
);
718 ASSERT(curr_opcode
->first
<= rule
->last
);
720 /* if something was found, check it includes the forced field range */
722 && curr_opcode
->first
> rule
->force_first
) {
723 curr_opcode
->first
= rule
->force_first
;
726 && curr_opcode
->last
< rule
->force_last
) {
727 curr_opcode
->last
= rule
->force_last
;
729 /* handle special case elminating any need to do shift after mask */
731 && rule
->force_last
== insn_size
-1) {
732 curr_opcode
->last
= insn_size
-1;
735 /* handle any special cases */
736 switch (rule
->special_rule
) {
737 case 0: /* let the above apply */
739 case 1: /* expand a limited nr of bits, ignoring the rest */
740 curr_opcode
->first
= rule
->force_first
;
741 curr_opcode
->last
= rule
->force_last
;
743 case 2: /* boolean field */
744 curr_opcode
->is_boolean
= 1;
753 insn_table_insert_expanded(insn_table
*table
,
758 insn_table
**ptr_to_cur_entry
= &table
->entries
;
759 insn_table
*cur_entry
= *ptr_to_cur_entry
;
761 /* find the new table for this entry */
762 while (cur_entry
!= NULL
763 && cur_entry
->opcode_nr
< new_opcode_nr
) {
764 ptr_to_cur_entry
= &cur_entry
->sibling
;
765 cur_entry
= *ptr_to_cur_entry
;
768 if (cur_entry
== NULL
|| cur_entry
->opcode_nr
!= new_opcode_nr
) {
769 insn_table
*new_entry
= ZALLOC(insn_table
);
770 new_entry
->opcode_nr
= new_opcode_nr
;
771 new_entry
->expanded_bits
= new_bits
;
772 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
773 new_entry
->sibling
= cur_entry
;
774 new_entry
->parent
= table
;
775 *ptr_to_cur_entry
= new_entry
;
776 cur_entry
= new_entry
;
779 /* ASSERT new_bits == cur_entry bits */
780 ASSERT(cur_entry
!= NULL
&& cur_entry
->opcode_nr
== new_opcode_nr
);
781 insn_table_insert_insn(cur_entry
,
782 old_insn
->file_entry
,
787 insn_table_expand_opcode(insn_table
*table
,
794 if (field_nr
> table
->opcode
->last
) {
795 insn_table_insert_expanded(table
, instruction
, opcode_nr
, bits
);
798 insn_field
*field
= instruction
->fields
->bits
[field_nr
];
799 if (field
->is_int
|| field
->is_slash
) {
800 ASSERT(field
->first
>= table
->opcode
->first
801 && field
->last
<= table
->opcode
->last
);
802 insn_table_expand_opcode(table
, instruction
, field
->last
+1,
803 ((opcode_nr
<< field
->width
) + field
->val_int
),
808 int last_pos
= ((field
->last
< table
->opcode
->last
)
809 ? field
->last
: table
->opcode
->last
);
810 int first_pos
= ((field
->first
> table
->opcode
->first
)
811 ? field
->first
: table
->opcode
->first
);
812 int width
= last_pos
- first_pos
+ 1;
813 int last_val
= (table
->opcode
->is_boolean
815 for (val
= 0; val
< last_val
; val
++) {
816 insn_bits
*new_bits
= ZALLOC(insn_bits
);
817 new_bits
->field
= field
;
818 new_bits
->value
= val
;
819 new_bits
->last
= bits
;
820 new_bits
->opcode
= table
->opcode
;
821 insn_table_expand_opcode(table
, instruction
, last_pos
+1,
822 ((opcode_nr
<< width
) | val
),
830 insn_table_insert_expanding(insn_table
*table
,
833 insn_table_expand_opcode(table
,
835 table
->opcode
->first
,
837 table
->expanded_bits
);
842 insn_table_expand_insns(insn_table
*table
)
845 ASSERT(table
->nr_insn
>= 1);
847 /* determine a valid opcode */
848 while (table
->opcode_rule
) {
849 /* specials only for single instructions */
850 if ((table
->nr_insn
> 1
851 && table
->opcode_rule
->special_mask
== 0
852 && table
->opcode_rule
->special_rule
== 0)
853 || (table
->nr_insn
== 1
854 && table
->opcode_rule
->special_mask
!= 0
855 && ((table
->insns
->fields
->value
856 & table
->opcode_rule
->special_mask
)
857 == table
->opcode_rule
->special_value
))
858 || (idecode_expand_semantics
859 && table
->opcode_rule
->special_mask
== 0
860 && table
->opcode_rule
->special_rule
== 0))
862 insn_table_find_opcode_field(table
->insns
,
864 table
->nr_insn
== 1/*string*/
866 if (table
->opcode
!= NULL
)
868 table
->opcode_rule
= table
->opcode_rule
->next
;
871 /* did we find anything */
872 if (table
->opcode
== NULL
) {
875 ASSERT(table
->opcode
!= NULL
);
877 /* back link what we found to its parent */
878 if (table
->parent
!= NULL
) {
879 ASSERT(table
->parent
->opcode
!= NULL
);
880 table
->opcode
->parent
= table
->parent
->opcode
;
883 /* expand the raw instructions according to the opcode */
886 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
) {
887 insn_table_insert_expanding(table
, entry
);
891 /* and do the same for the sub entries */
894 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
) {
895 insn_table_expand_insns(entry
);
903 insn_table_load_insns(char *file_name
)
905 table
*file
= table_open(file_name
, nr_insn_table_fields
);
906 insn_table
*table
= ZALLOC(insn_table
);
907 table_entry
*file_entry
;
908 table
->opcode_rule
= opcode_table
;
910 while ((file_entry
= table_entry_read(file
)) != NULL
) {
911 if (it_is("function", file_entry
->fields
[insn_flags
])
912 || it_is("internal", file_entry
->fields
[insn_flags
])) {
913 insn_table_insert_function(table
, file_entry
);
917 /* skip instructions that aren't relevant to the mode */
918 filter
*filt
= filters
;
919 while (filt
!= NULL
) {
920 if (it_is(filt
->flag
, file_entry
->fields
[insn_flags
]))
925 /* create/insert the new instruction */
926 fields
= parse_insn_format(file_entry
,
927 file_entry
->fields
[insn_format
]);
928 insn_table_insert_insn(table
, file_entry
, fields
);
937 dump_insn(insn
*entry
, int indent
, int levels
)
939 printf("(insn*)%p\n", entry
);
941 if (levels
&& entry
!= NULL
) {
943 dumpf(indent
, "(file_entry ");
944 dump_table_entry(entry
->file_entry
, indent
+1);
945 dumpf(indent
, " )\n");
947 dumpf(indent
, "(fields ");
948 dump_insn_fields(entry
->fields
, indent
+1);
949 dumpf(indent
, " )\n");
951 dumpf(indent
, "(next ");
952 dump_insn(entry
->next
, indent
+1, levels
-1);
953 dumpf(indent
, " )\n");
961 dump_insn_table(insn_table
*table
,
962 int indent
, int levels
)
965 printf("(insn_table*)%p\n", table
);
967 if (levels
&& table
!= NULL
) {
969 dumpf(indent
, "(opcode_nr %d)\n", table
->opcode_nr
);
971 dumpf(indent
, "(expanded_bits ");
972 dump_insn_bits(table
->expanded_bits
, indent
+1, -1);
973 dumpf(indent
, " )\n");
975 dumpf(indent
, "(int nr_insn %d)\n", table
->nr_insn
);
977 dumpf(indent
, "(insns ");
978 dump_insn(table
->insns
, indent
+1, table
->nr_insn
);
979 dumpf(indent
, " )\n");
981 dumpf(indent
, "(opcode_rule ");
982 dump_opcode_rule(table
->opcode_rule
, indent
+1);
983 dumpf(indent
, " )\n");
985 dumpf(indent
, "(opcode ");
986 dump_opcode_field(table
->opcode
, indent
+1, 1);
987 dumpf(indent
, " )\n");
989 dumpf(indent
, "(nr_entries %d)\n", table
->entries
);
990 dumpf(indent
, "(entries ");
991 dump_insn_table(table
->entries
, indent
+1, table
->nr_entries
);
992 dumpf(indent
, " )\n");
994 dumpf(indent
, "(sibling ", table
->sibling
);
995 dump_insn_table(table
->sibling
, indent
+1, levels
-1);
996 dumpf(indent
, " )\n");
998 dumpf(indent
, "(parent ", table
->parent
);
999 dump_insn_table(table
->parent
, indent
+1, 0);
1000 dumpf(indent
, " )\n");
1006 /****************************************************************/
1010 lf_print_insn_bits(lf
*file
, insn_bits
*bits
)
1014 lf_print_insn_bits(file
, bits
->last
);
1015 lf_putchr(file
, '_');
1016 lf_putstr(file
, bits
->field
->val_string
);
1017 if (!bits
->opcode
->is_boolean
|| bits
->value
== 0) {
1018 if (bits
->opcode
->last
< bits
->field
->last
)
1019 lf_putint(file
, bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1021 lf_putint(file
, bits
->value
);
1026 lf_print_opcodes(lf
*file
,
1029 if (table
!= NULL
) {
1031 lf_printf(file
, "_%d_%d",
1032 table
->opcode
->first
,
1033 table
->opcode
->last
);
1034 if (table
->parent
== NULL
) break;
1035 lf_printf(file
, "__%d", table
->opcode_nr
);
1036 table
= table
->parent
;
1042 lf_print_table_name(lf
*file
,
1045 lf_printf(file
, "idecode_table");
1046 lf_print_opcodes(file
, table
);
1052 function_name_prefix_semantics
,
1053 function_name_prefix_idecode
,
1054 function_name_prefix_itable
,
1055 function_name_prefix_none
1056 } lf_function_name_prefixes
;
1059 lf_print_function_name(lf
*file
,
1061 insn_bits
*expanded_bits
,
1062 lf_function_name_prefixes prefix
)
1067 case function_name_prefix_semantics
:
1068 lf_putstr(file
, "semantic_");
1070 case function_name_prefix_idecode
:
1071 lf_printf(file
, "idecode_");
1073 case function_name_prefix_itable
:
1074 lf_putstr(file
, "itable_");
1080 /* the function name */
1083 for (pos
= basename
;
1091 lf_putchr(file
, '_');
1094 lf_putchr(file
, *pos
);
1101 if (idecode_expand_semantics
)
1102 lf_print_insn_bits(file
, expanded_bits
);
1107 lf_print_idecode_table(lf
*file
,
1110 int can_assume_leaf
;
1111 opcode_rules
*opcode_rule
;
1113 /* have a look at the rule table, if all table rules follow all
1114 switch rules, I can assume that all end points are leaves */
1115 opcode_rule
= opcode_table
;
1116 while (opcode_rule
!= NULL
1117 && opcode_rule
->use_switch
)
1118 opcode_rule
= opcode_rule
->next
;
1119 while (opcode_rule
!= NULL
1120 && opcode_rule
->use_switch
1121 && opcode_rule
->special_rule
)
1122 opcode_rule
= opcode_rule
->next
;
1123 can_assume_leaf
= opcode_rule
== NULL
;
1125 lf_printf(file
, "{\n");
1126 lf_indent(file
, +2);
1128 lf_printf(file
, "idecode_table_entry *table = ");
1129 lf_print_table_name(file
, entry
);
1130 lf_printf(file
, ";\n");
1131 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1132 i2target(hi_bit_nr
, entry
->opcode
->first
),
1133 i2target(hi_bit_nr
, entry
->opcode
->last
));
1134 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
1135 lf_printf(file
, "while (1) {\n");
1136 lf_indent(file
, +2);
1138 lf_printf(file
, "while (table_entry->mask != 0) {\n");
1139 lf_indent(file
, +2);
1141 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1142 lf_printf(file
, " table_entry->function_or_table);\n");
1143 lf_printf(file
, "opcode = ((instruction & table_entry->mask)\n");
1144 lf_printf(file
, " >> table_entry->shift);\n");
1145 lf_printf(file
, "table_entry = table + opcode;\n");
1147 lf_indent(file
, -2);
1148 lf_printf(file
, "}\n");
1149 if (!idecode_cache
&& can_assume_leaf
) {
1150 lf_printf(file
, "return (((idecode_semantic*)\n");
1151 lf_printf(file
, " table_entry->function_or_table)\n");
1152 lf_printf(file
, " (%s));\n", semantic_actual
);
1154 else if (!idecode_cache
&& !can_assume_leaf
) {
1155 lf_printf(file
, "if (table_entry->shift == 0)");
1156 lf_printf(file
, " return (((idecode_semantic*)\n");
1157 lf_printf(file
, " table_entry->function_or_table)\n");
1158 lf_printf(file
, " (%s));\n", semantic_actual
);
1161 lf_printf(file
, "if (table_entry->shift == 0)\n");
1162 lf_printf(file
, " return (((idecode_crack*)\n");
1163 lf_printf(file
, " table_entry->function_or_table)\n");
1164 lf_printf(file
, " (%s));\n", cache_idecode_actual
);
1166 if (!can_assume_leaf
) {
1167 lf_printf(file
, "opcode = (instruction & table_entry->shift) != 0;\n");
1168 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1169 lf_printf(file
, " table_entry->function_or_table);\n");
1170 lf_printf(file
, "table_entry = table + opcode;\n");
1173 lf_indent(file
, -2);
1174 lf_printf(file
, "}\n");
1176 lf_indent(file
, -2);
1177 lf_printf(file
, "}\n");
1182 lf_print_my_prefix(lf
*file
,
1183 table_entry
*file_entry
,
1186 lf_printf(file
, "const char *const my_prefix = \n");
1187 lf_printf(file
, " \"%s:%s:%s:%d\";\n",
1188 filter_filename (file_entry
->file_name
),
1189 (idecode
? "idecode" : "semantics"),
1190 file_entry
->fields
[insn_name
],
1191 file_entry
->line_nr
);
1196 lf_print_ptrace(lf
*file
,
1199 lf_printf(file
, "\n");
1200 lf_printf(file
, "ITRACE(trace_%s, (\"\\n\"));\n",
1201 (idecode
? "idecode" : "semantics"));
1205 /****************************************************************/
1207 typedef void leaf_handler
1211 typedef void padding_handler
1219 insn_table_traverse_tree(insn_table
*table
,
1222 leaf_handler
*start
,
1225 padding_handler
*padding
)
1230 ASSERT(table
!= NULL
1231 && table
->opcode
!= NULL
1232 && table
->nr_entries
> 0
1233 && table
->entries
!= 0);
1235 if (start
!= NULL
&& depth
>= 0)
1236 start(table
, data
, depth
);
1238 for (entry_nr
= 0, entry
= table
->entries
;
1239 entry_nr
< (table
->opcode
->is_boolean
1241 : (1 << (table
->opcode
->last
- table
->opcode
->first
+ 1)));
1244 || (!table
->opcode
->is_boolean
1245 && entry_nr
< entry
->opcode_nr
)) {
1246 if (padding
!= NULL
&& depth
>= 0)
1247 padding(table
, data
, depth
, entry_nr
);
1250 ASSERT(entry
!= NULL
&& (entry
->opcode_nr
== entry_nr
1251 || table
->opcode
->is_boolean
));
1252 if (entry
->opcode
!= NULL
&& depth
!= 0) {
1253 insn_table_traverse_tree(entry
, data
, depth
+1,
1254 start
, leaf
, end
, padding
);
1256 else if (depth
>= 0) {
1258 leaf(entry
, data
, depth
);
1260 entry
= entry
->sibling
;
1263 if (end
!= NULL
&& depth
>= 0)
1264 end(table
, data
, depth
);
1268 typedef void function_handler
1271 table_entry
*function
);
1274 insn_table_traverse_function(insn_table
*table
,
1276 function_handler
*leaf
)
1279 for (function
= table
->functions
;
1281 function
= function
->next
) {
1282 leaf(table
, data
, function
->file_entry
);
1287 typedef void insn_handler
1293 insn_table_traverse_insn(insn_table
*table
,
1298 for (instruction
= table
->insns
;
1299 instruction
!= NULL
;
1300 instruction
= instruction
->next
) {
1301 leaf(table
, data
, instruction
);
1307 update_depth(insn_table
*entry
,
1311 int *max_depth
= (int*)data
;
1312 if (*max_depth
< depth
)
1318 insn_table_depth(insn_table
*table
)
1321 insn_table_traverse_tree(table
,
1332 /****************************************************************/
1335 dump_traverse_start(insn_table
*table
,
1339 dumpf(depth
*2, "(%d\n", table
->opcode_nr
);
1343 dump_traverse_leaf(insn_table
*entry
,
1347 ASSERT(entry
->nr_entries
== 0
1348 && entry
->nr_insn
== 1
1349 && entry
->opcode
== NULL
);
1350 dumpf(depth
*2, ".%d %s\n", entry
->opcode_nr
,
1351 entry
->insns
->file_entry
->fields
[insn_format
]);
1355 dump_traverse_end(insn_table
*table
,
1359 dumpf(depth
*2, ")\n");
1363 dump_traverse_padding(insn_table
*table
,
1368 dumpf(depth
*2, ".<%d>\n", opcode_nr
);
1373 dump_traverse(insn_table
*table
)
1375 insn_table_traverse_tree(table
, NULL
, 1,
1376 dump_traverse_start
,
1379 dump_traverse_padding
);
1383 /****************************************************************/
1387 semantics_h_print_function(lf
*file
,
1389 insn_bits
*expanded_bits
)
1391 lf_printf(file
, "\n");
1392 lf_printf(file
, "INLINE_SEMANTICS unsigned_word ");
1393 lf_print_function_name(file
,
1396 function_name_prefix_semantics
);
1397 lf_printf(file
, "\n(%s);\n",
1398 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
1403 semantics_h_leaf(insn_table
*entry
,
1407 lf
*file
= (lf
*)data
;
1408 ASSERT(entry
->nr_insn
== 1);
1409 semantics_h_print_function(file
,
1410 entry
->insns
->file_entry
->fields
[insn_name
],
1411 entry
->expanded_bits
);
1415 semantics_h_insn(insn_table
*entry
,
1419 lf
*file
= (lf
*)data
;
1420 semantics_h_print_function(file
,
1421 instruction
->file_entry
->fields
[insn_name
],
1426 semantics_h_function(insn_table
*entry
,
1428 table_entry
*function
)
1430 lf
*file
= (lf
*)data
;
1431 if (function
->fields
[function_type
] == NULL
1432 || function
->fields
[function_type
][0] == '\0') {
1433 semantics_h_print_function(file
,
1434 function
->fields
[function_name
],
1438 lf_printf(file
, "\n");
1439 lf_printf(file
, "INLINE_SEMANTICS %s %s\n(%s);\n",
1440 function
->fields
[function_type
],
1441 function
->fields
[function_name
],
1442 function
->fields
[function_param
]);
1448 gen_semantics_h(insn_table
*table
, lf
*file
)
1451 lf_print_copyleft(file
);
1452 lf_printf(file
, "\n");
1453 lf_printf(file
, "#ifndef _SEMANTICS_H_\n");
1454 lf_printf(file
, "#define _SEMANTICS_H_\n");
1455 lf_printf(file
, "\n");
1456 lf_printf(file
, "#ifndef INLINE_SEMANTICS\n");
1457 lf_printf(file
, "#define INLINE_SEMANTICS\n");
1458 lf_printf(file
, "#endif\n");
1459 lf_printf(file
, "\n");
1460 lf_printf(file
, "\n");
1462 /* output a declaration for all functions */
1463 insn_table_traverse_function(table
,
1465 semantics_h_function
);
1467 /* output a declaration for all instructions */
1468 if (idecode_expand_semantics
)
1469 insn_table_traverse_tree(table
,
1473 semantics_h_leaf
, /* leaf */
1475 NULL
); /* padding */
1477 insn_table_traverse_insn(table
,
1481 lf_printf(file
, "\n");
1482 lf_printf(file
, "#endif /* _SEMANTICS_H_ */\n");
1486 /****************************************************************/
1488 typedef struct _icache_tree icache_tree
;
1489 struct _icache_tree
{
1492 icache_tree
*children
;
1495 static icache_tree
*
1496 icache_tree_insert(icache_tree
*tree
,
1499 icache_tree
*new_tree
;
1501 icache_tree
**ptr_to_cur_tree
= &tree
->children
;
1502 icache_tree
*cur_tree
= *ptr_to_cur_tree
;
1503 while (cur_tree
!= NULL
1504 && strcmp(cur_tree
->name
, name
) < 0) {
1505 ptr_to_cur_tree
= &cur_tree
->next
;
1506 cur_tree
= *ptr_to_cur_tree
;
1508 ASSERT(cur_tree
== NULL
1509 || strcmp(cur_tree
->name
, name
) >= 0);
1510 /* already in the tree */
1511 if (cur_tree
!= NULL
1512 && strcmp(cur_tree
->name
, name
) == 0)
1514 /* missing, insert it */
1515 ASSERT(cur_tree
== NULL
1516 || strcmp(cur_tree
->name
, name
) > 0);
1517 new_tree
= ZALLOC(icache_tree
);
1518 new_tree
->name
= name
;
1519 new_tree
->next
= cur_tree
;
1520 *ptr_to_cur_tree
= new_tree
;
1525 static icache_tree
*
1526 insn_table_cache_fields(insn_table
*table
)
1528 icache_tree
*tree
= ZALLOC(icache_tree
);
1530 for (instruction
= table
->insns
;
1531 instruction
!= NULL
;
1532 instruction
= instruction
->next
) {
1535 icache_tree_insert(tree
,
1536 instruction
->file_entry
->fields
[insn_form
]);
1537 for (field
= instruction
->fields
->first
;
1539 field
= field
->next
) {
1540 if (field
->is_string
)
1541 icache_tree_insert(form
, field
->val_string
);
1550 gen_icache_h(icache_tree
*tree
,
1553 lf_print_copyleft(file
);
1554 lf_printf(file
, "\n");
1555 lf_printf(file
, "#ifndef _ICACHE_H_\n");
1556 lf_printf(file
, "#define _ICACHE_H_\n");
1557 lf_printf(file
, "\n");
1558 lf_printf(file
, "#ifndef INLINE_ICACHE\n");
1559 lf_printf(file
, "#define INLINE_ICACHE\n");
1560 lf_printf(file
, "#endif\n");
1561 lf_printf(file
, "\n");
1563 lf_printf(file
, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1565 lf_printf(file
, "\n");
1567 /* create an instruction cache if being used */
1568 if (idecode_cache
) {
1570 lf_printf(file
, "typedef struct _idecode_cache {\n");
1571 lf_printf(file
, " unsigned_word address;\n");
1572 lf_printf(file
, " void *semantic;\n");
1573 lf_printf(file
, " union {\n");
1574 for (form
= tree
->children
;
1576 form
= form
->next
) {
1578 lf_printf(file
, " struct {\n");
1579 for (field
= form
->children
;
1581 field
= field
->next
) {
1582 cache_rules
*cache_rule
;
1584 for (cache_rule
= cache_table
;
1586 cache_rule
= cache_rule
->next
) {
1587 if (strcmp(field
->name
, cache_rule
->old_name
) == 0) {
1589 if (cache_rule
->new_name
!= NULL
)
1590 lf_printf(file
, " %s %s; /* %s */\n",
1591 (cache_rule
->type
== NULL
1593 : cache_rule
->type
),
1594 cache_rule
->new_name
,
1595 cache_rule
->old_name
);
1599 lf_printf(file
, " unsigned %s;\n", field
->name
);
1601 lf_printf(file
, " } %s;\n", form
->name
);
1603 lf_printf(file
, " } crack;\n");
1604 lf_printf(file
, "} idecode_cache;\n");
1607 /* alernativly, since no cache, #define the fields to be
1608 extractions from the instruction variable */
1609 cache_rules
*cache_rule
;
1610 lf_printf(file
, "\n");
1611 for (cache_rule
= cache_table
;
1613 cache_rule
= cache_rule
->next
) {
1614 if (cache_rule
->expression
!= NULL
1615 && strlen(cache_rule
->expression
) > 0)
1616 lf_printf(file
, "#define %s %s\n",
1617 cache_rule
->new_name
, cache_rule
->expression
);
1621 lf_printf(file
, "\n");
1622 lf_printf(file
, "#endif /* _ICACHE_H_ */\n");
1628 /****************************************************************/
1632 lf_print_c_extraction(lf
*file
,
1636 char *field_expression
,
1637 insn_field
*cur_field
,
1639 int get_value_from_cache
,
1640 int put_value_in_cache
)
1642 ASSERT(field_name
!= NULL
);
1644 && (!bits
->opcode
->is_boolean
|| bits
->value
== 0)
1645 && strcmp(field_name
, cur_field
->val_string
) == 0) {
1646 ASSERT(bits
->field
== cur_field
);
1647 ASSERT(field_type
== NULL
);
1648 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1649 lf_printf(file
, "const unsigned %s = ",
1651 if (bits
->opcode
->last
< bits
->field
->last
)
1652 lf_printf(file
, "%d;\n",
1653 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1655 lf_printf(file
, "%d;\n", bits
->value
);
1658 /* put the field in the local variable */
1659 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1660 lf_printf(file
, "%s const %s = ",
1661 field_type
== NULL
? "unsigned" : field_type
,
1663 /* getting it from the cache */
1664 if (get_value_from_cache
|| put_value_in_cache
) {
1665 lf_printf(file
, "cache_entry->crack.%s.%s",
1666 instruction
->file_entry
->fields
[insn_form
],
1668 if (put_value_in_cache
) /* also put it in the cache? */
1669 lf_printf(file
, " = ");
1671 if (!get_value_from_cache
) {
1672 if (strcmp(field_name
, cur_field
->val_string
) == 0)
1673 lf_printf(file
, "EXTRACTED32(instruction, %d, %d)",
1674 i2target(hi_bit_nr
, cur_field
->first
),
1675 i2target(hi_bit_nr
, cur_field
->last
));
1676 else if (field_expression
!= NULL
)
1677 lf_printf(file
, "%s", field_expression
);
1679 lf_printf(file
, "eval_%s", field_name
);
1681 lf_printf(file
, ";\n");
1687 lf_print_c_extractions(lf
*file
,
1689 insn_bits
*expanded_bits
,
1690 int get_value_from_cache
,
1691 int put_value_in_cache
)
1693 insn_field
*cur_field
;
1695 /* extract instruction fields */
1696 lf_printf(file
, "/* extraction: %s */\n",
1697 instruction
->file_entry
->fields
[insn_format
]);
1699 for (cur_field
= instruction
->fields
->first
;
1700 cur_field
->first
< insn_size
;
1701 cur_field
= cur_field
->next
) {
1702 if (cur_field
->is_string
) {
1705 /* find any corresponding value */
1706 for (bits
= expanded_bits
;
1708 bits
= bits
->last
) {
1709 if (bits
->field
== cur_field
)
1712 /* try the cache rule table for what to do */
1713 if (get_value_from_cache
|| put_value_in_cache
) {
1714 cache_rules
*cache_rule
;
1715 for (cache_rule
= cache_table
;
1717 cache_rule
= cache_rule
->next
) {
1718 if (strcmp(cur_field
->val_string
, cache_rule
->old_name
) == 0) {
1720 if (cache_rule
->valid
> 1 && put_value_in_cache
)
1721 lf_print_c_extraction(file
,
1723 cache_rule
->new_name
,
1725 cache_rule
->expression
,
1730 else if (cache_rule
->valid
== 1)
1731 lf_print_c_extraction(file
,
1733 cache_rule
->new_name
,
1735 cache_rule
->expression
,
1738 get_value_from_cache
,
1739 put_value_in_cache
);
1743 if (found_rule
== 0)
1744 lf_print_c_extraction(file
,
1746 cur_field
->val_string
,
1751 get_value_from_cache
,
1752 put_value_in_cache
);
1753 /* if any (XXX == 0), output a corresponding test */
1754 if (instruction
->file_entry
->annex
!= NULL
) {
1755 char *field_name
= cur_field
->val_string
;
1756 char *is_0_ptr
= instruction
->file_entry
->annex
;
1757 int field_len
= strlen(field_name
);
1758 if (strlen(is_0_ptr
) >= (strlen("_is_0") + field_len
)) {
1759 is_0_ptr
+= field_len
;
1760 while ((is_0_ptr
= strstr(is_0_ptr
, "_is_0")) != NULL
) {
1761 if (strncmp(is_0_ptr
- field_len
, field_name
, field_len
) == 0
1762 && !isalpha(is_0_ptr
[ - field_len
- 1])) {
1763 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1764 lf_printf(file
, "const unsigned %s_is_0 = (", field_name
);
1766 lf_printf(file
, "%d", bits
->value
);
1768 lf_printf(file
, "%s", field_name
);
1769 lf_printf(file
, " == 0);\n");
1772 is_0_ptr
+= strlen("_is_0");
1776 /* any thing else ... */
1779 lf_print_lf_c_line_nr(file
);
1784 lf_print_idecode_illegal(lf
*file
)
1787 lf_printf(file
, "return idecode_illegal(%s);\n", cache_idecode_actual
);
1789 lf_printf(file
, "return semantic_illegal(%s);\n", semantic_actual
);
1794 lf_print_idecode_floating_point_unavailable(lf
*file
)
1797 lf_printf(file
, "return idecode_floating_point_unavailable(%s);\n",
1798 cache_idecode_actual
);
1800 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
1805 /* Output code to do any final checks on the decoded instruction.
1806 This includes things like verifying any on decoded fields have the
1807 correct value and checking that (for floating point) floating point
1808 hardware isn't disabled */
1811 lf_print_c_validate(lf
*file
,
1813 opcode_field
*opcodes
)
1815 /* Validate: unchecked instruction fields
1817 If any constant fields in the instruction were not checked by the
1818 idecode tables, output code to check that they have the correct
1821 unsigned check_mask
= 0;
1822 unsigned check_val
= 0;
1824 opcode_field
*opcode
;
1826 /* form check_mask/check_val containing what needs to be checked
1827 in the instruction */
1828 for (field
= instruction
->fields
->first
;
1829 field
->first
< insn_size
;
1830 field
= field
->next
) {
1832 check_mask
<<= field
->width
;
1833 check_val
<<= field
->width
;
1835 /* is it a constant that could need validating? */
1836 if (!field
->is_int
&& !field
->is_slash
)
1839 /* has it been checked by a table? */
1840 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1841 if (field
->first
>= opcode
->first
1842 && field
->last
<= opcode
->last
)
1848 check_mask
|= (1 << field
->width
)-1;
1849 check_val
|= field
->val_int
;
1852 /* if any bits not checked by opcode tables, output code to check them */
1854 lf_printf(file
, "\n");
1855 lf_printf(file
, "/* validate: %s */\n",
1856 instruction
->file_entry
->fields
[insn_format
]);
1857 lf_printf(file
, "if ((instruction & 0x%x) != 0x%x)\n",
1858 check_mask
, check_val
);
1859 lf_indent(file
, +2);
1860 lf_print_idecode_illegal(file
);
1861 lf_indent(file
, -2);
1865 /* Validate floating point hardware
1867 If the simulator is being built with out floating point hardware
1868 (different to it being disabled in the MSR) then floating point
1869 instructions are invalid */
1871 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1872 lf_printf(file
, "\n");
1873 lf_printf(file
, "/* Validate: FP hardware exists */\n");
1874 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1875 lf_indent(file
, +2);
1876 lf_print_idecode_illegal(file
);
1877 lf_indent(file
, -2);
1881 /* Validate: Floating Point available
1883 If floating point is not available, we enter a floating point
1884 unavailable interrupt into the cache instead of the instruction
1887 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1888 ever a CSI occures we flush the instruction cache. */
1891 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1892 lf_printf(file
, "\n");
1893 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
1894 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
1895 lf_indent(file
, +2);
1896 lf_print_idecode_floating_point_unavailable(file
);
1897 lf_indent(file
, -2);
1904 lf_print_c_cracker(lf
*file
,
1906 insn_bits
*expanded_bits
,
1907 opcode_field
*opcodes
)
1910 /* function header */
1911 lf_printf(file
, "{\n");
1912 lf_indent(file
, +2);
1914 lf_print_my_prefix(file
,
1915 instruction
->file_entry
,
1916 1/*putting-value-in-cache*/);
1918 lf_print_ptrace(file
,
1919 1/*putting-value-in-cache*/);
1921 lf_print_c_validate(file
, instruction
, opcodes
);
1923 lf_printf(file
, "\n");
1924 lf_printf(file
, "{\n");
1925 lf_indent(file
, +2);
1926 lf_print_c_extractions(file
,
1929 0/*get_value_from_cache*/,
1930 1/*put_value_in_cache*/);
1931 lf_indent(file
, -2);
1932 lf_printf(file
, "}\n");
1934 /* return the function propper (main sorts this one out) */
1935 lf_printf(file
, "\n");
1936 lf_printf(file
, "/* semantic routine */\n");
1937 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1938 lf_printf(file
, "return ");
1939 lf_print_function_name(file
,
1940 instruction
->file_entry
->fields
[insn_name
],
1942 function_name_prefix_semantics
);
1943 lf_printf(file
, ";\n");
1945 lf_print_lf_c_line_nr(file
);
1946 lf_indent(file
, -2);
1947 lf_printf(file
, "}\n");
1952 lf_print_c_semantic(lf
*file
,
1954 insn_bits
*expanded_bits
,
1955 opcode_field
*opcodes
)
1958 lf_printf(file
, "{\n");
1959 lf_indent(file
, +2);
1961 lf_print_my_prefix(file
,
1962 instruction
->file_entry
,
1963 0/*not putting value in cache*/);
1964 lf_printf(file
, "unsigned_word nia = cia + %d;\n", insn_size
/ 8);
1966 lf_printf(file
, "\n");
1967 lf_print_c_extractions(file
,
1970 idecode_cache
/*get_value_from_cache*/,
1971 0/*put_value_in_cache*/);
1973 lf_print_ptrace(file
,
1974 0/*put_value_in_cache*/);
1976 /* validate the instruction, if a cache this has already been done */
1978 lf_print_c_validate(file
, instruction
, opcodes
);
1980 /* generate the profileing call - this is delayed until after the
1981 instruction has been verified */
1982 lf_printf(file
, "\n");
1983 lf_printf(file
, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
1984 lf_printf(file
, " mon_issue(");
1985 lf_print_function_name(file
,
1986 instruction
->file_entry
->fields
[insn_name
],
1988 function_name_prefix_itable
);
1989 lf_printf(file
, ", processor, cia);\n");
1991 /* generate the code (or at least something */
1992 if (instruction
->file_entry
->annex
!= NULL
) {
1994 lf_printf(file
, "\n");
1995 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1996 lf_printf(file
, "{\n");
1997 lf_indent(file
, +2);
1998 lf_print_c_code(file
, instruction
->file_entry
->annex
);
1999 lf_indent(file
, -2);
2000 lf_printf(file
, "}\n");
2001 lf_print_lf_c_line_nr(file
);
2003 else if (it_is("nop", instruction
->file_entry
->fields
[insn_flags
])) {
2004 lf_print_lf_c_line_nr(file
);
2006 else if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2007 /* unimplemented floating point instruction - call for assistance */
2008 lf_printf(file
, "\n");
2009 lf_printf(file
, "/* unimplemented floating point instruction - call for assistance */\n");
2010 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2011 lf_putstr(file
, "floating_point_assist_interrupt(processor, cia);\n");
2012 lf_print_lf_c_line_nr(file
);
2015 /* abort so it is implemented now */
2016 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2017 lf_putstr(file
, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2018 lf_print_lf_c_line_nr(file
);
2019 lf_printf(file
, "\n");
2022 /* the function footer */
2023 lf_printf(file
, "return nia;\n");
2024 lf_indent(file
, -2);
2025 lf_printf(file
, "}\n");
2029 lf_print_c_semantic_function_header(lf
*file
,
2031 insn_bits
*expanded_bits
)
2033 lf_printf(file
, "\n");
2034 lf_printf(file
, "INLINE_SEMANTICS unsigned_word\n");
2035 lf_print_function_name(file
,
2038 function_name_prefix_semantics
);
2039 lf_printf(file
, "\n(%s)\n",
2040 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2044 lf_print_c_semantic_function(lf
*file
,
2046 insn_bits
*expanded_bits
,
2047 opcode_field
*opcodes
)
2050 /* build the semantic routine to execute the instruction */
2051 lf_print_c_semantic_function_header(file
,
2052 instruction
->file_entry
->fields
[insn_name
],
2054 lf_print_c_semantic(file
,
2062 semantics_c_leaf(insn_table
*entry
,
2066 lf
*file
= (lf
*)data
;
2067 ASSERT(entry
->nr_insn
== 1
2068 && entry
->opcode
== NULL
2069 && entry
->parent
!= NULL
2070 && entry
->parent
->opcode
!= NULL
);
2071 lf_print_c_semantic_function(file
,
2073 entry
->expanded_bits
,
2074 entry
->parent
->opcode
);
2078 semantics_c_insn(insn_table
*table
,
2082 lf
*file
= (lf
*)data
;
2083 lf_print_c_semantic_function(file
, instruction
,
2088 semantics_c_function(insn_table
*table
,
2090 table_entry
*function
)
2092 lf
*file
= (lf
*)data
;
2093 if (function
->fields
[function_type
] == NULL
2094 || function
->fields
[function_type
][0] == '\0') {
2095 lf_print_c_semantic_function_header(file
,
2096 function
->fields
[function_name
],
2100 lf_printf(file
, "\n");
2101 lf_printf(file
, "INLINE_SEMANTICS %s\n%s(%s)\n",
2102 function
->fields
[function_type
],
2103 function
->fields
[function_name
],
2104 function
->fields
[function_param
]);
2106 table_entry_lf_c_line_nr(file
, function
);
2107 lf_printf(file
, "{\n");
2108 lf_indent(file
, +2);
2109 lf_print_c_code(file
, function
->annex
);
2110 lf_indent(file
, -2);
2111 lf_printf(file
, "}\n");
2112 lf_print_lf_c_line_nr(file
);
2118 gen_semantics_c(insn_table
*table
, lf
*file
)
2120 lf_print_copyleft(file
);
2121 lf_printf(file
, "\n");
2122 lf_printf(file
, "#ifndef _SEMANTICS_C_\n");
2123 lf_printf(file
, "#define _SEMANTICS_C_\n");
2124 lf_printf(file
, "\n");
2125 lf_printf(file
, "#ifndef STATIC_INLINE_SEMANTICS\n");
2126 lf_printf(file
, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2127 lf_printf(file
, "#endif\n");
2128 lf_printf(file
, "\n");
2129 lf_printf(file
, "#include \"cpu.h\"\n");
2130 lf_printf(file
, "#include \"idecode.h\"\n");
2131 lf_printf(file
, "#include \"semantics.h\"\n");
2132 lf_printf(file
, "\n");
2134 /* output a definition (c-code) for all functions */
2135 insn_table_traverse_function(table
,
2137 semantics_c_function
);
2139 /* output a definition (c-code) for all instructions */
2140 if (idecode_expand_semantics
)
2141 insn_table_traverse_tree(table
,
2147 NULL
); /* padding */
2149 insn_table_traverse_insn(table
,
2153 lf_printf(file
, "\n");
2154 lf_printf(file
, "#endif /* _SEMANTICS_C_ */\n");
2158 /****************************************************************/
2161 gen_idecode_h(insn_table
*table
, lf
*file
)
2163 lf_print_copyleft(file
);
2164 lf_printf(file
, "\n");
2165 lf_printf(file
, "#ifndef _IDECODE_H_\n");
2166 lf_printf(file
, "#define _IDECODE_H_\n");
2167 lf_printf(file
, "\n");
2168 lf_printf(file
, "#ifndef INLINE_IDECODE\n");
2169 lf_printf(file
, "#define INLINE_IDECODE\n");
2170 lf_printf(file
, "#endif\n");
2171 lf_printf(file
, "\n");
2172 lf_printf(file
, "#include \"idecode_expression.h\"\n");
2173 lf_printf(file
, "#include \"idecode_fields.h\"\n");
2174 lf_printf(file
, "#include \"idecode_branch.h\"\n");
2175 lf_printf(file
, "\n");
2176 lf_printf(file
, "#include \"icache.h\"\n");
2177 lf_printf(file
, "\n");
2178 lf_printf(file
, "typedef unsigned_word idecode_semantic\n(%s);\n",
2179 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2180 lf_printf(file
, "\n");
2182 lf_printf(file
, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2183 cache_idecode_formal
);
2185 lf_printf(file
, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2187 lf_printf(file
, "\n");
2188 lf_printf(file
, "#endif /* _IDECODE_H_ */\n");
2192 /****************************************************************/
2196 idecode_table_start(insn_table
*table
,
2200 lf
*file
= (lf
*)data
;
2202 /* start of the table */
2203 if (!table
->opcode_rule
->use_switch
) {
2204 lf_printf(file
, "\n");
2205 lf_printf(file
, "static idecode_table_entry ");
2206 lf_print_table_name(file
, table
);
2207 lf_printf(file
, "[] = {\n");
2212 idecode_table_leaf(insn_table
*entry
,
2216 lf
*file
= (lf
*)data
;
2217 ASSERT(entry
->parent
!= NULL
);
2220 /* add an entry to the table */
2221 if (!entry
->parent
->opcode_rule
->use_switch
) {
2222 if (entry
->opcode
== NULL
) {
2223 /* table leaf entry */
2224 lf_printf(file
, " /*%d*/ { 0, 0, ", entry
->opcode_nr
);
2225 lf_print_function_name(file
,
2226 entry
->insns
->file_entry
->fields
[insn_name
],
2227 entry
->expanded_bits
,
2229 ? function_name_prefix_idecode
2230 : function_name_prefix_semantics
));
2231 lf_printf(file
, " },\n");
2233 else if (entry
->opcode_rule
->use_switch
) {
2234 /* table calling switch statement */
2235 lf_printf(file
, " /*%d*/ { -1, 0, ",
2237 lf_print_table_name(file
, entry
);
2238 lf_printf(file
, " },\n");
2241 /* table `calling' another table */
2242 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
2243 if (entry
->opcode
->is_boolean
)
2244 lf_printf(file
, "MASK32(%d,%d), 0, ",
2245 i2target(hi_bit_nr
, entry
->opcode
->first
),
2246 i2target(hi_bit_nr
, entry
->opcode
->last
));
2248 lf_printf(file
, "%d, MASK32(%d,%d), ",
2249 insn_size
- entry
->opcode
->last
- 1,
2250 i2target(hi_bit_nr
, entry
->opcode
->first
),
2251 i2target(hi_bit_nr
, entry
->opcode
->last
));
2252 lf_print_table_name(file
, entry
);
2253 lf_printf(file
, " },\n");
2259 idecode_table_end(insn_table
*table
,
2263 lf
*file
= (lf
*)data
;
2266 if (!table
->opcode_rule
->use_switch
) {
2267 lf_printf(file
, "};\n");
2272 idecode_table_padding(insn_table
*table
,
2277 lf
*file
= (lf
*)data
;
2280 if (!table
->opcode_rule
->use_switch
) {
2281 lf_printf(file
, " /*%d*/ { 0, 0, %s_illegal },\n",
2282 opcode_nr
, (idecode_cache
? "idecode" : "semantic"));
2287 /****************************************************************/
2290 void lf_print_idecode_switch
2296 idecode_switch_start(insn_table
*table
,
2300 lf
*file
= (lf
*)data
;
2302 ASSERT(table
->opcode_rule
->use_switch
);
2304 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2305 i2target(hi_bit_nr
, table
->opcode
->first
),
2306 i2target(hi_bit_nr
, table
->opcode
->last
));
2311 idecode_switch_leaf(insn_table
*entry
,
2315 lf
*file
= (lf
*)data
;
2316 ASSERT(entry
->parent
!= NULL
);
2318 ASSERT(entry
->parent
->opcode_rule
->use_switch
);
2320 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
2321 lf_indent(file
, +2);
2323 if (entry
->opcode
== NULL
) {
2324 /* switch calling leaf */
2325 lf_printf(file
, "return ");
2326 lf_print_function_name(file
,
2327 entry
->insns
->file_entry
->fields
[insn_name
],
2328 entry
->expanded_bits
,
2330 ? function_name_prefix_idecode
2331 : function_name_prefix_semantics
));
2333 lf_printf(file
, "(%s);\n", cache_idecode_actual
);
2335 lf_printf(file
, "(%s);\n", semantic_actual
);
2337 else if (entry
->opcode_rule
->use_switch
) {
2338 /* switch calling switch */
2339 lf_print_idecode_switch(file
, entry
);
2342 /* switch calling table */
2343 lf_printf(file
, "return ");
2344 lf_print_idecode_table(file
, entry
);
2346 lf_printf(file
, "break;\n");
2348 lf_indent(file
, -2);
2353 lf_print_idecode_switch_illegal(lf
*file
)
2355 lf_indent(file
, +2);
2356 lf_print_idecode_illegal(file
);
2357 lf_printf(file
, "break;\n");
2358 lf_indent(file
, -2);
2362 idecode_switch_end(insn_table
*table
,
2366 lf
*file
= (lf
*)data
;
2368 ASSERT(table
->opcode_rule
->use_switch
);
2370 if (table
->opcode_rule
->use_switch
== 1) {
2371 lf_printf(file
, "default:\n");
2372 lf_print_idecode_switch_illegal(file
);
2374 lf_printf(file
, "}\n");
2378 idecode_switch_padding(insn_table
*table
,
2383 lf
*file
= (lf
*)data
;
2386 ASSERT(table
->opcode_rule
->use_switch
);
2388 if (table
->opcode_rule
->use_switch
> 1) {
2389 lf_printf(file
, "case %d:\n", opcode_nr
);
2390 lf_print_idecode_switch_illegal(file
);
2396 lf_print_idecode_switch(lf
*file
,
2399 insn_table_traverse_tree(table
,
2402 idecode_switch_start
,
2403 idecode_switch_leaf
,
2405 idecode_switch_padding
);
2410 idecode_expand_if_switch(insn_table
*table
,
2414 lf
*file
= (lf
*)data
;
2416 if (table
->opcode_rule
->use_switch
2417 && table
->parent
!= NULL
/* don't expand the top one yet */
2418 && !table
->parent
->opcode_rule
->use_switch
) {
2419 lf_printf(file
, "\n");
2420 lf_printf(file
, "STATIC_INLINE_IDECODE void\n");
2421 lf_print_table_name(file
, table
);
2422 lf_printf(file
, "\n(%s)\n",
2423 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2424 lf_printf(file
, "{\n");
2426 lf_indent(file
, +2);
2427 lf_print_idecode_switch(file
, table
);
2428 lf_indent(file
, -2);
2430 lf_printf(file
, "}\n");
2436 lf_print_c_cracker_function(lf
*file
,
2438 insn_bits
*expanded_bits
,
2439 opcode_field
*opcodes
)
2441 /* if needed, generate code to enter this routine into a cache */
2442 lf_printf(file
, "\n");
2443 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2444 lf_print_function_name(file
,
2445 instruction
->file_entry
->fields
[insn_name
],
2447 function_name_prefix_idecode
);
2448 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2450 lf_print_c_cracker(file
,
2457 idecode_crack_leaf(insn_table
*entry
,
2461 lf
*file
= (lf
*)data
;
2462 ASSERT(entry
->nr_insn
== 1
2463 && entry
->opcode
== NULL
2464 && entry
->parent
!= NULL
2465 && entry
->parent
->opcode
!= NULL
);
2466 lf_print_c_cracker_function(file
,
2468 entry
->expanded_bits
,
2473 idecode_crack_insn(insn_table
*entry
,
2477 lf
*file
= (lf
*)data
;
2478 lf_print_c_cracker_function(file
,
2485 idecode_c_internal_function(insn_table
*table
,
2487 table_entry
*function
)
2489 lf
*file
= (lf
*)data
;
2490 ASSERT(idecode_cache
!= 0);
2491 if (it_is("internal", function
->fields
[insn_flags
])) {
2492 lf_printf(file
, "\n");
2493 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2494 lf_print_function_name(file
,
2495 function
->fields
[insn_name
],
2497 function_name_prefix_idecode
);
2498 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2499 lf_printf(file
, "{\n");
2500 lf_indent(file
, +2);
2501 lf_printf(file
, "/* semantic routine */\n");
2502 table_entry_lf_c_line_nr(file
, function
);
2503 lf_printf(file
, "return ");
2504 lf_print_function_name(file
,
2505 function
->fields
[insn_name
],
2507 function_name_prefix_semantics
);
2508 lf_printf(file
, ";\n");
2510 lf_print_lf_c_line_nr(file
);
2511 lf_indent(file
, -2);
2512 lf_printf(file
, "}\n");
2517 /****************************************************************/
2520 gen_idecode_c(insn_table
*table
, lf
*file
)
2525 lf_print_copyleft(file
);
2526 lf_printf(file
, "\n");
2527 lf_printf(file
, "\n");
2528 lf_printf(file
, "#ifndef _IDECODE_C_\n");
2529 lf_printf(file
, "#define _IDECODE_C_\n");
2530 lf_printf(file
, "\n");
2531 lf_printf(file
, "#ifndef STATIC_INLINE_IDECODE\n");
2532 lf_printf(file
, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2533 lf_printf(file
, "#endif\n");
2534 lf_printf(file
, "\n");
2535 lf_printf(file
, "#include \"cpu.h\"\n");
2536 lf_printf(file
, "#include \"idecode.h\"\n");
2537 lf_printf(file
, "#include \"semantics.h\"\n");
2538 lf_printf(file
, "\n");
2539 lf_printf(file
, "\n");
2540 lf_printf(file
, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2541 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2542 lf_printf(file
, "\n");
2543 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
2544 lf_printf(file
, " unsigned shift;\n");
2545 lf_printf(file
, " unsigned mask;\n");
2546 lf_printf(file
, " void *function_or_table;\n");
2547 lf_printf(file
, "} idecode_table_entry;\n");
2548 lf_printf(file
, "\n");
2549 lf_printf(file
, "\n");
2551 /* output `internal' invalid/floating-point unavailable functions
2553 if (idecode_cache
) {
2554 insn_table_traverse_function(table
,
2556 idecode_c_internal_function
);
2559 /* output cracking functions where needed */
2560 if (idecode_cache
) {
2561 if (idecode_expand_semantics
)
2562 insn_table_traverse_tree(table
,
2570 insn_table_traverse_insn(table
,
2572 idecode_crack_insn
);
2576 /* output tables where needed */
2577 for (depth
= insn_table_depth(table
);
2580 insn_table_traverse_tree(table
,
2583 idecode_table_start
,
2586 idecode_table_padding
);
2589 /* output switch functions where needed */
2590 insn_table_traverse_tree(table
,
2593 idecode_expand_if_switch
, /* START */
2596 /* output the main idecode routine */
2597 lf_printf(file
, "\n");
2599 lf_printf(file
, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2600 cache_idecode_formal
);
2602 lf_printf(file
, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2604 lf_printf(file
, "{\n");
2605 lf_indent(file
, +2);
2606 if (table
->opcode_rule
->use_switch
)
2607 lf_print_idecode_switch(file
, table
);
2609 lf_print_idecode_table(file
, table
);
2610 lf_indent(file
, -2);
2611 lf_printf(file
, "}\n");
2612 lf_printf(file
, "\n");
2613 lf_printf(file
, "#endif\n");
2617 /****************************************************************/
2620 itable_h_insn(insn_table
*entry
,
2624 lf
*file
= (lf
*)data
;
2625 lf_printf(file
, " ");
2626 lf_print_function_name(file
,
2627 instruction
->file_entry
->fields
[insn_name
],
2629 function_name_prefix_itable
);
2630 lf_printf(file
, ",\n");
2635 gen_itable_h(insn_table
*table
, lf
*file
)
2638 lf_print_copyleft(file
);
2639 lf_printf(file
, "\n");
2640 lf_printf(file
, "#ifndef _ITABLE_H_\n");
2641 lf_printf(file
, "#define _ITABLE_H_\n");
2642 lf_printf(file
, "\n");
2643 lf_printf(file
, "#ifndef INLINE_ITABLE\n");
2644 lf_printf(file
, "#define INLINE_ITABLE\n");
2645 lf_printf(file
, "#endif\n");
2646 lf_printf(file
, "\n");
2647 lf_printf(file
, "\n");
2649 /* output an enumerated type for each instruction */
2650 lf_printf(file
, "typedef enum {\n");
2651 insn_table_traverse_insn(table
,
2654 lf_printf(file
, " nr_itable_entries,\n");
2655 lf_printf(file
, "} itable_index;\n");
2656 lf_printf(file
, "\n");
2658 /* output the table that contains the actual instruction info */
2659 lf_printf(file
, "typedef struct _itable_instruction_info {\n");
2660 lf_printf(file
, " itable_index nr;\n");
2661 lf_printf(file
, " char *format;\n");
2662 lf_printf(file
, " char *form;\n");
2663 lf_printf(file
, " char *flags;\n");
2664 lf_printf(file
, " char *nmemonic;\n");
2665 lf_printf(file
, " char *name;\n");
2666 lf_printf(file
, "} itable_info;\n");
2667 lf_printf(file
, "\n");
2668 lf_printf(file
, "extern itable_info itable[nr_itable_entries];\n");
2670 lf_printf(file
, "\n");
2671 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2675 /****************************************************************/
2678 itable_c_insn(insn_table
*entry
,
2682 lf
*file
= (lf
*)data
;
2683 char **fields
= instruction
->file_entry
->fields
;
2684 lf_printf(file
, " { ");
2685 lf_print_function_name(file
,
2686 instruction
->file_entry
->fields
[insn_name
],
2688 function_name_prefix_itable
);
2689 lf_printf(file
, ",\n");
2690 lf_printf(file
, " \"%s\",\n", fields
[insn_format
]);
2691 lf_printf(file
, " \"%s\",\n", fields
[insn_form
]);
2692 lf_printf(file
, " \"%s\",\n", fields
[insn_flags
]);
2693 lf_printf(file
, " \"%s\",\n", fields
[insn_nmemonic
]);
2694 lf_printf(file
, " \"%s\",\n", fields
[insn_name
]);
2695 lf_printf(file
, " },\n");
2700 gen_itable_c(insn_table
*table
, lf
*file
)
2703 lf_print_copyleft(file
);
2704 lf_printf(file
, "\n");
2705 lf_printf(file
, "#ifndef _ITABLE_C_\n");
2706 lf_printf(file
, "#define _ITABLE_C_\n");
2707 lf_printf(file
, "\n");
2708 lf_printf(file
, "#ifndef STATIC_INLINE_ITABLE\n");
2709 lf_printf(file
, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2710 lf_printf(file
, "#endif\n");
2711 lf_printf(file
, "\n");
2712 lf_printf(file
, "#include \"itable.h\"\n");
2713 lf_printf(file
, "\n");
2715 /* output the table that contains the actual instruction info */
2716 lf_printf(file
, "itable_info itable[nr_itable_entries] = {\n");
2717 insn_table_traverse_insn(table
,
2720 lf_printf(file
, "};\n");
2721 lf_printf(file
, "\n");
2723 lf_printf(file
, "\n");
2724 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2728 /****************************************************************/
2736 insn_table
*instructions
= NULL
;
2737 icache_tree
*cache_fields
= NULL
;
2738 char *real_file_name
= NULL
;
2743 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
2744 printf("Config options:\n");
2745 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
2746 printf(" -e Expand (duplicate) semantic functions\n");
2747 printf(" -r <icache-size> Generate cracking cache version\n");
2748 printf(" -l Supress line numbering in output files\n");
2749 printf(" -b <bit-size> Set the number of bits in an instruction\n");
2750 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
2751 printf("Input options (ucase version also dumps loaded table):\n");
2752 printf(" -[Oo] <opcode-rules>\n");
2753 printf(" -[Kk] <cache-rules>\n");
2754 printf(" -[Ii] <instruction-table>\n");
2755 printf("Output options:\n");
2756 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
2757 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
2758 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
2759 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
2762 while ((ch
= getopt(argc
, argv
,
2763 "leb:h:r:f:I:i:O:o:K:k:n:S:s:D:d:T:t:C:")) != -1) {
2764 fprintf(stderr
, "\t-%c %s\n", ch
, (optarg
? optarg
: ""));
2770 idecode_expand_semantics
= 1;
2773 idecode_cache
= a2i(optarg
);
2776 insn_size
= a2i(optarg
);
2777 ASSERT(insn_size
> 0 && insn_size
<= max_insn_size
2778 && (hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0));
2781 hi_bit_nr
= a2i(optarg
);
2782 ASSERT(hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0);
2786 filter
*new_filter
= ZALLOC(filter
);
2787 new_filter
->flag
= strdup(optarg
);
2788 new_filter
->next
= filters
;
2789 filters
= new_filter
;
2794 ASSERT(opcode_table
!= NULL
);
2795 ASSERT(cache_table
!= NULL
);
2796 instructions
= insn_table_load_insns(optarg
);
2797 fprintf(stderr
, "\texpanding ...\n");
2798 insn_table_expand_insns(instructions
);
2799 fprintf(stderr
, "\tcache fields ...\n");
2800 cache_fields
= insn_table_cache_fields(instructions
);
2802 dump_traverse(instructions
);
2803 dump_insn_table(instructions
, 0, 1);
2808 opcode_table
= load_opcode_rules(optarg
);
2810 dump_opcode_rules(opcode_table
, 0);
2814 cache_table
= load_cache_rules(optarg
);
2816 dump_cache_rules(cache_table
, 0);
2819 real_file_name
= strdup(optarg
);
2829 lf
*file
= lf_open(optarg
, real_file_name
, number_lines
);
2830 ASSERT(instructions
!= NULL
);
2833 gen_semantics_h(instructions
, file
);
2836 gen_semantics_c(instructions
, file
);
2839 gen_idecode_h(instructions
, file
);
2842 gen_idecode_c(instructions
, file
);
2845 gen_itable_h(instructions
, file
);
2848 gen_itable_c(instructions
, file
);
2851 gen_icache_h(cache_fields
, file
);
2856 real_file_name
= NULL
;
2859 error("unknown option\n");