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.
31 /****************************************************************/
38 int insn_size
= max_insn_size
;
39 int idecode_expand_semantics
= 0;
40 int idecode_cache
= 0;
44 /****************************************************************/
47 char *cache_idecode_formal
= "cpu *processor,\n instruction_word instruction,\n unsigned_word cia,\n idecode_cache *cache_entry";
48 char *cache_idecode_actual
= "processor, instruction, cia, cache_entry";
50 char *cache_semantic_formal
= "cpu *processor,\n idecode_cache *cache_entry,\n unsigned_word cia";
51 char *cache_semantic_actual
= "processor, entry, cia";
53 char *semantic_formal
= "cpu *processor,\n instruction_word instruction,\n unsigned_word cia";
54 char *semantic_actual
= "processor, instruction, cia";
58 /****************************************************************/
61 typedef struct _filter filter
;
66 filter
*filters
= NULL
;
69 /****************************************************************/
72 typedef struct _cache_rules cache_rules
;
81 cache_rules
*cache_table
;
94 load_cache_rules(char *file_name
)
96 table
*file
= table_open(file_name
, nr_cache_rule_fields
);
98 cache_rules
*table
= NULL
;
99 cache_rules
**curr_rule
= &table
;
100 while ((entry
= table_entry_read(file
)) != NULL
) {
101 cache_rules
*new_rule
= ZALLOC(cache_rules
);
102 new_rule
->valid
= target_a2i(hi_bit_nr
, entry
->fields
[ca_valid
]);
103 new_rule
->old_name
= entry
->fields
[ca_old_name
];
104 new_rule
->new_name
= entry
->fields
[ca_new_name
];
105 new_rule
->type
= (strlen(entry
->fields
[ca_type
])
106 ? entry
->fields
[ca_type
]
108 new_rule
->expression
= (strlen(entry
->fields
[ca_expression
]) > 0
109 ? entry
->fields
[ca_expression
]
111 *curr_rule
= new_rule
;
112 curr_rule
= &new_rule
->next
;
120 dump_cache_rule(cache_rules
* rule
,
123 dumpf(indent
, "((cache_rules*)0x%x\n", rule
);
124 dumpf(indent
, " (valid %d)\n", rule
->valid
);
125 dumpf(indent
, " (old_name \"%s\")\n", rule
->old_name
);
126 dumpf(indent
, " (new_name \"%s\")\n", rule
->new_name
);
127 dumpf(indent
, " (type \"%s\")\n", rule
->type
);
128 dumpf(indent
, " (expression \"%s\")\n", rule
->expression
);
129 dumpf(indent
, " (next 0x%x)\n", rule
->next
);
130 dumpf(indent
, " )\n");
135 dump_cache_rules(cache_rules
* rule
, int indent
)
138 dump_cache_rule(rule
, indent
);
144 /****************************************************************/
147 typedef struct _opcode_rules opcode_rules
;
148 struct _opcode_rules
{
154 char *force_expansion
;
156 unsigned special_mask
;
157 unsigned special_value
;
158 unsigned special_rule
;
161 opcode_rules
*opcode_table
;
179 static opcode_rules
*
180 load_opcode_rules(char *file_name
)
182 table
*file
= table_open(file_name
, nr_opcode_fields
);
184 opcode_rules
*table
= NULL
;
185 opcode_rules
**curr_rule
= &table
;
186 while ((entry
= table_entry_read(file
)) != NULL
) {
187 opcode_rules
*new_rule
= ZALLOC(opcode_rules
);
188 new_rule
->first
= target_a2i(hi_bit_nr
, entry
->fields
[op_first
]);
189 new_rule
->last
= target_a2i(hi_bit_nr
, entry
->fields
[op_last
]);
190 new_rule
->force_first
= target_a2i(hi_bit_nr
, entry
->fields
[op_force_first
]);
191 new_rule
->force_last
= target_a2i(hi_bit_nr
, entry
->fields
[op_force_last
]);
192 new_rule
->force_slash
= a2i(entry
->fields
[op_force_slash
]);
193 new_rule
->force_expansion
= entry
->fields
[op_force_expansion
];
194 new_rule
->use_switch
= a2i(entry
->fields
[op_use_switch
]);
195 new_rule
->special_mask
= a2i(entry
->fields
[op_special_mask
]);
196 new_rule
->special_value
= a2i(entry
->fields
[op_special_value
]);
197 new_rule
->special_rule
= a2i(entry
->fields
[op_special_rule
]);
198 *curr_rule
= new_rule
;
199 curr_rule
= &new_rule
->next
;
206 dump_opcode_rule(opcode_rules
*rule
,
209 dumpf(indent
, "((opcode_rules*)%p\n", rule
);
211 dumpf(indent
, " (first %d)\n", rule
->first
);
212 dumpf(indent
, " (last %d)\n", rule
->last
);
213 dumpf(indent
, " (force_first %d)\n", rule
->force_first
);
214 dumpf(indent
, " (force_last %d)\n", rule
->force_last
);
215 dumpf(indent
, " (force_slash %d)\n", rule
->force_slash
);
216 dumpf(indent
, " (force_expansion \"%s\")\n", rule
->force_expansion
);
217 dumpf(indent
, " (use_switch %d)\n", rule
->use_switch
);
218 dumpf(indent
, " (special_mask 0x%x)\n", rule
->special_mask
);
219 dumpf(indent
, " (special_value 0x%x)\n", rule
->special_value
);
220 dumpf(indent
, " (special_rule 0x%x)\n", rule
->special_rule
);
221 dumpf(indent
, " (next 0x%x)\n", rule
->next
);
223 dumpf(indent
, " )\n");
228 dump_opcode_rules(opcode_rules
*rule
,
232 dump_opcode_rule(rule
, indent
);
238 /****************************************************************/
240 typedef struct _insn_field insn_field
;
255 typedef struct _insn_fields insn_fields
;
256 struct _insn_fields
{
257 insn_field
*bits
[max_insn_size
];
264 parse_insn_format(table_entry
*entry
,
268 insn_fields
*fields
= ZALLOC(insn_fields
);
270 /* create a leading sentinal */
271 fields
->first
= ZALLOC(insn_field
);
272 fields
->first
->first
= -1;
273 fields
->first
->last
= -1;
274 fields
->first
->width
= 0;
276 /* and a trailing sentinal */
277 fields
->last
= ZALLOC(insn_field
);
278 fields
->last
->first
= insn_size
;
279 fields
->last
->last
= insn_size
;
280 fields
->last
->width
= 0;
282 /* link them together */
283 fields
->first
->next
= fields
->last
;
284 fields
->last
->prev
= fields
->first
;
286 /* now work through the formats */
289 while (*chp
!= '\0') {
294 insn_field
*new_field
;
297 if (!isdigit(*chp
)) {
298 error("%s:%d: missing position field at `%s'\n",
299 entry
->file_name
, entry
->line_nr
, chp
);
302 /* break out the bit position */
304 while (isdigit(*chp
))
306 strlen_pos
= chp
- start_pos
;
307 if (*chp
== '.' && strlen_pos
> 0)
310 error("%s:%d: missing field value at %s\n",
311 entry
->file_name
, entry
->line_nr
, chp
);
315 /* break out the value */
317 while ((*start_val
== '/' && *chp
== '/')
318 || (isdigit(*start_val
) && isdigit(*chp
))
319 || (isalpha(*start_val
) && (isalnum(*chp
) || *chp
== '_')))
321 strlen_val
= chp
- start_val
;
324 else if (*chp
!= '\0' || strlen_val
== 0) {
325 error("%s:%d: missing field terminator at %s\n",
326 entry
->file_name
, entry
->line_nr
, chp
);
330 /* create a new field and insert it */
331 new_field
= ZALLOC(insn_field
);
332 new_field
->next
= fields
->last
;
333 new_field
->prev
= fields
->last
->prev
;
334 new_field
->next
->prev
= new_field
;
335 new_field
->prev
->next
= new_field
;
338 new_field
->val_string
= (char*)zalloc(strlen_val
+1);
339 strncpy(new_field
->val_string
, start_val
, strlen_val
);
340 if (isdigit(*new_field
->val_string
)) {
341 new_field
->val_int
= a2i(new_field
->val_string
);
342 new_field
->is_int
= 1;
344 else if (new_field
->val_string
[0] == '/') {
345 new_field
->is_slash
= 1;
348 new_field
->is_string
= 1;
352 new_field
->pos_string
= (char*)zalloc(strlen_pos
+1);
353 strncpy(new_field
->pos_string
, start_pos
, strlen_pos
);
354 new_field
->first
= target_a2i(hi_bit_nr
, new_field
->pos_string
);
355 new_field
->last
= new_field
->next
->first
- 1; /* guess */
356 new_field
->width
= new_field
->last
- new_field
->first
+ 1; /* guess */
357 new_field
->prev
->last
= new_field
->first
-1; /*fix*/
358 new_field
->prev
->width
= new_field
->first
- new_field
->prev
->first
; /*fix*/
361 /* fiddle first/last so that the sentinals `disapear' */
362 ASSERT(fields
->first
->last
< 0);
363 ASSERT(fields
->last
->first
>= insn_size
);
364 fields
->first
= fields
->first
->next
;
365 fields
->last
= fields
->last
->prev
;
367 /* now go over this again, pointing each bit position at a field
372 field
= fields
->first
;
373 for (i
= 0; i
< insn_size
; i
++) {
374 while (field
->last
< i
)
376 fields
->bits
[i
] = field
;
380 /* go over each of the fields, and compute a `value' for the insn */
384 for (field
= fields
->first
;
385 field
->last
< insn_size
;
386 field
= field
->next
) {
387 fields
->value
<<= field
->width
;
389 fields
->value
|= field
->val_int
;
397 field_constant_int
= 1,
398 field_constant_slash
= 2,
399 field_constant_string
= 3
400 } constant_field_types
;
404 insn_field_is_constant(insn_field
*field
,
407 /* field is an integer */
409 return field_constant_int
;
410 /* field is `/' and treating that as a constant */
411 if (field
->is_slash
&& rule
->force_slash
)
412 return field_constant_slash
;
413 /* field, though variable is on the list */
414 if (field
->is_string
&& rule
->force_expansion
!= NULL
) {
415 char *forced_fields
= rule
->force_expansion
;
416 while (*forced_fields
!= '\0') {
418 char *end
= strchr(forced_fields
, ',');
420 field_len
= strlen(forced_fields
);
422 field_len
= end
-forced_fields
;
423 if (strncmp(forced_fields
, field
->val_string
, field_len
) == 0
424 && field
->val_string
[field_len
] == '\0')
425 return field_constant_string
;
426 forced_fields
+= field_len
;
427 if (*forced_fields
== ',')
436 dump_insn_field(insn_field
*field
,
440 printf("(insn_field*)0x%x\n", (unsigned)field
);
442 dumpf(indent
, "(first %d)\n", field
->first
);
444 dumpf(indent
, "(last %d)\n", field
->last
);
446 dumpf(indent
, "(width %d)\n", field
->width
);
449 dumpf(indent
, "(is_int %d)\n", field
->val_int
);
452 dumpf(indent
, "(is_slash)\n");
454 if (field
->is_string
)
455 dumpf(indent
, "(is_string `%s')\n", field
->val_string
);
457 dumpf(indent
, "(next 0x%x)\n", field
->next
);
459 dumpf(indent
, "(prev 0x%x)\n", field
->prev
);
465 dump_insn_fields(insn_fields
*fields
,
470 printf("(insn_fields*)%p\n", fields
);
472 dumpf(indent
, "(first 0x%x)\n", fields
->first
);
473 dumpf(indent
, "(last 0x%x)\n", fields
->last
);
475 dumpf(indent
, "(value 0x%x)\n", fields
->value
);
477 for (i
= 0; i
< insn_size
; i
++) {
478 dumpf(indent
, "(bits[%d] ", i
, fields
->bits
[i
]);
479 dump_insn_field(fields
->bits
[i
], indent
+1);
480 dumpf(indent
, " )\n");
486 /****************************************************************/
488 typedef struct _opcode_field opcode_field
;
489 struct _opcode_field
{
493 opcode_field
*parent
;
496 static opcode_field
*
499 opcode_field
*new_field
= (opcode_field
*)zalloc(sizeof(opcode_field
));
500 ASSERT(new_field
!= NULL
);
501 new_field
->first
= insn_size
;
502 new_field
->last
= -1;
507 dump_opcode_field(opcode_field
*field
, int indent
, int levels
)
509 printf("(opcode_field*)%p\n", field
);
510 if (levels
&& field
!= NULL
) {
511 dumpf(indent
, "(first %d)\n", field
->first
);
512 dumpf(indent
, "(last %d)\n", field
->last
);
513 dumpf(indent
, "(is_boolean %d)\n", field
->is_boolean
);
514 dumpf(indent
, "(parent ");
515 dump_opcode_field(field
->parent
, indent
, levels
-1);
520 /****************************************************************/
522 typedef struct _insn_bits insn_bits
;
527 opcode_field
*opcode
;
533 dump_insn_bits(insn_bits
*bits
, int indent
, int levels
)
535 printf("(insn_bits*)%p\n", bits
);
537 if (levels
&& bits
!= NULL
) {
538 dumpf(indent
, "(value %d)\n", bits
->value
);
539 dumpf(indent
, "(opcode ");
540 dump_opcode_field(bits
->opcode
, indent
+1, 0);
541 dumpf(indent
, " )\n");
542 dumpf(indent
, "(field ");
543 dump_insn_field(bits
->field
, indent
+1);
544 dumpf(indent
, " )\n");
545 dumpf(indent
, "(last ");
546 dump_insn_bits(bits
->last
, indent
+1, levels
-1);
551 /****************************************************************/
561 nr_insn_table_fields
,
563 char *insn_field_name
[nr_insn_table_fields
] = {
564 "format", "form", "flags", "nmemonic", "name", "comments"
568 function_type
= insn_format
,
569 function_name
= insn_name
,
570 function_param
= insn_comment
,
571 } function_table_fields
;
574 typedef struct _insn insn
;
576 table_entry
*file_entry
;
581 typedef struct _insn_table insn_table
;
584 insn_bits
*expanded_bits
;
588 opcode_rules
*opcode_rule
;
589 opcode_field
*opcode
;
599 insn_table_insert_function(insn_table
*table
,
600 table_entry
*file_entry
)
602 insn
**ptr_to_cur_function
= &table
->functions
;
604 /* create a new function */
605 insn
*new_function
= ZALLOC(insn
);
606 new_function
->file_entry
= file_entry
;
608 /* append it to the end of the function list */
609 while (*ptr_to_cur_function
!= NULL
) {
610 ptr_to_cur_function
= &(*ptr_to_cur_function
)->next
;
612 *ptr_to_cur_function
= new_function
;
617 insn_table_insert_insn(insn_table
*table
,
618 table_entry
*file_entry
,
621 insn
**ptr_to_cur_insn
= &table
->insns
;
622 insn
*cur_insn
= *ptr_to_cur_insn
;
624 /* create a new instruction */
625 insn
*new_insn
= ZALLOC(insn
);
626 new_insn
->file_entry
= file_entry
;
627 new_insn
->fields
= fields
;
629 /* insert it according to the order of the fields */
630 while (cur_insn
!= NULL
631 && new_insn
->fields
->value
>= cur_insn
->fields
->value
) {
632 ptr_to_cur_insn
= &cur_insn
->next
;
633 cur_insn
= *ptr_to_cur_insn
;
636 new_insn
->next
= cur_insn
;
637 *ptr_to_cur_insn
= new_insn
;
643 static opcode_field
*
644 insn_table_find_opcode_field(insn
*insns
,
648 opcode_field
*curr_opcode
= opcode_field_new();
653 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
) {
654 insn_fields
*fields
= entry
->fields
;
655 opcode_field new_opcode
;
657 /* find a start point for the opcode field */
658 new_opcode
.first
= rule
->first
;
659 while (new_opcode
.first
<= rule
->last
661 || insn_field_is_constant(fields
->bits
[new_opcode
.first
],
662 rule
) != field_constant_string
)
664 || !insn_field_is_constant(fields
->bits
[new_opcode
.first
],
666 new_opcode
.first
= fields
->bits
[new_opcode
.first
]->last
+ 1;
667 ASSERT(new_opcode
.first
> rule
->last
669 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
670 rule
) == field_constant_string
)
672 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
675 /* find the end point for the opcode field */
676 new_opcode
.last
= rule
->last
;
677 while (new_opcode
.last
>= rule
->first
679 || insn_field_is_constant(fields
->bits
[new_opcode
.last
],
680 rule
) != field_constant_string
)
682 || !insn_field_is_constant(fields
->bits
[new_opcode
.last
],
684 new_opcode
.last
= fields
->bits
[new_opcode
.last
]->first
- 1;
685 ASSERT(new_opcode
.last
< rule
->first
687 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
688 rule
) == field_constant_string
)
690 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
693 /* now see if our current opcode needs expanding */
694 if (new_opcode
.first
<= rule
->last
695 && curr_opcode
->first
> new_opcode
.first
)
696 curr_opcode
->first
= new_opcode
.first
;
697 if (new_opcode
.last
>= rule
->first
698 && curr_opcode
->last
< new_opcode
.last
)
699 curr_opcode
->last
= new_opcode
.last
;
703 /* was any thing interesting found? */
704 if (curr_opcode
->first
> rule
->last
) {
705 ASSERT(curr_opcode
->last
< rule
->first
);
708 ASSERT(curr_opcode
->last
>= rule
->first
);
709 ASSERT(curr_opcode
->first
<= rule
->last
);
711 /* if something was found, check it includes the forced field range */
713 && curr_opcode
->first
> rule
->force_first
) {
714 curr_opcode
->first
= rule
->force_first
;
717 && curr_opcode
->last
< rule
->force_last
) {
718 curr_opcode
->last
= rule
->force_last
;
720 /* handle special case elminating any need to do shift after mask */
722 && rule
->force_last
== insn_size
-1) {
723 curr_opcode
->last
= insn_size
-1;
726 /* handle any special cases */
727 switch (rule
->special_rule
) {
728 case 0: /* let the above apply */
730 case 1: /* expand a limited nr of bits, ignoring the rest */
731 curr_opcode
->first
= rule
->force_first
;
732 curr_opcode
->last
= rule
->force_last
;
734 case 2: /* boolean field */
735 curr_opcode
->is_boolean
= 1;
744 insn_table_insert_expanded(insn_table
*table
,
749 insn_table
**ptr_to_cur_entry
= &table
->entries
;
750 insn_table
*cur_entry
= *ptr_to_cur_entry
;
752 /* find the new table for this entry */
753 while (cur_entry
!= NULL
754 && cur_entry
->opcode_nr
< new_opcode_nr
) {
755 ptr_to_cur_entry
= &cur_entry
->sibling
;
756 cur_entry
= *ptr_to_cur_entry
;
759 if (cur_entry
== NULL
|| cur_entry
->opcode_nr
!= new_opcode_nr
) {
760 insn_table
*new_entry
= ZALLOC(insn_table
);
761 new_entry
->opcode_nr
= new_opcode_nr
;
762 new_entry
->expanded_bits
= new_bits
;
763 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
764 new_entry
->sibling
= cur_entry
;
765 new_entry
->parent
= table
;
766 *ptr_to_cur_entry
= new_entry
;
767 cur_entry
= new_entry
;
770 /* ASSERT new_bits == cur_entry bits */
771 ASSERT(cur_entry
!= NULL
&& cur_entry
->opcode_nr
== new_opcode_nr
);
772 insn_table_insert_insn(cur_entry
,
773 old_insn
->file_entry
,
778 insn_table_expand_opcode(insn_table
*table
,
785 if (field_nr
> table
->opcode
->last
) {
786 insn_table_insert_expanded(table
, instruction
, opcode_nr
, bits
);
789 insn_field
*field
= instruction
->fields
->bits
[field_nr
];
790 if (field
->is_int
|| field
->is_slash
) {
791 ASSERT(field
->first
>= table
->opcode
->first
792 && field
->last
<= table
->opcode
->last
);
793 insn_table_expand_opcode(table
, instruction
, field
->last
+1,
794 ((opcode_nr
<< field
->width
) + field
->val_int
),
799 int last_pos
= ((field
->last
< table
->opcode
->last
)
800 ? field
->last
: table
->opcode
->last
);
801 int first_pos
= ((field
->first
> table
->opcode
->first
)
802 ? field
->first
: table
->opcode
->first
);
803 int width
= last_pos
- first_pos
+ 1;
804 int last_val
= (table
->opcode
->is_boolean
806 for (val
= 0; val
< last_val
; val
++) {
807 insn_bits
*new_bits
= ZALLOC(insn_bits
);
808 new_bits
->field
= field
;
809 new_bits
->value
= val
;
810 new_bits
->last
= bits
;
811 new_bits
->opcode
= table
->opcode
;
812 insn_table_expand_opcode(table
, instruction
, last_pos
+1,
813 ((opcode_nr
<< width
) | val
),
821 insn_table_insert_expanding(insn_table
*table
,
824 insn_table_expand_opcode(table
,
826 table
->opcode
->first
,
828 table
->expanded_bits
);
833 insn_table_expand_insns(insn_table
*table
)
836 ASSERT(table
->nr_insn
>= 1);
838 /* determine a valid opcode */
839 while (table
->opcode_rule
) {
840 /* specials only for single instructions */
841 if ((table
->nr_insn
> 1
842 && table
->opcode_rule
->special_mask
== 0
843 && table
->opcode_rule
->special_rule
== 0)
844 || (table
->nr_insn
== 1
845 && table
->opcode_rule
->special_mask
!= 0
846 && ((table
->insns
->fields
->value
847 & table
->opcode_rule
->special_mask
)
848 == table
->opcode_rule
->special_value
))
849 || (idecode_expand_semantics
850 && table
->opcode_rule
->special_mask
== 0
851 && table
->opcode_rule
->special_rule
== 0))
853 insn_table_find_opcode_field(table
->insns
,
855 table
->nr_insn
== 1/*string*/
857 if (table
->opcode
!= NULL
)
859 table
->opcode_rule
= table
->opcode_rule
->next
;
862 /* did we find anything */
863 if (table
->opcode
== NULL
) {
866 ASSERT(table
->opcode
!= NULL
);
868 /* back link what we found to its parent */
869 if (table
->parent
!= NULL
) {
870 ASSERT(table
->parent
->opcode
!= NULL
);
871 table
->opcode
->parent
= table
->parent
->opcode
;
874 /* expand the raw instructions according to the opcode */
877 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
) {
878 insn_table_insert_expanding(table
, entry
);
882 /* and do the same for the sub entries */
885 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
) {
886 insn_table_expand_insns(entry
);
894 insn_table_load_insns(char *file_name
)
896 table
*file
= table_open(file_name
, nr_insn_table_fields
);
897 insn_table
*table
= ZALLOC(insn_table
);
898 table_entry
*file_entry
;
899 table
->opcode_rule
= opcode_table
;
901 while ((file_entry
= table_entry_read(file
)) != NULL
) {
902 if (it_is("function", file_entry
->fields
[insn_flags
])
903 || it_is("internal", file_entry
->fields
[insn_flags
])) {
904 insn_table_insert_function(table
, file_entry
);
908 /* skip instructions that aren't relevant to the mode */
909 filter
*filt
= filters
;
910 while (filt
!= NULL
) {
911 if (it_is(filt
->flag
, file_entry
->fields
[insn_flags
]))
916 /* create/insert the new instruction */
917 fields
= parse_insn_format(file_entry
,
918 file_entry
->fields
[insn_format
]);
919 insn_table_insert_insn(table
, file_entry
, fields
);
928 dump_insn(insn
*entry
, int indent
, int levels
)
930 printf("(insn*)%p\n", entry
);
932 if (levels
&& entry
!= NULL
) {
934 dumpf(indent
, "(file_entry ");
935 dump_table_entry(entry
->file_entry
, indent
+1);
936 dumpf(indent
, " )\n");
938 dumpf(indent
, "(fields ");
939 dump_insn_fields(entry
->fields
, indent
+1);
940 dumpf(indent
, " )\n");
942 dumpf(indent
, "(next ");
943 dump_insn(entry
->next
, indent
+1, levels
-1);
944 dumpf(indent
, " )\n");
952 dump_insn_table(insn_table
*table
,
953 int indent
, int levels
)
956 printf("(insn_table*)%p\n", table
);
958 if (levels
&& table
!= NULL
) {
960 dumpf(indent
, "(opcode_nr %d)\n", table
->opcode_nr
);
962 dumpf(indent
, "(expanded_bits ");
963 dump_insn_bits(table
->expanded_bits
, indent
+1, -1);
964 dumpf(indent
, " )\n");
966 dumpf(indent
, "(int nr_insn %d)\n", table
->nr_insn
);
968 dumpf(indent
, "(insns ");
969 dump_insn(table
->insns
, indent
+1, table
->nr_insn
);
970 dumpf(indent
, " )\n");
972 dumpf(indent
, "(opcode_rule ");
973 dump_opcode_rule(table
->opcode_rule
, indent
+1);
974 dumpf(indent
, " )\n");
976 dumpf(indent
, "(opcode ");
977 dump_opcode_field(table
->opcode
, indent
+1, 1);
978 dumpf(indent
, " )\n");
980 dumpf(indent
, "(nr_entries %d)\n", table
->entries
);
981 dumpf(indent
, "(entries ");
982 dump_insn_table(table
->entries
, indent
+1, table
->nr_entries
);
983 dumpf(indent
, " )\n");
985 dumpf(indent
, "(sibling ", table
->sibling
);
986 dump_insn_table(table
->sibling
, indent
+1, levels
-1);
987 dumpf(indent
, " )\n");
989 dumpf(indent
, "(parent ", table
->parent
);
990 dump_insn_table(table
->parent
, indent
+1, 0);
991 dumpf(indent
, " )\n");
997 /****************************************************************/
1001 lf_print_insn_bits(lf
*file
, insn_bits
*bits
)
1005 lf_print_insn_bits(file
, bits
->last
);
1006 lf_putchr(file
, '_');
1007 lf_putstr(file
, bits
->field
->val_string
);
1008 if (!bits
->opcode
->is_boolean
|| bits
->value
== 0) {
1009 if (bits
->opcode
->last
< bits
->field
->last
)
1010 lf_putint(file
, bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1012 lf_putint(file
, bits
->value
);
1017 lf_print_opcodes(lf
*file
,
1020 if (table
!= NULL
) {
1022 lf_printf(file
, "_%d_%d",
1023 table
->opcode
->first
,
1024 table
->opcode
->last
);
1025 if (table
->parent
== NULL
) break;
1026 lf_printf(file
, "__%d", table
->opcode_nr
);
1027 table
= table
->parent
;
1033 lf_print_table_name(lf
*file
,
1036 lf_printf(file
, "idecode_table");
1037 lf_print_opcodes(file
, table
);
1043 function_name_prefix_semantics
,
1044 function_name_prefix_idecode
,
1045 function_name_prefix_itable
,
1046 function_name_prefix_none
1047 } lf_function_name_prefixes
;
1050 lf_print_function_name(lf
*file
,
1052 insn_bits
*expanded_bits
,
1053 lf_function_name_prefixes prefix
)
1058 case function_name_prefix_semantics
:
1059 lf_putstr(file
, "semantic_");
1061 case function_name_prefix_idecode
:
1062 lf_printf(file
, "idecode_");
1064 case function_name_prefix_itable
:
1065 lf_putstr(file
, "itable_");
1071 /* the function name */
1074 for (pos
= basename
;
1082 lf_putchr(file
, '_');
1085 lf_putchr(file
, *pos
);
1092 if (idecode_expand_semantics
)
1093 lf_print_insn_bits(file
, expanded_bits
);
1098 lf_print_idecode_table(lf
*file
,
1101 int can_assume_leaf
;
1102 opcode_rules
*opcode_rule
;
1104 /* have a look at the rule table, if all table rules follow all
1105 switch rules, I can assume that all end points are leaves */
1106 opcode_rule
= opcode_table
;
1107 while (opcode_rule
!= NULL
1108 && opcode_rule
->use_switch
)
1109 opcode_rule
= opcode_rule
->next
;
1110 while (opcode_rule
!= NULL
1111 && opcode_rule
->use_switch
1112 && opcode_rule
->special_rule
)
1113 opcode_rule
= opcode_rule
->next
;
1114 can_assume_leaf
= opcode_rule
== NULL
;
1116 lf_printf(file
, "{\n");
1117 lf_indent(file
, +2);
1119 lf_printf(file
, "idecode_table_entry *table = ");
1120 lf_print_table_name(file
, entry
);
1121 lf_printf(file
, ";\n");
1122 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1123 i2target(hi_bit_nr
, entry
->opcode
->first
),
1124 i2target(hi_bit_nr
, entry
->opcode
->last
));
1125 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
1126 lf_printf(file
, "while (1) {\n");
1127 lf_indent(file
, +2);
1129 lf_printf(file
, "while (table_entry->mask != 0) {\n");
1130 lf_indent(file
, +2);
1132 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1133 lf_printf(file
, " table_entry->function_or_table);\n");
1134 lf_printf(file
, "opcode = ((instruction & table_entry->mask)\n");
1135 lf_printf(file
, " >> table_entry->shift);\n");
1136 lf_printf(file
, "table_entry = table + opcode;\n");
1138 lf_indent(file
, -2);
1139 lf_printf(file
, "}\n");
1140 if (!idecode_cache
&& can_assume_leaf
) {
1141 lf_printf(file
, "return (((idecode_semantic*)\n");
1142 lf_printf(file
, " table_entry->function_or_table)\n");
1143 lf_printf(file
, " (%s));\n", semantic_actual
);
1145 else if (!idecode_cache
&& !can_assume_leaf
) {
1146 lf_printf(file
, "if (table_entry->shift == 0)");
1147 lf_printf(file
, " return (((idecode_semantic*)\n");
1148 lf_printf(file
, " table_entry->function_or_table)\n");
1149 lf_printf(file
, " (%s));\n", semantic_actual
);
1152 lf_printf(file
, "if (table_entry->shift == 0)\n");
1153 lf_printf(file
, " return (((idecode_crack*)\n");
1154 lf_printf(file
, " table_entry->function_or_table)\n");
1155 lf_printf(file
, " (%s));\n", cache_idecode_actual
);
1157 if (!can_assume_leaf
) {
1158 lf_printf(file
, "opcode = (instruction & table_entry->shift) != 0;\n");
1159 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1160 lf_printf(file
, " table_entry->function_or_table);\n");
1161 lf_printf(file
, "table_entry = table + opcode;\n");
1164 lf_indent(file
, -2);
1165 lf_printf(file
, "}\n");
1167 lf_indent(file
, -2);
1168 lf_printf(file
, "}\n");
1173 lf_print_my_prefix(lf
*file
,
1174 table_entry
*file_entry
,
1177 lf_printf(file
, "const char *const my_prefix = \n");
1178 lf_printf(file
, " \"%s:%s:%s:%d\";\n",
1179 filter_filename (file_entry
->file_name
),
1180 (idecode
? "idecode" : "semantics"),
1181 file_entry
->fields
[insn_name
],
1182 file_entry
->line_nr
);
1187 lf_print_ptrace(lf
*file
,
1190 lf_printf(file
, "\n");
1191 lf_printf(file
, "ITRACE(trace_%s, (\"\\n\"));\n",
1192 (idecode
? "idecode" : "semantics"));
1196 /****************************************************************/
1198 typedef void leaf_handler
1202 typedef void padding_handler
1210 insn_table_traverse_tree(insn_table
*table
,
1213 leaf_handler
*start
,
1216 padding_handler
*padding
)
1221 ASSERT(table
!= NULL
1222 && table
->opcode
!= NULL
1223 && table
->nr_entries
> 0
1224 && table
->entries
!= 0);
1226 if (start
!= NULL
&& depth
>= 0)
1227 start(table
, data
, depth
);
1229 for (entry_nr
= 0, entry
= table
->entries
;
1230 entry_nr
< (table
->opcode
->is_boolean
1232 : (1 << (table
->opcode
->last
- table
->opcode
->first
+ 1)));
1235 || (!table
->opcode
->is_boolean
1236 && entry_nr
< entry
->opcode_nr
)) {
1237 if (padding
!= NULL
&& depth
>= 0)
1238 padding(table
, data
, depth
, entry_nr
);
1241 ASSERT(entry
!= NULL
&& (entry
->opcode_nr
== entry_nr
1242 || table
->opcode
->is_boolean
));
1243 if (entry
->opcode
!= NULL
&& depth
!= 0) {
1244 insn_table_traverse_tree(entry
, data
, depth
+1,
1245 start
, leaf
, end
, padding
);
1247 else if (depth
>= 0) {
1249 leaf(entry
, data
, depth
);
1251 entry
= entry
->sibling
;
1254 if (end
!= NULL
&& depth
>= 0)
1255 end(table
, data
, depth
);
1259 typedef void function_handler
1262 table_entry
*function
);
1265 insn_table_traverse_function(insn_table
*table
,
1267 function_handler
*leaf
)
1270 for (function
= table
->functions
;
1272 function
= function
->next
) {
1273 leaf(table
, data
, function
->file_entry
);
1278 typedef void insn_handler
1284 insn_table_traverse_insn(insn_table
*table
,
1289 for (instruction
= table
->insns
;
1290 instruction
!= NULL
;
1291 instruction
= instruction
->next
) {
1292 leaf(table
, data
, instruction
);
1298 update_depth(insn_table
*entry
,
1302 int *max_depth
= (int*)data
;
1303 if (*max_depth
< depth
)
1309 insn_table_depth(insn_table
*table
)
1312 insn_table_traverse_tree(table
,
1323 /****************************************************************/
1326 dump_traverse_start(insn_table
*table
,
1330 dumpf(depth
*2, "(%d\n", table
->opcode_nr
);
1334 dump_traverse_leaf(insn_table
*entry
,
1338 ASSERT(entry
->nr_entries
== 0
1339 && entry
->nr_insn
== 1
1340 && entry
->opcode
== NULL
);
1341 dumpf(depth
*2, ".%d %s\n", entry
->opcode_nr
,
1342 entry
->insns
->file_entry
->fields
[insn_format
]);
1346 dump_traverse_end(insn_table
*table
,
1350 dumpf(depth
*2, ")\n");
1354 dump_traverse_padding(insn_table
*table
,
1359 dumpf(depth
*2, ".<%d>\n", opcode_nr
);
1364 dump_traverse(insn_table
*table
)
1366 insn_table_traverse_tree(table
, NULL
, 1,
1367 dump_traverse_start
,
1370 dump_traverse_padding
);
1374 /****************************************************************/
1378 semantics_h_print_function(lf
*file
,
1380 insn_bits
*expanded_bits
)
1382 lf_printf(file
, "\n");
1383 lf_printf(file
, "INLINE_SEMANTICS unsigned_word ");
1384 lf_print_function_name(file
,
1387 function_name_prefix_semantics
);
1388 lf_printf(file
, "\n(%s);\n",
1389 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
1394 semantics_h_leaf(insn_table
*entry
,
1398 lf
*file
= (lf
*)data
;
1399 ASSERT(entry
->nr_insn
== 1);
1400 semantics_h_print_function(file
,
1401 entry
->insns
->file_entry
->fields
[insn_name
],
1402 entry
->expanded_bits
);
1406 semantics_h_insn(insn_table
*entry
,
1410 lf
*file
= (lf
*)data
;
1411 semantics_h_print_function(file
,
1412 instruction
->file_entry
->fields
[insn_name
],
1417 semantics_h_function(insn_table
*entry
,
1419 table_entry
*function
)
1421 lf
*file
= (lf
*)data
;
1422 if (function
->fields
[function_type
] == NULL
1423 || function
->fields
[function_type
][0] == '\0') {
1424 semantics_h_print_function(file
,
1425 function
->fields
[function_name
],
1429 lf_printf(file
, "\n");
1430 lf_printf(file
, "INLINE_SEMANTICS %s %s\n(%s);\n",
1431 function
->fields
[function_type
],
1432 function
->fields
[function_name
],
1433 function
->fields
[function_param
]);
1439 gen_semantics_h(insn_table
*table
, lf
*file
)
1442 lf_print_copyleft(file
);
1443 lf_printf(file
, "\n");
1444 lf_printf(file
, "#ifndef _SEMANTICS_H_\n");
1445 lf_printf(file
, "#define _SEMANTICS_H_\n");
1446 lf_printf(file
, "\n");
1447 lf_printf(file
, "#ifndef INLINE_SEMANTICS\n");
1448 lf_printf(file
, "#define INLINE_SEMANTICS\n");
1449 lf_printf(file
, "#endif\n");
1450 lf_printf(file
, "\n");
1451 lf_printf(file
, "\n");
1453 /* output a declaration for all functions */
1454 insn_table_traverse_function(table
,
1456 semantics_h_function
);
1458 /* output a declaration for all instructions */
1459 if (idecode_expand_semantics
)
1460 insn_table_traverse_tree(table
,
1464 semantics_h_leaf
, /* leaf */
1466 NULL
); /* padding */
1468 insn_table_traverse_insn(table
,
1472 lf_printf(file
, "\n");
1473 lf_printf(file
, "#endif /* _SEMANTICS_H_ */\n");
1477 /****************************************************************/
1479 typedef struct _icache_tree icache_tree
;
1480 struct _icache_tree
{
1483 icache_tree
*children
;
1486 static icache_tree
*
1487 icache_tree_insert(icache_tree
*tree
,
1490 icache_tree
*new_tree
;
1492 icache_tree
**ptr_to_cur_tree
= &tree
->children
;
1493 icache_tree
*cur_tree
= *ptr_to_cur_tree
;
1494 while (cur_tree
!= NULL
1495 && strcmp(cur_tree
->name
, name
) < 0) {
1496 ptr_to_cur_tree
= &cur_tree
->next
;
1497 cur_tree
= *ptr_to_cur_tree
;
1499 ASSERT(cur_tree
== NULL
1500 || strcmp(cur_tree
->name
, name
) >= 0);
1501 /* already in the tree */
1502 if (cur_tree
!= NULL
1503 && strcmp(cur_tree
->name
, name
) == 0)
1505 /* missing, insert it */
1506 ASSERT(cur_tree
== NULL
1507 || strcmp(cur_tree
->name
, name
) > 0);
1508 new_tree
= ZALLOC(icache_tree
);
1509 new_tree
->name
= name
;
1510 new_tree
->next
= cur_tree
;
1511 *ptr_to_cur_tree
= new_tree
;
1516 static icache_tree
*
1517 insn_table_cache_fields(insn_table
*table
)
1519 icache_tree
*tree
= ZALLOC(icache_tree
);
1521 for (instruction
= table
->insns
;
1522 instruction
!= NULL
;
1523 instruction
= instruction
->next
) {
1526 icache_tree_insert(tree
,
1527 instruction
->file_entry
->fields
[insn_form
]);
1528 for (field
= instruction
->fields
->first
;
1530 field
= field
->next
) {
1531 if (field
->is_string
)
1532 icache_tree_insert(form
, field
->val_string
);
1541 gen_icache_h(icache_tree
*tree
,
1544 lf_print_copyleft(file
);
1545 lf_printf(file
, "\n");
1546 lf_printf(file
, "#ifndef _ICACHE_H_\n");
1547 lf_printf(file
, "#define _ICACHE_H_\n");
1548 lf_printf(file
, "\n");
1549 lf_printf(file
, "#ifndef INLINE_ICACHE\n");
1550 lf_printf(file
, "#define INLINE_ICACHE\n");
1551 lf_printf(file
, "#endif\n");
1552 lf_printf(file
, "\n");
1554 lf_printf(file
, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1556 lf_printf(file
, "\n");
1558 /* create an instruction cache if being used */
1559 if (idecode_cache
) {
1561 lf_printf(file
, "typedef struct _idecode_cache {\n");
1562 lf_printf(file
, " unsigned_word address;\n");
1563 lf_printf(file
, " void *semantic;\n");
1564 lf_printf(file
, " union {\n");
1565 for (form
= tree
->children
;
1567 form
= form
->next
) {
1569 lf_printf(file
, " struct {\n");
1570 for (field
= form
->children
;
1572 field
= field
->next
) {
1573 cache_rules
*cache_rule
;
1575 for (cache_rule
= cache_table
;
1577 cache_rule
= cache_rule
->next
) {
1578 if (strcmp(field
->name
, cache_rule
->old_name
) == 0) {
1580 if (cache_rule
->new_name
!= NULL
)
1581 lf_printf(file
, " %s %s; /* %s */\n",
1582 (cache_rule
->type
== NULL
1584 : cache_rule
->type
),
1585 cache_rule
->new_name
,
1586 cache_rule
->old_name
);
1590 lf_printf(file
, " unsigned %s;\n", field
->name
);
1592 lf_printf(file
, " } %s;\n", form
->name
);
1594 lf_printf(file
, " } crack;\n");
1595 lf_printf(file
, "} idecode_cache;\n");
1598 /* alernativly, since no cache, #define the fields to be
1599 extractions from the instruction variable */
1600 cache_rules
*cache_rule
;
1601 lf_printf(file
, "\n");
1602 for (cache_rule
= cache_table
;
1604 cache_rule
= cache_rule
->next
) {
1605 if (cache_rule
->expression
!= NULL
1606 && strlen(cache_rule
->expression
) > 0)
1607 lf_printf(file
, "#define %s %s\n",
1608 cache_rule
->new_name
, cache_rule
->expression
);
1612 lf_printf(file
, "\n");
1613 lf_printf(file
, "#endif /* _ICACHE_H_ */\n");
1619 /****************************************************************/
1623 lf_print_c_extraction(lf
*file
,
1627 char *field_expression
,
1628 insn_field
*cur_field
,
1630 int get_value_from_cache
,
1631 int put_value_in_cache
)
1633 ASSERT(field_name
!= NULL
);
1635 && (!bits
->opcode
->is_boolean
|| bits
->value
== 0)
1636 && strcmp(field_name
, cur_field
->val_string
) == 0) {
1637 ASSERT(bits
->field
== cur_field
);
1638 ASSERT(field_type
== NULL
);
1639 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1640 lf_printf(file
, "const unsigned %s = ",
1642 if (bits
->opcode
->last
< bits
->field
->last
)
1643 lf_printf(file
, "%d;\n",
1644 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1646 lf_printf(file
, "%d;\n", bits
->value
);
1649 /* put the field in the local variable */
1650 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1651 lf_printf(file
, "%s const %s = ",
1652 field_type
== NULL
? "unsigned" : field_type
,
1654 /* getting it from the cache */
1655 if (get_value_from_cache
|| put_value_in_cache
) {
1656 lf_printf(file
, "cache_entry->crack.%s.%s",
1657 instruction
->file_entry
->fields
[insn_form
],
1659 if (put_value_in_cache
) /* also put it in the cache? */
1660 lf_printf(file
, " = ");
1662 if (!get_value_from_cache
) {
1663 if (strcmp(field_name
, cur_field
->val_string
) == 0)
1664 lf_printf(file
, "EXTRACTED32(instruction, %d, %d)",
1665 i2target(hi_bit_nr
, cur_field
->first
),
1666 i2target(hi_bit_nr
, cur_field
->last
));
1667 else if (field_expression
!= NULL
)
1668 lf_printf(file
, "%s", field_expression
);
1670 lf_printf(file
, "eval_%s", field_name
);
1672 lf_printf(file
, ";\n");
1678 lf_print_c_extractions(lf
*file
,
1680 insn_bits
*expanded_bits
,
1681 int get_value_from_cache
,
1682 int put_value_in_cache
)
1684 insn_field
*cur_field
;
1686 /* extract instruction fields */
1687 lf_printf(file
, "/* extraction: %s */\n",
1688 instruction
->file_entry
->fields
[insn_format
]);
1690 for (cur_field
= instruction
->fields
->first
;
1691 cur_field
->first
< insn_size
;
1692 cur_field
= cur_field
->next
) {
1693 if (cur_field
->is_string
) {
1696 /* find any corresponding value */
1697 for (bits
= expanded_bits
;
1699 bits
= bits
->last
) {
1700 if (bits
->field
== cur_field
)
1703 /* try the cache rule table for what to do */
1704 if (get_value_from_cache
|| put_value_in_cache
) {
1705 cache_rules
*cache_rule
;
1706 for (cache_rule
= cache_table
;
1708 cache_rule
= cache_rule
->next
) {
1709 if (strcmp(cur_field
->val_string
, cache_rule
->old_name
) == 0) {
1711 if (cache_rule
->valid
> 1 && put_value_in_cache
)
1712 lf_print_c_extraction(file
,
1714 cache_rule
->new_name
,
1716 cache_rule
->expression
,
1721 else if (cache_rule
->valid
== 1)
1722 lf_print_c_extraction(file
,
1724 cache_rule
->new_name
,
1726 cache_rule
->expression
,
1729 get_value_from_cache
,
1730 put_value_in_cache
);
1734 if (found_rule
== 0)
1735 lf_print_c_extraction(file
,
1737 cur_field
->val_string
,
1742 get_value_from_cache
,
1743 put_value_in_cache
);
1744 /* if any (XXX == 0), output a corresponding test */
1745 if (instruction
->file_entry
->annex
!= NULL
) {
1746 char *field_name
= cur_field
->val_string
;
1747 char *is_0_ptr
= instruction
->file_entry
->annex
;
1748 int field_len
= strlen(field_name
);
1749 if (strlen(is_0_ptr
) >= (strlen("_is_0") + field_len
)) {
1750 is_0_ptr
+= field_len
;
1751 while ((is_0_ptr
= strstr(is_0_ptr
, "_is_0")) != NULL
) {
1752 if (strncmp(is_0_ptr
- field_len
, field_name
, field_len
) == 0
1753 && !isalpha(is_0_ptr
[ - field_len
- 1])) {
1754 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1755 lf_printf(file
, "const unsigned %s_is_0 = (", field_name
);
1757 lf_printf(file
, "%d", bits
->value
);
1759 lf_printf(file
, "%s", field_name
);
1760 lf_printf(file
, " == 0);\n");
1763 is_0_ptr
+= strlen("_is_0");
1767 /* any thing else ... */
1770 lf_print_lf_c_line_nr(file
);
1775 lf_print_idecode_illegal(lf
*file
)
1778 lf_printf(file
, "return idecode_illegal(%s);\n", cache_idecode_actual
);
1780 lf_printf(file
, "return semantic_illegal(%s);\n", semantic_actual
);
1785 lf_print_idecode_floating_point_unavailable(lf
*file
)
1788 lf_printf(file
, "return idecode_floating_point_unavailable(%s);\n",
1789 cache_idecode_actual
);
1791 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
1796 /* Output code to do any final checks on the decoded instruction.
1797 This includes things like verifying any on decoded fields have the
1798 correct value and checking that (for floating point) floating point
1799 hardware isn't disabled */
1802 lf_print_c_validate(lf
*file
,
1804 opcode_field
*opcodes
)
1806 /* Validate: unchecked instruction fields
1808 If any constant fields in the instruction were not checked by the
1809 idecode tables, output code to check that they have the correct
1812 unsigned check_mask
= 0;
1813 unsigned check_val
= 0;
1815 opcode_field
*opcode
;
1817 /* form check_mask/check_val containing what needs to be checked
1818 in the instruction */
1819 for (field
= instruction
->fields
->first
;
1820 field
->first
< insn_size
;
1821 field
= field
->next
) {
1823 check_mask
<<= field
->width
;
1824 check_val
<<= field
->width
;
1826 /* is it a constant that could need validating? */
1827 if (!field
->is_int
&& !field
->is_slash
)
1830 /* has it been checked by a table? */
1831 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1832 if (field
->first
>= opcode
->first
1833 && field
->last
<= opcode
->last
)
1839 check_mask
|= (1 << field
->width
)-1;
1840 check_val
|= field
->val_int
;
1843 /* if any bits not checked by opcode tables, output code to check them */
1845 lf_printf(file
, "\n");
1846 lf_printf(file
, "/* validate: %s */\n",
1847 instruction
->file_entry
->fields
[insn_format
]);
1848 lf_printf(file
, "if ((instruction & 0x%x) != 0x%x)\n",
1849 check_mask
, check_val
);
1850 lf_indent(file
, +2);
1851 lf_print_idecode_illegal(file
);
1852 lf_indent(file
, -2);
1856 /* Validate floating point hardware
1858 If the simulator is being built with out floating point hardware
1859 (different to it being disabled in the MSR) then floating point
1860 instructions are invalid */
1862 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1863 lf_printf(file
, "\n");
1864 lf_printf(file
, "/* Validate: FP hardware exists */\n");
1865 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1866 lf_indent(file
, +2);
1867 lf_print_idecode_illegal(file
);
1868 lf_indent(file
, -2);
1872 /* Validate: Floating Point available
1874 If floating point is not available, we enter a floating point
1875 unavailable interrupt into the cache instead of the instruction
1878 The PowerPC spec requires a CSI after MSR[FP] is changed and when
1879 ever a CSI occures we flush the instruction cache. */
1882 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1883 lf_printf(file
, "\n");
1884 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
1885 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
1886 lf_indent(file
, +2);
1887 lf_print_idecode_floating_point_unavailable(file
);
1888 lf_indent(file
, -2);
1895 lf_print_c_cracker(lf
*file
,
1897 insn_bits
*expanded_bits
,
1898 opcode_field
*opcodes
)
1901 /* function header */
1902 lf_printf(file
, "{\n");
1903 lf_indent(file
, +2);
1905 lf_print_my_prefix(file
,
1906 instruction
->file_entry
,
1907 1/*putting-value-in-cache*/);
1909 lf_print_ptrace(file
,
1910 1/*putting-value-in-cache*/);
1912 lf_print_c_validate(file
, instruction
, opcodes
);
1914 lf_printf(file
, "\n");
1915 lf_printf(file
, "{\n");
1916 lf_indent(file
, +2);
1917 lf_print_c_extractions(file
,
1920 0/*get_value_from_cache*/,
1921 1/*put_value_in_cache*/);
1922 lf_indent(file
, -2);
1923 lf_printf(file
, "}\n");
1925 /* return the function propper (main sorts this one out) */
1926 lf_printf(file
, "\n");
1927 lf_printf(file
, "/* semantic routine */\n");
1928 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1929 lf_printf(file
, "return ");
1930 lf_print_function_name(file
,
1931 instruction
->file_entry
->fields
[insn_name
],
1933 function_name_prefix_semantics
);
1934 lf_printf(file
, ";\n");
1936 lf_print_lf_c_line_nr(file
);
1937 lf_indent(file
, -2);
1938 lf_printf(file
, "}\n");
1943 lf_print_c_semantic(lf
*file
,
1945 insn_bits
*expanded_bits
,
1946 opcode_field
*opcodes
)
1949 lf_printf(file
, "{\n");
1950 lf_indent(file
, +2);
1952 lf_print_my_prefix(file
,
1953 instruction
->file_entry
,
1954 0/*not putting value in cache*/);
1955 lf_printf(file
, "unsigned_word nia = cia + %d;\n", insn_size
/ 8);
1957 lf_printf(file
, "\n");
1958 lf_print_c_extractions(file
,
1961 idecode_cache
/*get_value_from_cache*/,
1962 0/*put_value_in_cache*/);
1964 lf_print_ptrace(file
,
1965 0/*put_value_in_cache*/);
1967 /* validate the instruction, if a cache this has already been done */
1969 lf_print_c_validate(file
, instruction
, opcodes
);
1971 /* generate the profileing call - this is delayed until after the
1972 instruction has been verified */
1973 lf_printf(file
, "\n");
1974 lf_printf(file
, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
1975 lf_printf(file
, " mon_issue(");
1976 lf_print_function_name(file
,
1977 instruction
->file_entry
->fields
[insn_name
],
1979 function_name_prefix_itable
);
1980 lf_printf(file
, ", processor, cia);\n");
1982 /* generate the code (or at least something */
1983 if (instruction
->file_entry
->annex
!= NULL
) {
1985 lf_printf(file
, "\n");
1986 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1987 lf_printf(file
, "{\n");
1988 lf_indent(file
, +2);
1989 lf_print_c_code(file
, instruction
->file_entry
->annex
);
1990 lf_indent(file
, -2);
1991 lf_printf(file
, "}\n");
1992 lf_print_lf_c_line_nr(file
);
1994 else if (it_is("nop", instruction
->file_entry
->fields
[insn_flags
])) {
1995 lf_print_lf_c_line_nr(file
);
1997 else if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1998 /* unimplemented floating point instruction - call for assistance */
1999 lf_printf(file
, "\n");
2000 lf_printf(file
, "/* unimplemented floating point instruction - call for assistance */\n");
2001 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2002 lf_putstr(file
, "floating_point_assist_interrupt(processor, cia);\n");
2003 lf_print_lf_c_line_nr(file
);
2006 /* abort so it is implemented now */
2007 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2008 lf_putstr(file
, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2009 lf_print_lf_c_line_nr(file
);
2010 lf_printf(file
, "\n");
2013 /* the function footer */
2014 lf_printf(file
, "return nia;\n");
2015 lf_indent(file
, -2);
2016 lf_printf(file
, "}\n");
2020 lf_print_c_semantic_function_header(lf
*file
,
2022 insn_bits
*expanded_bits
)
2024 lf_printf(file
, "\n");
2025 lf_printf(file
, "INLINE_SEMANTICS unsigned_word\n");
2026 lf_print_function_name(file
,
2029 function_name_prefix_semantics
);
2030 lf_printf(file
, "\n(%s)\n",
2031 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2035 lf_print_c_semantic_function(lf
*file
,
2037 insn_bits
*expanded_bits
,
2038 opcode_field
*opcodes
)
2041 /* build the semantic routine to execute the instruction */
2042 lf_print_c_semantic_function_header(file
,
2043 instruction
->file_entry
->fields
[insn_name
],
2045 lf_print_c_semantic(file
,
2053 semantics_c_leaf(insn_table
*entry
,
2057 lf
*file
= (lf
*)data
;
2058 ASSERT(entry
->nr_insn
== 1
2059 && entry
->opcode
== NULL
2060 && entry
->parent
!= NULL
2061 && entry
->parent
->opcode
!= NULL
);
2062 lf_print_c_semantic_function(file
,
2064 entry
->expanded_bits
,
2065 entry
->parent
->opcode
);
2069 semantics_c_insn(insn_table
*table
,
2073 lf
*file
= (lf
*)data
;
2074 lf_print_c_semantic_function(file
, instruction
,
2079 semantics_c_function(insn_table
*table
,
2081 table_entry
*function
)
2083 lf
*file
= (lf
*)data
;
2084 if (function
->fields
[function_type
] == NULL
2085 || function
->fields
[function_type
][0] == '\0') {
2086 lf_print_c_semantic_function_header(file
,
2087 function
->fields
[function_name
],
2091 lf_printf(file
, "\n");
2092 lf_printf(file
, "INLINE_SEMANTICS %s\n%s(%s)\n",
2093 function
->fields
[function_type
],
2094 function
->fields
[function_name
],
2095 function
->fields
[function_param
]);
2097 table_entry_lf_c_line_nr(file
, function
);
2098 lf_printf(file
, "{\n");
2099 lf_indent(file
, +2);
2100 lf_print_c_code(file
, function
->annex
);
2101 lf_indent(file
, -2);
2102 lf_printf(file
, "}\n");
2103 lf_print_lf_c_line_nr(file
);
2109 gen_semantics_c(insn_table
*table
, lf
*file
)
2111 lf_print_copyleft(file
);
2112 lf_printf(file
, "\n");
2113 lf_printf(file
, "#ifndef _SEMANTICS_C_\n");
2114 lf_printf(file
, "#define _SEMANTICS_C_\n");
2115 lf_printf(file
, "\n");
2116 lf_printf(file
, "#ifndef STATIC_INLINE_SEMANTICS\n");
2117 lf_printf(file
, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2118 lf_printf(file
, "#endif\n");
2119 lf_printf(file
, "\n");
2120 lf_printf(file
, "#include \"cpu.h\"\n");
2121 lf_printf(file
, "#include \"idecode.h\"\n");
2122 lf_printf(file
, "#include \"semantics.h\"\n");
2123 lf_printf(file
, "\n");
2125 /* output a definition (c-code) for all functions */
2126 insn_table_traverse_function(table
,
2128 semantics_c_function
);
2130 /* output a definition (c-code) for all instructions */
2131 if (idecode_expand_semantics
)
2132 insn_table_traverse_tree(table
,
2138 NULL
); /* padding */
2140 insn_table_traverse_insn(table
,
2144 lf_printf(file
, "\n");
2145 lf_printf(file
, "#endif /* _SEMANTICS_C_ */\n");
2149 /****************************************************************/
2152 gen_idecode_h(insn_table
*table
, lf
*file
)
2154 lf_print_copyleft(file
);
2155 lf_printf(file
, "\n");
2156 lf_printf(file
, "#ifndef _IDECODE_H_\n");
2157 lf_printf(file
, "#define _IDECODE_H_\n");
2158 lf_printf(file
, "\n");
2159 lf_printf(file
, "#ifndef INLINE_IDECODE\n");
2160 lf_printf(file
, "#define INLINE_IDECODE\n");
2161 lf_printf(file
, "#endif\n");
2162 lf_printf(file
, "\n");
2163 lf_printf(file
, "#include \"idecode_expression.h\"\n");
2164 lf_printf(file
, "#include \"idecode_fields.h\"\n");
2165 lf_printf(file
, "#include \"idecode_branch.h\"\n");
2166 lf_printf(file
, "\n");
2167 lf_printf(file
, "#include \"icache.h\"\n");
2168 lf_printf(file
, "\n");
2169 lf_printf(file
, "typedef unsigned_word idecode_semantic\n(%s);\n",
2170 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2171 lf_printf(file
, "\n");
2173 lf_printf(file
, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2174 cache_idecode_formal
);
2176 lf_printf(file
, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2178 lf_printf(file
, "\n");
2179 lf_printf(file
, "#endif /* _IDECODE_H_ */\n");
2183 /****************************************************************/
2187 idecode_table_start(insn_table
*table
,
2191 lf
*file
= (lf
*)data
;
2193 /* start of the table */
2194 if (!table
->opcode_rule
->use_switch
) {
2195 lf_printf(file
, "\n");
2196 lf_printf(file
, "static idecode_table_entry ");
2197 lf_print_table_name(file
, table
);
2198 lf_printf(file
, "[] = {\n");
2203 idecode_table_leaf(insn_table
*entry
,
2207 lf
*file
= (lf
*)data
;
2208 ASSERT(entry
->parent
!= NULL
);
2211 /* add an entry to the table */
2212 if (!entry
->parent
->opcode_rule
->use_switch
) {
2213 if (entry
->opcode
== NULL
) {
2214 /* table leaf entry */
2215 lf_printf(file
, " /*%d*/ { 0, 0, ", entry
->opcode_nr
);
2216 lf_print_function_name(file
,
2217 entry
->insns
->file_entry
->fields
[insn_name
],
2218 entry
->expanded_bits
,
2220 ? function_name_prefix_idecode
2221 : function_name_prefix_semantics
));
2222 lf_printf(file
, " },\n");
2224 else if (entry
->opcode_rule
->use_switch
) {
2225 /* table calling switch statement */
2226 lf_printf(file
, " /*%d*/ { -1, 0, ",
2228 lf_print_table_name(file
, entry
);
2229 lf_printf(file
, " },\n");
2232 /* table `calling' another table */
2233 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
2234 if (entry
->opcode
->is_boolean
)
2235 lf_printf(file
, "MASK32(%d,%d), 0, ",
2236 i2target(hi_bit_nr
, entry
->opcode
->first
),
2237 i2target(hi_bit_nr
, entry
->opcode
->last
));
2239 lf_printf(file
, "%d, MASK32(%d,%d), ",
2240 insn_size
- entry
->opcode
->last
- 1,
2241 i2target(hi_bit_nr
, entry
->opcode
->first
),
2242 i2target(hi_bit_nr
, entry
->opcode
->last
));
2243 lf_print_table_name(file
, entry
);
2244 lf_printf(file
, " },\n");
2250 idecode_table_end(insn_table
*table
,
2254 lf
*file
= (lf
*)data
;
2257 if (!table
->opcode_rule
->use_switch
) {
2258 lf_printf(file
, "};\n");
2263 idecode_table_padding(insn_table
*table
,
2268 lf
*file
= (lf
*)data
;
2271 if (!table
->opcode_rule
->use_switch
) {
2272 lf_printf(file
, " /*%d*/ { 0, 0, %s_illegal },\n",
2273 opcode_nr
, (idecode_cache
? "idecode" : "semantic"));
2278 /****************************************************************/
2281 void lf_print_idecode_switch
2287 idecode_switch_start(insn_table
*table
,
2291 lf
*file
= (lf
*)data
;
2293 ASSERT(table
->opcode_rule
->use_switch
);
2295 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2296 i2target(hi_bit_nr
, table
->opcode
->first
),
2297 i2target(hi_bit_nr
, table
->opcode
->last
));
2302 idecode_switch_leaf(insn_table
*entry
,
2306 lf
*file
= (lf
*)data
;
2307 ASSERT(entry
->parent
!= NULL
);
2309 ASSERT(entry
->parent
->opcode_rule
->use_switch
);
2311 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
2312 lf_indent(file
, +2);
2314 if (entry
->opcode
== NULL
) {
2315 /* switch calling leaf */
2316 lf_printf(file
, "return ");
2317 lf_print_function_name(file
,
2318 entry
->insns
->file_entry
->fields
[insn_name
],
2319 entry
->expanded_bits
,
2321 ? function_name_prefix_idecode
2322 : function_name_prefix_semantics
));
2324 lf_printf(file
, "(%s);\n", cache_idecode_actual
);
2326 lf_printf(file
, "(%s);\n", semantic_actual
);
2328 else if (entry
->opcode_rule
->use_switch
) {
2329 /* switch calling switch */
2330 lf_print_idecode_switch(file
, entry
);
2333 /* switch calling table */
2334 lf_printf(file
, "return ");
2335 lf_print_idecode_table(file
, entry
);
2337 lf_printf(file
, "break;\n");
2339 lf_indent(file
, -2);
2344 lf_print_idecode_switch_illegal(lf
*file
)
2346 lf_indent(file
, +2);
2347 lf_print_idecode_illegal(file
);
2348 lf_printf(file
, "break;\n");
2349 lf_indent(file
, -2);
2353 idecode_switch_end(insn_table
*table
,
2357 lf
*file
= (lf
*)data
;
2359 ASSERT(table
->opcode_rule
->use_switch
);
2361 if (table
->opcode_rule
->use_switch
== 1) {
2362 lf_printf(file
, "default:\n");
2363 lf_print_idecode_switch_illegal(file
);
2365 lf_printf(file
, "}\n");
2369 idecode_switch_padding(insn_table
*table
,
2374 lf
*file
= (lf
*)data
;
2377 ASSERT(table
->opcode_rule
->use_switch
);
2379 if (table
->opcode_rule
->use_switch
> 1) {
2380 lf_printf(file
, "case %d:\n", opcode_nr
);
2381 lf_print_idecode_switch_illegal(file
);
2387 lf_print_idecode_switch(lf
*file
,
2390 insn_table_traverse_tree(table
,
2393 idecode_switch_start
,
2394 idecode_switch_leaf
,
2396 idecode_switch_padding
);
2401 idecode_expand_if_switch(insn_table
*table
,
2405 lf
*file
= (lf
*)data
;
2407 if (table
->opcode_rule
->use_switch
2408 && table
->parent
!= NULL
/* don't expand the top one yet */
2409 && !table
->parent
->opcode_rule
->use_switch
) {
2410 lf_printf(file
, "\n");
2411 lf_printf(file
, "STATIC_INLINE_IDECODE void\n");
2412 lf_print_table_name(file
, table
);
2413 lf_printf(file
, "\n(%s)\n",
2414 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2415 lf_printf(file
, "{\n");
2417 lf_indent(file
, +2);
2418 lf_print_idecode_switch(file
, table
);
2419 lf_indent(file
, -2);
2421 lf_printf(file
, "}\n");
2427 lf_print_c_cracker_function(lf
*file
,
2429 insn_bits
*expanded_bits
,
2430 opcode_field
*opcodes
)
2432 /* if needed, generate code to enter this routine into a cache */
2433 lf_printf(file
, "\n");
2434 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2435 lf_print_function_name(file
,
2436 instruction
->file_entry
->fields
[insn_name
],
2438 function_name_prefix_idecode
);
2439 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2441 lf_print_c_cracker(file
,
2448 idecode_crack_leaf(insn_table
*entry
,
2452 lf
*file
= (lf
*)data
;
2453 ASSERT(entry
->nr_insn
== 1
2454 && entry
->opcode
== NULL
2455 && entry
->parent
!= NULL
2456 && entry
->parent
->opcode
!= NULL
);
2457 lf_print_c_cracker_function(file
,
2459 entry
->expanded_bits
,
2464 idecode_crack_insn(insn_table
*entry
,
2468 lf
*file
= (lf
*)data
;
2469 lf_print_c_cracker_function(file
,
2476 idecode_c_internal_function(insn_table
*table
,
2478 table_entry
*function
)
2480 lf
*file
= (lf
*)data
;
2481 ASSERT(idecode_cache
!= 0);
2482 if (it_is("internal", function
->fields
[insn_flags
])) {
2483 lf_printf(file
, "\n");
2484 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2485 lf_print_function_name(file
,
2486 function
->fields
[insn_name
],
2488 function_name_prefix_idecode
);
2489 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2490 lf_printf(file
, "{\n");
2491 lf_indent(file
, +2);
2492 lf_printf(file
, "/* semantic routine */\n");
2493 table_entry_lf_c_line_nr(file
, function
);
2494 lf_printf(file
, "return ");
2495 lf_print_function_name(file
,
2496 function
->fields
[insn_name
],
2498 function_name_prefix_semantics
);
2499 lf_printf(file
, ";\n");
2501 lf_print_lf_c_line_nr(file
);
2502 lf_indent(file
, -2);
2503 lf_printf(file
, "}\n");
2508 /****************************************************************/
2511 gen_idecode_c(insn_table
*table
, lf
*file
)
2516 lf_print_copyleft(file
);
2517 lf_printf(file
, "\n");
2518 lf_printf(file
, "\n");
2519 lf_printf(file
, "#ifndef _IDECODE_C_\n");
2520 lf_printf(file
, "#define _IDECODE_C_\n");
2521 lf_printf(file
, "\n");
2522 lf_printf(file
, "#ifndef STATIC_INLINE_IDECODE\n");
2523 lf_printf(file
, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2524 lf_printf(file
, "#endif\n");
2525 lf_printf(file
, "\n");
2526 lf_printf(file
, "#include \"cpu.h\"\n");
2527 lf_printf(file
, "#include \"idecode.h\"\n");
2528 lf_printf(file
, "#include \"semantics.h\"\n");
2529 lf_printf(file
, "\n");
2530 lf_printf(file
, "\n");
2531 lf_printf(file
, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2532 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2533 lf_printf(file
, "\n");
2534 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
2535 lf_printf(file
, " unsigned shift;\n");
2536 lf_printf(file
, " unsigned mask;\n");
2537 lf_printf(file
, " void *function_or_table;\n");
2538 lf_printf(file
, "} idecode_table_entry;\n");
2539 lf_printf(file
, "\n");
2540 lf_printf(file
, "\n");
2542 /* output `internal' invalid/floating-point unavailable functions
2544 if (idecode_cache
) {
2545 insn_table_traverse_function(table
,
2547 idecode_c_internal_function
);
2550 /* output cracking functions where needed */
2551 if (idecode_cache
) {
2552 if (idecode_expand_semantics
)
2553 insn_table_traverse_tree(table
,
2561 insn_table_traverse_insn(table
,
2563 idecode_crack_insn
);
2567 /* output tables where needed */
2568 for (depth
= insn_table_depth(table
);
2571 insn_table_traverse_tree(table
,
2574 idecode_table_start
,
2577 idecode_table_padding
);
2580 /* output switch functions where needed */
2581 insn_table_traverse_tree(table
,
2584 idecode_expand_if_switch
, /* START */
2587 /* output the main idecode routine */
2588 lf_printf(file
, "\n");
2590 lf_printf(file
, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2591 cache_idecode_formal
);
2593 lf_printf(file
, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2595 lf_printf(file
, "{\n");
2596 lf_indent(file
, +2);
2597 if (table
->opcode_rule
->use_switch
)
2598 lf_print_idecode_switch(file
, table
);
2600 lf_print_idecode_table(file
, table
);
2601 lf_indent(file
, -2);
2602 lf_printf(file
, "}\n");
2603 lf_printf(file
, "\n");
2604 lf_printf(file
, "#endif\n");
2608 /****************************************************************/
2611 itable_h_insn(insn_table
*entry
,
2615 lf
*file
= (lf
*)data
;
2616 lf_printf(file
, " ");
2617 lf_print_function_name(file
,
2618 instruction
->file_entry
->fields
[insn_name
],
2620 function_name_prefix_itable
);
2621 lf_printf(file
, ",\n");
2626 gen_itable_h(insn_table
*table
, lf
*file
)
2629 lf_print_copyleft(file
);
2630 lf_printf(file
, "\n");
2631 lf_printf(file
, "#ifndef _ITABLE_H_\n");
2632 lf_printf(file
, "#define _ITABLE_H_\n");
2633 lf_printf(file
, "\n");
2634 lf_printf(file
, "#ifndef INLINE_ITABLE\n");
2635 lf_printf(file
, "#define INLINE_ITABLE\n");
2636 lf_printf(file
, "#endif\n");
2637 lf_printf(file
, "\n");
2638 lf_printf(file
, "\n");
2640 /* output an enumerated type for each instruction */
2641 lf_printf(file
, "typedef enum {\n");
2642 insn_table_traverse_insn(table
,
2645 lf_printf(file
, " nr_itable_entries,\n");
2646 lf_printf(file
, "} itable_index;\n");
2647 lf_printf(file
, "\n");
2649 /* output the table that contains the actual instruction info */
2650 lf_printf(file
, "typedef struct _itable_instruction_info {\n");
2651 lf_printf(file
, " itable_index nr;\n");
2652 lf_printf(file
, " char *format;\n");
2653 lf_printf(file
, " char *form;\n");
2654 lf_printf(file
, " char *flags;\n");
2655 lf_printf(file
, " char *nmemonic;\n");
2656 lf_printf(file
, " char *name;\n");
2657 lf_printf(file
, "} itable_info;\n");
2658 lf_printf(file
, "\n");
2659 lf_printf(file
, "extern itable_info itable[nr_itable_entries];\n");
2661 lf_printf(file
, "\n");
2662 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2666 /****************************************************************/
2669 itable_c_insn(insn_table
*entry
,
2673 lf
*file
= (lf
*)data
;
2674 char **fields
= instruction
->file_entry
->fields
;
2675 lf_printf(file
, " { ");
2676 lf_print_function_name(file
,
2677 instruction
->file_entry
->fields
[insn_name
],
2679 function_name_prefix_itable
);
2680 lf_printf(file
, ",\n");
2681 lf_printf(file
, " \"%s\",\n", fields
[insn_format
]);
2682 lf_printf(file
, " \"%s\",\n", fields
[insn_form
]);
2683 lf_printf(file
, " \"%s\",\n", fields
[insn_flags
]);
2684 lf_printf(file
, " \"%s\",\n", fields
[insn_nmemonic
]);
2685 lf_printf(file
, " \"%s\",\n", fields
[insn_name
]);
2686 lf_printf(file
, " },\n");
2691 gen_itable_c(insn_table
*table
, lf
*file
)
2694 lf_print_copyleft(file
);
2695 lf_printf(file
, "\n");
2696 lf_printf(file
, "#ifndef _ITABLE_C_\n");
2697 lf_printf(file
, "#define _ITABLE_C_\n");
2698 lf_printf(file
, "\n");
2699 lf_printf(file
, "#ifndef STATIC_INLINE_ITABLE\n");
2700 lf_printf(file
, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2701 lf_printf(file
, "#endif\n");
2702 lf_printf(file
, "\n");
2703 lf_printf(file
, "#include \"itable.h\"\n");
2704 lf_printf(file
, "\n");
2706 /* output the table that contains the actual instruction info */
2707 lf_printf(file
, "itable_info itable[nr_itable_entries] = {\n");
2708 insn_table_traverse_insn(table
,
2711 lf_printf(file
, "};\n");
2712 lf_printf(file
, "\n");
2714 lf_printf(file
, "\n");
2715 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2719 /****************************************************************/
2727 insn_table
*instructions
= NULL
;
2728 icache_tree
*cache_fields
= NULL
;
2729 char *real_file_name
= NULL
;
2734 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
2735 printf("Config options:\n");
2736 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
2737 printf(" -e Expand (duplicate) semantic functions\n");
2738 printf(" -r <icache-size> Generate cracking cache version\n");
2739 printf(" -l Supress line numbering in output files\n");
2740 printf(" -b <bit-size> Set the number of bits in an instruction\n");
2741 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
2742 printf("Input options (ucase version also dumps loaded table):\n");
2743 printf(" -[Oo] <opcode-rules>\n");
2744 printf(" -[Kk] <cache-rules>\n");
2745 printf(" -[Ii] <instruction-table>\n");
2746 printf("Output options:\n");
2747 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
2748 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
2749 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
2750 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
2753 while ((ch
= getopt(argc
, argv
,
2754 "leb:h:r:f:I:i:O:o:K:k:n:S:s:D:d:T:t:C:")) != -1) {
2755 fprintf(stderr
, "\t-%c %s\n", ch
, (optarg
? optarg
: ""));
2761 idecode_expand_semantics
= 1;
2764 idecode_cache
= a2i(optarg
);
2767 insn_size
= a2i(optarg
);
2768 ASSERT(insn_size
> 0 && insn_size
<= max_insn_size
2769 && (hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0));
2772 hi_bit_nr
= a2i(optarg
);
2773 ASSERT(hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0);
2777 filter
*new_filter
= ZALLOC(filter
);
2778 new_filter
->flag
= strdup(optarg
);
2779 new_filter
->next
= filters
;
2780 filters
= new_filter
;
2785 ASSERT(opcode_table
!= NULL
);
2786 ASSERT(cache_table
!= NULL
);
2787 instructions
= insn_table_load_insns(optarg
);
2788 fprintf(stderr
, "\texpanding ...\n");
2789 insn_table_expand_insns(instructions
);
2790 fprintf(stderr
, "\tcache fields ...\n");
2791 cache_fields
= insn_table_cache_fields(instructions
);
2793 dump_traverse(instructions
);
2794 dump_insn_table(instructions
, 0, 1);
2799 opcode_table
= load_opcode_rules(optarg
);
2801 dump_opcode_rules(opcode_table
, 0);
2805 cache_table
= load_cache_rules(optarg
);
2807 dump_cache_rules(cache_table
, 0);
2810 real_file_name
= strdup(optarg
);
2820 lf
*file
= lf_open(optarg
, real_file_name
, number_lines
);
2821 ASSERT(instructions
!= NULL
);
2824 gen_semantics_h(instructions
, file
);
2827 gen_semantics_c(instructions
, file
);
2830 gen_idecode_h(instructions
, file
);
2833 gen_idecode_c(instructions
, file
);
2836 gen_itable_h(instructions
, file
);
2839 gen_itable_c(instructions
, file
);
2842 gen_icache_h(cache_fields
, file
);
2847 real_file_name
= NULL
;
2850 error("unknown option\n");