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 /****************************************************************/
46 static int hi_bit_nr
= 0;
47 static int insn_size
= max_insn_size
;
48 static int idecode_expand_semantics
= 0;
49 static int idecode_cache
= 0;
50 static int number_lines
= 1;
53 /****************************************************************/
56 static char *cache_idecode_formal
=
58 instruction_word instruction,\n\
60 idecode_cache *cache_entry";
62 static char *cache_idecode_actual
= "processor, instruction, cia, cache_entry";
64 static char *cache_semantic_formal
=
66 idecode_cache *cache_entry,\n\
69 static char *semantic_formal
=
71 instruction_word instruction,\n\
74 static char *semantic_actual
= "processor, instruction, cia";
78 /****************************************************************/
81 typedef struct _filter filter
;
86 static filter
*filters
= NULL
;
89 /****************************************************************/
92 typedef struct _cache_rules cache_rules
;
101 static cache_rules
*cache_table
;
110 nr_cache_rule_fields
,
114 load_cache_rules(char *file_name
)
116 table
*file
= table_open(file_name
, nr_cache_rule_fields
, 0);
118 cache_rules
*table
= NULL
;
119 cache_rules
**curr_rule
= &table
;
120 while ((entry
= table_entry_read(file
)) != NULL
) {
121 cache_rules
*new_rule
= ZALLOC(cache_rules
);
122 new_rule
->valid
= target_a2i(hi_bit_nr
, entry
->fields
[ca_valid
]);
123 new_rule
->old_name
= entry
->fields
[ca_old_name
];
124 new_rule
->new_name
= entry
->fields
[ca_new_name
];
125 new_rule
->type
= (strlen(entry
->fields
[ca_type
])
126 ? entry
->fields
[ca_type
]
128 new_rule
->expression
= (strlen(entry
->fields
[ca_expression
]) > 0
129 ? entry
->fields
[ca_expression
]
131 *curr_rule
= new_rule
;
132 curr_rule
= &new_rule
->next
;
140 dump_cache_rule(cache_rules
* rule
,
143 dumpf(indent
, "((cache_rules*)0x%x\n", rule
);
144 dumpf(indent
, " (valid %d)\n", rule
->valid
);
145 dumpf(indent
, " (old_name \"%s\")\n", rule
->old_name
);
146 dumpf(indent
, " (new_name \"%s\")\n", rule
->new_name
);
147 dumpf(indent
, " (type \"%s\")\n", rule
->type
);
148 dumpf(indent
, " (expression \"%s\")\n", rule
->expression
);
149 dumpf(indent
, " (next 0x%x)\n", rule
->next
);
150 dumpf(indent
, " )\n");
155 dump_cache_rules(cache_rules
* rule
, int indent
)
158 dump_cache_rule(rule
, indent
);
164 /****************************************************************/
167 typedef struct _opcode_rules opcode_rules
;
168 struct _opcode_rules
{
174 char *force_expansion
;
176 unsigned special_mask
;
177 unsigned special_value
;
178 unsigned special_rule
;
181 static opcode_rules
*opcode_table
;
199 static opcode_rules
*
200 load_opcode_rules(char *file_name
)
202 table
*file
= table_open(file_name
, nr_opcode_fields
, 0);
204 opcode_rules
*table
= NULL
;
205 opcode_rules
**curr_rule
= &table
;
206 while ((entry
= table_entry_read(file
)) != NULL
) {
207 opcode_rules
*new_rule
= ZALLOC(opcode_rules
);
208 new_rule
->first
= target_a2i(hi_bit_nr
, entry
->fields
[op_first
]);
209 new_rule
->last
= target_a2i(hi_bit_nr
, entry
->fields
[op_last
]);
210 new_rule
->force_first
= target_a2i(hi_bit_nr
, entry
->fields
[op_force_first
]);
211 new_rule
->force_last
= target_a2i(hi_bit_nr
, entry
->fields
[op_force_last
]);
212 new_rule
->force_slash
= a2i(entry
->fields
[op_force_slash
]);
213 new_rule
->force_expansion
= entry
->fields
[op_force_expansion
];
214 new_rule
->use_switch
= a2i(entry
->fields
[op_use_switch
]);
215 new_rule
->special_mask
= a2i(entry
->fields
[op_special_mask
]);
216 new_rule
->special_value
= a2i(entry
->fields
[op_special_value
]);
217 new_rule
->special_rule
= a2i(entry
->fields
[op_special_rule
]);
218 *curr_rule
= new_rule
;
219 curr_rule
= &new_rule
->next
;
226 dump_opcode_rule(opcode_rules
*rule
,
229 dumpf(indent
, "((opcode_rules*)%p\n", rule
);
231 dumpf(indent
, " (first %d)\n", rule
->first
);
232 dumpf(indent
, " (last %d)\n", rule
->last
);
233 dumpf(indent
, " (force_first %d)\n", rule
->force_first
);
234 dumpf(indent
, " (force_last %d)\n", rule
->force_last
);
235 dumpf(indent
, " (force_slash %d)\n", rule
->force_slash
);
236 dumpf(indent
, " (force_expansion \"%s\")\n", rule
->force_expansion
);
237 dumpf(indent
, " (use_switch %d)\n", rule
->use_switch
);
238 dumpf(indent
, " (special_mask 0x%x)\n", rule
->special_mask
);
239 dumpf(indent
, " (special_value 0x%x)\n", rule
->special_value
);
240 dumpf(indent
, " (special_rule 0x%x)\n", rule
->special_rule
);
241 dumpf(indent
, " (next 0x%x)\n", rule
->next
);
243 dumpf(indent
, " )\n");
248 dump_opcode_rules(opcode_rules
*rule
,
252 dump_opcode_rule(rule
, indent
);
258 /****************************************************************/
260 typedef struct _insn_field insn_field
;
275 typedef struct _insn_fields insn_fields
;
276 struct _insn_fields
{
277 insn_field
*bits
[max_insn_size
];
284 parse_insn_format(table_entry
*entry
,
288 insn_fields
*fields
= ZALLOC(insn_fields
);
290 /* create a leading sentinal */
291 fields
->first
= ZALLOC(insn_field
);
292 fields
->first
->first
= -1;
293 fields
->first
->last
= -1;
294 fields
->first
->width
= 0;
296 /* and a trailing sentinal */
297 fields
->last
= ZALLOC(insn_field
);
298 fields
->last
->first
= insn_size
;
299 fields
->last
->last
= insn_size
;
300 fields
->last
->width
= 0;
302 /* link them together */
303 fields
->first
->next
= fields
->last
;
304 fields
->last
->prev
= fields
->first
;
306 /* now work through the formats */
309 while (*chp
!= '\0') {
314 insn_field
*new_field
;
317 if (!isdigit(*chp
)) {
318 error("%s:%d: missing position field at `%s'\n",
319 entry
->file_name
, entry
->line_nr
, chp
);
322 /* break out the bit position */
324 while (isdigit(*chp
))
326 strlen_pos
= chp
- start_pos
;
327 if (*chp
== '.' && strlen_pos
> 0)
330 error("%s:%d: missing field value at %s\n",
331 entry
->file_name
, entry
->line_nr
, chp
);
335 /* break out the value */
337 while ((*start_val
== '/' && *chp
== '/')
338 || (isdigit(*start_val
) && isdigit(*chp
))
339 || (isalpha(*start_val
) && (isalnum(*chp
) || *chp
== '_')))
341 strlen_val
= chp
- start_val
;
344 else if (*chp
!= '\0' || strlen_val
== 0) {
345 error("%s:%d: missing field terminator at %s\n",
346 entry
->file_name
, entry
->line_nr
, chp
);
350 /* create a new field and insert it */
351 new_field
= ZALLOC(insn_field
);
352 new_field
->next
= fields
->last
;
353 new_field
->prev
= fields
->last
->prev
;
354 new_field
->next
->prev
= new_field
;
355 new_field
->prev
->next
= new_field
;
358 new_field
->val_string
= (char*)zalloc(strlen_val
+1);
359 strncpy(new_field
->val_string
, start_val
, strlen_val
);
360 if (isdigit(*new_field
->val_string
)) {
361 new_field
->val_int
= a2i(new_field
->val_string
);
362 new_field
->is_int
= 1;
364 else if (new_field
->val_string
[0] == '/') {
365 new_field
->is_slash
= 1;
368 new_field
->is_string
= 1;
372 new_field
->pos_string
= (char*)zalloc(strlen_pos
+1);
373 strncpy(new_field
->pos_string
, start_pos
, strlen_pos
);
374 new_field
->first
= target_a2i(hi_bit_nr
, new_field
->pos_string
);
375 new_field
->last
= new_field
->next
->first
- 1; /* guess */
376 new_field
->width
= new_field
->last
- new_field
->first
+ 1; /* guess */
377 new_field
->prev
->last
= new_field
->first
-1; /*fix*/
378 new_field
->prev
->width
= new_field
->first
- new_field
->prev
->first
; /*fix*/
381 /* fiddle first/last so that the sentinals `disapear' */
382 ASSERT(fields
->first
->last
< 0);
383 ASSERT(fields
->last
->first
>= insn_size
);
384 fields
->first
= fields
->first
->next
;
385 fields
->last
= fields
->last
->prev
;
387 /* now go over this again, pointing each bit position at a field
392 field
= fields
->first
;
393 for (i
= 0; i
< insn_size
; i
++) {
394 while (field
->last
< i
)
396 fields
->bits
[i
] = field
;
400 /* go over each of the fields, and compute a `value' for the insn */
404 for (field
= fields
->first
;
405 field
->last
< insn_size
;
406 field
= field
->next
) {
407 fields
->value
<<= field
->width
;
409 fields
->value
|= field
->val_int
;
417 field_constant_int
= 1,
418 field_constant_slash
= 2,
419 field_constant_string
= 3
420 } constant_field_types
;
424 insn_field_is_constant(insn_field
*field
,
427 /* field is an integer */
429 return field_constant_int
;
430 /* field is `/' and treating that as a constant */
431 if (field
->is_slash
&& rule
->force_slash
)
432 return field_constant_slash
;
433 /* field, though variable is on the list */
434 if (field
->is_string
&& rule
->force_expansion
!= NULL
) {
435 char *forced_fields
= rule
->force_expansion
;
436 while (*forced_fields
!= '\0') {
438 char *end
= strchr(forced_fields
, ',');
440 field_len
= strlen(forced_fields
);
442 field_len
= end
-forced_fields
;
443 if (strncmp(forced_fields
, field
->val_string
, field_len
) == 0
444 && field
->val_string
[field_len
] == '\0')
445 return field_constant_string
;
446 forced_fields
+= field_len
;
447 if (*forced_fields
== ',')
456 dump_insn_field(insn_field
*field
,
460 printf("(insn_field*)0x%x\n", (unsigned)field
);
462 dumpf(indent
, "(first %d)\n", field
->first
);
464 dumpf(indent
, "(last %d)\n", field
->last
);
466 dumpf(indent
, "(width %d)\n", field
->width
);
469 dumpf(indent
, "(is_int %d)\n", field
->val_int
);
472 dumpf(indent
, "(is_slash)\n");
474 if (field
->is_string
)
475 dumpf(indent
, "(is_string `%s')\n", field
->val_string
);
477 dumpf(indent
, "(next 0x%x)\n", field
->next
);
479 dumpf(indent
, "(prev 0x%x)\n", field
->prev
);
485 dump_insn_fields(insn_fields
*fields
,
490 printf("(insn_fields*)%p\n", fields
);
492 dumpf(indent
, "(first 0x%x)\n", fields
->first
);
493 dumpf(indent
, "(last 0x%x)\n", fields
->last
);
495 dumpf(indent
, "(value 0x%x)\n", fields
->value
);
497 for (i
= 0; i
< insn_size
; i
++) {
498 dumpf(indent
, "(bits[%d] ", i
, fields
->bits
[i
]);
499 dump_insn_field(fields
->bits
[i
], indent
+1);
500 dumpf(indent
, " )\n");
506 /****************************************************************/
508 typedef struct _opcode_field opcode_field
;
509 struct _opcode_field
{
513 opcode_field
*parent
;
516 static opcode_field
*
517 opcode_field_new(void)
519 opcode_field
*new_field
= (opcode_field
*)zalloc(sizeof(opcode_field
));
520 ASSERT(new_field
!= NULL
);
521 new_field
->first
= insn_size
;
522 new_field
->last
= -1;
527 dump_opcode_field(opcode_field
*field
, int indent
, int levels
)
529 printf("(opcode_field*)%p\n", field
);
530 if (levels
&& field
!= NULL
) {
531 dumpf(indent
, "(first %d)\n", field
->first
);
532 dumpf(indent
, "(last %d)\n", field
->last
);
533 dumpf(indent
, "(is_boolean %d)\n", field
->is_boolean
);
534 dumpf(indent
, "(parent ");
535 dump_opcode_field(field
->parent
, indent
, levels
-1);
540 /****************************************************************/
542 typedef struct _insn_bits insn_bits
;
547 opcode_field
*opcode
;
553 dump_insn_bits(insn_bits
*bits
, int indent
, int levels
)
555 printf("(insn_bits*)%p\n", bits
);
557 if (levels
&& bits
!= NULL
) {
558 dumpf(indent
, "(value %d)\n", bits
->value
);
559 dumpf(indent
, "(opcode ");
560 dump_opcode_field(bits
->opcode
, indent
+1, 0);
561 dumpf(indent
, " )\n");
562 dumpf(indent
, "(field ");
563 dump_insn_field(bits
->field
, indent
+1);
564 dumpf(indent
, " )\n");
565 dumpf(indent
, "(last ");
566 dump_insn_bits(bits
->last
, indent
+1, levels
-1);
571 /****************************************************************/
585 function_type
= insn_format
,
586 function_name
= insn_name
,
587 function_param
= insn_comment
588 } function_table_fields
;
591 model_name
= insn_nmemonic
,
592 model_identifer
= insn_name
,
593 model_func
= insn_comment
,
594 } model_table_fields
;
596 typedef struct _insn insn
;
598 table_entry
*file_entry
;
603 typedef struct _model_func_unit model_func_unit
;
604 struct _model_func_unit
{
605 model_func_unit
*next
;
612 typedef struct _model model
;
616 char *printable_name
;
617 model_func_unit
*func_unit_start
;
618 model_func_unit
*func_unit_end
;
621 typedef struct _insn_table insn_table
;
624 insn_bits
*expanded_bits
;
629 int max_func_unit_name_len
;
630 unsigned max_func_unit_mask
;
631 opcode_rules
*opcode_rule
;
632 opcode_field
*opcode
;
645 nr_insn_model_table_fields
646 } insn_model_table_fields
;
648 static model
*models
;
649 static model
*last_model
;
651 static insn
*model_macros
;
652 static insn
*last_model_macro
;
655 insn_table_insert_function(insn_table
*table
,
656 table_entry
*file_entry
)
658 /* create a new function */
659 insn
*new_function
= ZALLOC(insn
);
660 new_function
->file_entry
= file_entry
;
662 /* append it to the end of the function list */
663 if (table
->last_function
)
664 table
->last_function
->next
= new_function
;
666 table
->functions
= new_function
;
667 table
->last_function
= new_function
;
672 model_table_insert(insn_table
*table
,
673 table_entry
*file_entry
)
675 /* create a new model */
676 model
*new_model
= ZALLOC(model
);
677 model_func_unit
*func_unit
;
678 char *ptr
, *end
, *end_name
, *comment
, *name
;
685 new_model
->name
= file_entry
->fields
[model_identifer
];
686 new_model
->printable_name
= file_entry
->fields
[model_name
];
687 name_len
= strlen(new_model
->name
);
689 /* append it to the end of the model list */
691 last_model
->next
= new_model
;
694 last_model
= new_model
;
696 /* Parse the function units separated by commas */
698 for (ptr
= file_entry
->fields
[model_func
];
699 ((ch
= *ptr
) != '\0') && (ch
!= '\n');
700 ptr
= (*end
== ',') ? end
+1 : end
) {
702 while (ch
== ' ' || ch
== '\t')
705 if (!ch
|| ch
== '\n')
708 /* Search for comma or newline ending field */
710 end_name
= (char *)0;
715 while (ch
!= '\0' && ch
!= ',' && ch
!= '\n') {
716 if (end_name
== (char *)0 && (ch
== '=' || isspace(ch
)))
724 func_unit
= ZALLOC(model_func_unit
);
725 if (new_model
->func_unit_end
)
726 new_model
->func_unit_end
->next
= func_unit
;
728 new_model
->func_unit_start
= func_unit
;
730 new_model
->func_unit_end
= func_unit
;
732 /* Record function unit name as model name _ unit name */
733 func_name_len
= name_len
+ end_name
- ptr
+ 2;
734 if (table
->max_func_unit_name_len
< func_name_len
)
735 table
->max_func_unit_name_len
= func_name_len
;
737 func_unit
->name
= name
= (char *)zalloc(func_name_len
);
738 memcpy(name
, new_model
->name
, name_len
);
739 name
[name_len
] = '_';
740 memcpy(name
+ name_len
+ 1, ptr
, end_name
- ptr
);
742 /* See if there are multiple functional units */
743 if (*end_name
== '=') {
745 for(end_name
++; end_name
< end
&& isdigit(*end_name
); end_name
++)
746 number
= number
* 10 + (*end_name
- '0');
751 /* Now figure out the mask for these unit(s) */
752 func_unit
->number
= number
;
759 func_unit
->mask
= mask
;
760 table
->max_func_unit_mask
|= mask
;
762 /* Now figure out comments */
763 for (comment
= end_name
; comment
< end
&& ((ch
= *comment
) == ' ' || ch
== '\t'); comment
++)
767 func_unit
->comment
= (char *)zalloc(end
- comment
+ 1);
768 memcpy(func_unit
->comment
, comment
, end
- comment
);
772 /* Add an 'sentinel' function unit at the end to simpify the loop */
773 func_unit
= ZALLOC(model_func_unit
);
774 if (new_model
->func_unit_end
)
775 new_model
->func_unit_end
->next
= func_unit
;
777 new_model
->func_unit_start
= func_unit
;
779 new_model
->func_unit_end
= func_unit
;
781 /* Record function unit name as model name _ unit name */
782 func_name_len
= name_len
+ sizeof("_SENTINEL");
783 if (table
->max_func_unit_name_len
< func_name_len
)
784 table
->max_func_unit_name_len
= func_name_len
;
786 func_unit
->name
= name
= (char *)zalloc(func_name_len
);
787 func_unit
->number
= 0;
788 func_unit
->mask
= unit
;
789 func_unit
->comment
= "dummy";
790 table
->max_func_unit_mask
|= unit
;
792 memcpy(name
, new_model
->name
, name_len
);
793 strcpy(name
+ name_len
, "_SENTINEL");
798 insn_table_insert_insn(insn_table
*table
,
799 table_entry
*file_entry
,
802 insn
**ptr_to_cur_insn
= &table
->insns
;
803 insn
*cur_insn
= *ptr_to_cur_insn
;
804 table_model_entry
*insn_model_ptr
;
807 /* create a new instruction */
808 insn
*new_insn
= ZALLOC(insn
);
809 new_insn
->file_entry
= file_entry
;
810 new_insn
->fields
= fields
;
812 /* Check out any model information returned to make sure the model
814 for(insn_model_ptr
= file_entry
->model_first
; insn_model_ptr
; insn_model_ptr
= insn_model_ptr
->next
) {
815 char *name
= insn_model_ptr
->fields
[insn_model_name
];
817 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
818 if (strcmp(name
, model_ptr
->name
) == 0) {
820 /* Replace the name field with that of the global model, so that when we
821 want to print it out, we can just compare pointers. */
822 insn_model_ptr
->fields
[insn_model_name
] = model_ptr
->name
;
828 error("%s:%d: machine model `%s' was not known about\n",
829 file_entry
->file_name
, file_entry
->line_nr
, name
);
832 /* insert it according to the order of the fields */
833 while (cur_insn
!= NULL
834 && new_insn
->fields
->value
>= cur_insn
->fields
->value
) {
835 ptr_to_cur_insn
= &cur_insn
->next
;
836 cur_insn
= *ptr_to_cur_insn
;
839 new_insn
->next
= cur_insn
;
840 *ptr_to_cur_insn
= new_insn
;
846 static opcode_field
*
847 insn_table_find_opcode_field(insn
*insns
,
851 opcode_field
*curr_opcode
= opcode_field_new();
856 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
) {
857 insn_fields
*fields
= entry
->fields
;
858 opcode_field new_opcode
;
860 /* find a start point for the opcode field */
861 new_opcode
.first
= rule
->first
;
862 while (new_opcode
.first
<= rule
->last
864 || insn_field_is_constant(fields
->bits
[new_opcode
.first
],
865 rule
) != field_constant_string
)
867 || !insn_field_is_constant(fields
->bits
[new_opcode
.first
],
869 new_opcode
.first
= fields
->bits
[new_opcode
.first
]->last
+ 1;
870 ASSERT(new_opcode
.first
> rule
->last
872 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
873 rule
) == field_constant_string
)
875 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
878 /* find the end point for the opcode field */
879 new_opcode
.last
= rule
->last
;
880 while (new_opcode
.last
>= rule
->first
882 || insn_field_is_constant(fields
->bits
[new_opcode
.last
],
883 rule
) != field_constant_string
)
885 || !insn_field_is_constant(fields
->bits
[new_opcode
.last
],
887 new_opcode
.last
= fields
->bits
[new_opcode
.last
]->first
- 1;
888 ASSERT(new_opcode
.last
< rule
->first
890 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
891 rule
) == field_constant_string
)
893 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
896 /* now see if our current opcode needs expanding */
897 if (new_opcode
.first
<= rule
->last
898 && curr_opcode
->first
> new_opcode
.first
)
899 curr_opcode
->first
= new_opcode
.first
;
900 if (new_opcode
.last
>= rule
->first
901 && curr_opcode
->last
< new_opcode
.last
)
902 curr_opcode
->last
= new_opcode
.last
;
906 /* was any thing interesting found? */
907 if (curr_opcode
->first
> rule
->last
) {
908 ASSERT(curr_opcode
->last
< rule
->first
);
911 ASSERT(curr_opcode
->last
>= rule
->first
);
912 ASSERT(curr_opcode
->first
<= rule
->last
);
914 /* if something was found, check it includes the forced field range */
916 && curr_opcode
->first
> rule
->force_first
) {
917 curr_opcode
->first
= rule
->force_first
;
920 && curr_opcode
->last
< rule
->force_last
) {
921 curr_opcode
->last
= rule
->force_last
;
923 /* handle special case elminating any need to do shift after mask */
925 && rule
->force_last
== insn_size
-1) {
926 curr_opcode
->last
= insn_size
-1;
929 /* handle any special cases */
930 switch (rule
->special_rule
) {
931 case 0: /* let the above apply */
933 case 1: /* expand a limited nr of bits, ignoring the rest */
934 curr_opcode
->first
= rule
->force_first
;
935 curr_opcode
->last
= rule
->force_last
;
937 case 2: /* boolean field */
938 curr_opcode
->is_boolean
= 1;
947 insn_table_insert_expanded(insn_table
*table
,
952 insn_table
**ptr_to_cur_entry
= &table
->entries
;
953 insn_table
*cur_entry
= *ptr_to_cur_entry
;
955 /* find the new table for this entry */
956 while (cur_entry
!= NULL
957 && cur_entry
->opcode_nr
< new_opcode_nr
) {
958 ptr_to_cur_entry
= &cur_entry
->sibling
;
959 cur_entry
= *ptr_to_cur_entry
;
962 if (cur_entry
== NULL
|| cur_entry
->opcode_nr
!= new_opcode_nr
) {
963 insn_table
*new_entry
= ZALLOC(insn_table
);
964 new_entry
->opcode_nr
= new_opcode_nr
;
965 new_entry
->expanded_bits
= new_bits
;
966 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
967 new_entry
->sibling
= cur_entry
;
968 new_entry
->parent
= table
;
969 *ptr_to_cur_entry
= new_entry
;
970 cur_entry
= new_entry
;
973 /* ASSERT new_bits == cur_entry bits */
974 ASSERT(cur_entry
!= NULL
&& cur_entry
->opcode_nr
== new_opcode_nr
);
975 insn_table_insert_insn(cur_entry
,
976 old_insn
->file_entry
,
981 insn_table_expand_opcode(insn_table
*table
,
988 if (field_nr
> table
->opcode
->last
) {
989 insn_table_insert_expanded(table
, instruction
, opcode_nr
, bits
);
992 insn_field
*field
= instruction
->fields
->bits
[field_nr
];
993 if (field
->is_int
|| field
->is_slash
) {
994 ASSERT(field
->first
>= table
->opcode
->first
995 && field
->last
<= table
->opcode
->last
);
996 insn_table_expand_opcode(table
, instruction
, field
->last
+1,
997 ((opcode_nr
<< field
->width
) + field
->val_int
),
1002 int last_pos
= ((field
->last
< table
->opcode
->last
)
1003 ? field
->last
: table
->opcode
->last
);
1004 int first_pos
= ((field
->first
> table
->opcode
->first
)
1005 ? field
->first
: table
->opcode
->first
);
1006 int width
= last_pos
- first_pos
+ 1;
1007 int last_val
= (table
->opcode
->is_boolean
1008 ? 2 : (1 << width
));
1009 for (val
= 0; val
< last_val
; val
++) {
1010 insn_bits
*new_bits
= ZALLOC(insn_bits
);
1011 new_bits
->field
= field
;
1012 new_bits
->value
= val
;
1013 new_bits
->last
= bits
;
1014 new_bits
->opcode
= table
->opcode
;
1015 insn_table_expand_opcode(table
, instruction
, last_pos
+1,
1016 ((opcode_nr
<< width
) | val
),
1024 insn_table_insert_expanding(insn_table
*table
,
1027 insn_table_expand_opcode(table
,
1029 table
->opcode
->first
,
1031 table
->expanded_bits
);
1036 insn_table_expand_insns(insn_table
*table
)
1039 ASSERT(table
->nr_insn
>= 1);
1041 /* determine a valid opcode */
1042 while (table
->opcode_rule
) {
1043 /* specials only for single instructions */
1044 if ((table
->nr_insn
> 1
1045 && table
->opcode_rule
->special_mask
== 0
1046 && table
->opcode_rule
->special_rule
== 0)
1047 || (table
->nr_insn
== 1
1048 && table
->opcode_rule
->special_mask
!= 0
1049 && ((table
->insns
->fields
->value
1050 & table
->opcode_rule
->special_mask
)
1051 == table
->opcode_rule
->special_value
))
1052 || (idecode_expand_semantics
1053 && table
->opcode_rule
->special_mask
== 0
1054 && table
->opcode_rule
->special_rule
== 0))
1056 insn_table_find_opcode_field(table
->insns
,
1058 table
->nr_insn
== 1/*string*/
1060 if (table
->opcode
!= NULL
)
1062 table
->opcode_rule
= table
->opcode_rule
->next
;
1065 /* did we find anything */
1066 if (table
->opcode
== NULL
) {
1069 ASSERT(table
->opcode
!= NULL
);
1071 /* back link what we found to its parent */
1072 if (table
->parent
!= NULL
) {
1073 ASSERT(table
->parent
->opcode
!= NULL
);
1074 table
->opcode
->parent
= table
->parent
->opcode
;
1077 /* expand the raw instructions according to the opcode */
1080 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
) {
1081 insn_table_insert_expanding(table
, entry
);
1085 /* and do the same for the sub entries */
1088 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
) {
1089 insn_table_expand_insns(entry
);
1097 insn_table_load_insns(char *file_name
)
1099 table
*file
= table_open(file_name
, nr_insn_table_fields
, nr_insn_model_table_fields
);
1100 insn_table
*table
= ZALLOC(insn_table
);
1101 table_entry
*file_entry
;
1102 table
->opcode_rule
= opcode_table
;
1104 while ((file_entry
= table_entry_read(file
)) != NULL
) {
1105 if (it_is("function", file_entry
->fields
[insn_flags
])
1106 || it_is("internal", file_entry
->fields
[insn_flags
])) {
1107 insn_table_insert_function(table
, file_entry
);
1109 else if (it_is("model", file_entry
->fields
[insn_flags
])) {
1110 model_table_insert(table
, file_entry
);
1112 else if (it_is("model-macro", file_entry
->fields
[insn_flags
])) {
1113 insn
*macro
= ZALLOC(insn
);
1114 macro
->file_entry
= file_entry
;
1115 if (last_model_macro
)
1116 last_model_macro
->next
= macro
;
1118 model_macros
= macro
;
1119 last_model_macro
= macro
;
1122 insn_fields
*fields
;
1123 /* skip instructions that aren't relevant to the mode */
1124 filter
*filt
= filters
;
1125 while (filt
!= NULL
) {
1126 if (it_is(filt
->flag
, file_entry
->fields
[insn_flags
]))
1131 /* create/insert the new instruction */
1132 fields
= parse_insn_format(file_entry
,
1133 file_entry
->fields
[insn_format
]);
1134 insn_table_insert_insn(table
, file_entry
, fields
);
1143 dump_insn(insn
*entry
, int indent
, int levels
)
1145 printf("(insn*)%p\n", entry
);
1147 if (levels
&& entry
!= NULL
) {
1149 dumpf(indent
, "(file_entry ");
1150 dump_table_entry(entry
->file_entry
, indent
+1);
1151 dumpf(indent
, " )\n");
1153 dumpf(indent
, "(fields ");
1154 dump_insn_fields(entry
->fields
, indent
+1);
1155 dumpf(indent
, " )\n");
1157 dumpf(indent
, "(next ");
1158 dump_insn(entry
->next
, indent
+1, levels
-1);
1159 dumpf(indent
, " )\n");
1167 dump_insn_table(insn_table
*table
,
1168 int indent
, int levels
)
1171 printf("(insn_table*)%p\n", table
);
1173 if (levels
&& table
!= NULL
) {
1175 dumpf(indent
, "(opcode_nr %d)\n", table
->opcode_nr
);
1177 dumpf(indent
, "(expanded_bits ");
1178 dump_insn_bits(table
->expanded_bits
, indent
+1, -1);
1179 dumpf(indent
, " )\n");
1181 dumpf(indent
, "(int nr_insn %d)\n", table
->nr_insn
);
1183 dumpf(indent
, "(insns ");
1184 dump_insn(table
->insns
, indent
+1, table
->nr_insn
);
1185 dumpf(indent
, " )\n");
1187 dumpf(indent
, "(opcode_rule ");
1188 dump_opcode_rule(table
->opcode_rule
, indent
+1);
1189 dumpf(indent
, " )\n");
1191 dumpf(indent
, "(opcode ");
1192 dump_opcode_field(table
->opcode
, indent
+1, 1);
1193 dumpf(indent
, " )\n");
1195 dumpf(indent
, "(nr_entries %d)\n", table
->entries
);
1196 dumpf(indent
, "(entries ");
1197 dump_insn_table(table
->entries
, indent
+1, table
->nr_entries
);
1198 dumpf(indent
, " )\n");
1200 dumpf(indent
, "(sibling ", table
->sibling
);
1201 dump_insn_table(table
->sibling
, indent
+1, levels
-1);
1202 dumpf(indent
, " )\n");
1204 dumpf(indent
, "(parent ", table
->parent
);
1205 dump_insn_table(table
->parent
, indent
+1, 0);
1206 dumpf(indent
, " )\n");
1212 /****************************************************************/
1216 lf_print_insn_bits(lf
*file
, insn_bits
*bits
)
1220 lf_print_insn_bits(file
, bits
->last
);
1221 lf_putchr(file
, '_');
1222 lf_putstr(file
, bits
->field
->val_string
);
1223 if (!bits
->opcode
->is_boolean
|| bits
->value
== 0) {
1224 if (bits
->opcode
->last
< bits
->field
->last
)
1225 lf_putint(file
, bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1227 lf_putint(file
, bits
->value
);
1232 lf_print_opcodes(lf
*file
,
1235 if (table
!= NULL
) {
1237 lf_printf(file
, "_%d_%d",
1238 table
->opcode
->first
,
1239 table
->opcode
->last
);
1240 if (table
->parent
== NULL
) break;
1241 lf_printf(file
, "__%d", table
->opcode_nr
);
1242 table
= table
->parent
;
1248 lf_print_table_name(lf
*file
,
1251 lf_printf(file
, "idecode_table");
1252 lf_print_opcodes(file
, table
);
1258 function_name_prefix_semantics
,
1259 function_name_prefix_idecode
,
1260 function_name_prefix_itable
,
1261 function_name_prefix_none
1262 } lf_function_name_prefixes
;
1265 lf_print_function_name(lf
*file
,
1267 insn_bits
*expanded_bits
,
1268 lf_function_name_prefixes prefix
)
1273 case function_name_prefix_semantics
:
1274 lf_putstr(file
, "semantic_");
1276 case function_name_prefix_idecode
:
1277 lf_printf(file
, "idecode_");
1279 case function_name_prefix_itable
:
1280 lf_putstr(file
, "itable_");
1286 /* the function name */
1289 for (pos
= basename
;
1297 lf_putchr(file
, '_');
1300 lf_putchr(file
, *pos
);
1307 if (idecode_expand_semantics
)
1308 lf_print_insn_bits(file
, expanded_bits
);
1313 lf_print_idecode_table(lf
*file
,
1316 int can_assume_leaf
;
1317 opcode_rules
*opcode_rule
;
1319 /* have a look at the rule table, if all table rules follow all
1320 switch rules, I can assume that all end points are leaves */
1321 opcode_rule
= opcode_table
;
1322 while (opcode_rule
!= NULL
1323 && opcode_rule
->use_switch
)
1324 opcode_rule
= opcode_rule
->next
;
1325 while (opcode_rule
!= NULL
1326 && opcode_rule
->use_switch
1327 && opcode_rule
->special_rule
)
1328 opcode_rule
= opcode_rule
->next
;
1329 can_assume_leaf
= opcode_rule
== NULL
;
1331 lf_printf(file
, "{\n");
1332 lf_indent(file
, +2);
1334 lf_printf(file
, "idecode_table_entry *table = ");
1335 lf_print_table_name(file
, entry
);
1336 lf_printf(file
, ";\n");
1337 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1338 i2target(hi_bit_nr
, entry
->opcode
->first
),
1339 i2target(hi_bit_nr
, entry
->opcode
->last
));
1340 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
1341 lf_printf(file
, "while (1) {\n");
1342 lf_indent(file
, +2);
1344 lf_printf(file
, "while (table_entry->mask != 0) {\n");
1345 lf_indent(file
, +2);
1347 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1348 lf_printf(file
, " table_entry->function_or_table);\n");
1349 lf_printf(file
, "opcode = ((instruction & table_entry->mask)\n");
1350 lf_printf(file
, " >> table_entry->shift);\n");
1351 lf_printf(file
, "table_entry = table + opcode;\n");
1353 lf_indent(file
, -2);
1354 lf_printf(file
, "}\n");
1355 if (!idecode_cache
&& can_assume_leaf
) {
1356 lf_printf(file
, "return (((idecode_semantic*)\n");
1357 lf_printf(file
, " table_entry->function_or_table)\n");
1358 lf_printf(file
, " (%s));\n", semantic_actual
);
1360 else if (!idecode_cache
&& !can_assume_leaf
) {
1361 lf_printf(file
, "if (table_entry->shift == 0)");
1362 lf_printf(file
, " return (((idecode_semantic*)\n");
1363 lf_printf(file
, " table_entry->function_or_table)\n");
1364 lf_printf(file
, " (%s));\n", semantic_actual
);
1367 lf_printf(file
, "if (table_entry->shift == 0)\n");
1368 lf_printf(file
, " return (((idecode_crack*)\n");
1369 lf_printf(file
, " table_entry->function_or_table)\n");
1370 lf_printf(file
, " (%s));\n", cache_idecode_actual
);
1372 if (!can_assume_leaf
) {
1373 lf_printf(file
, "opcode = (instruction & table_entry->shift) != 0;\n");
1374 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1375 lf_printf(file
, " table_entry->function_or_table);\n");
1376 lf_printf(file
, "table_entry = table + opcode;\n");
1379 lf_indent(file
, -2);
1380 lf_printf(file
, "}\n");
1382 lf_indent(file
, -2);
1383 lf_printf(file
, "}\n");
1388 lf_print_my_prefix(lf
*file
,
1389 table_entry
*file_entry
,
1392 lf_printf(file
, "const char *const my_prefix = \n");
1393 lf_printf(file
, " \"%s:%s:%s:%d\";\n",
1394 filter_filename (file_entry
->file_name
),
1395 (idecode
? "idecode" : "semantics"),
1396 file_entry
->fields
[insn_name
],
1397 file_entry
->line_nr
);
1402 lf_print_ptrace(lf
*file
,
1405 lf_printf(file
, "\n");
1406 lf_printf(file
, "ITRACE(trace_%s, (\"\\n\"));\n",
1407 (idecode
? "idecode" : "semantics"));
1411 /****************************************************************/
1413 typedef void leaf_handler
1417 typedef void padding_handler
1425 insn_table_traverse_tree(insn_table
*table
,
1428 leaf_handler
*start
,
1431 padding_handler
*padding
)
1436 ASSERT(table
!= NULL
1437 && table
->opcode
!= NULL
1438 && table
->nr_entries
> 0
1439 && table
->entries
!= 0);
1441 if (start
!= NULL
&& depth
>= 0)
1442 start(table
, data
, depth
);
1444 for (entry_nr
= 0, entry
= table
->entries
;
1445 entry_nr
< (table
->opcode
->is_boolean
1447 : (1 << (table
->opcode
->last
- table
->opcode
->first
+ 1)));
1450 || (!table
->opcode
->is_boolean
1451 && entry_nr
< entry
->opcode_nr
)) {
1452 if (padding
!= NULL
&& depth
>= 0)
1453 padding(table
, data
, depth
, entry_nr
);
1456 ASSERT(entry
!= NULL
&& (entry
->opcode_nr
== entry_nr
1457 || table
->opcode
->is_boolean
));
1458 if (entry
->opcode
!= NULL
&& depth
!= 0) {
1459 insn_table_traverse_tree(entry
, data
, depth
+1,
1460 start
, leaf
, end
, padding
);
1462 else if (depth
>= 0) {
1464 leaf(entry
, data
, depth
);
1466 entry
= entry
->sibling
;
1469 if (end
!= NULL
&& depth
>= 0)
1470 end(table
, data
, depth
);
1474 typedef void function_handler
1477 table_entry
*function
);
1480 insn_table_traverse_function(insn_table
*table
,
1482 function_handler
*leaf
)
1485 for (function
= table
->functions
;
1487 function
= function
->next
) {
1488 leaf(table
, data
, function
->file_entry
);
1493 typedef void insn_handler
1499 insn_table_traverse_insn(insn_table
*table
,
1504 for (instruction
= table
->insns
;
1505 instruction
!= NULL
;
1506 instruction
= instruction
->next
) {
1507 leaf(table
, data
, instruction
);
1513 update_depth(insn_table
*entry
,
1517 int *max_depth
= (int*)data
;
1518 if (*max_depth
< depth
)
1524 insn_table_depth(insn_table
*table
)
1527 insn_table_traverse_tree(table
,
1538 /****************************************************************/
1541 dump_traverse_start(insn_table
*table
,
1545 dumpf(depth
*2, "(%d\n", table
->opcode_nr
);
1549 dump_traverse_leaf(insn_table
*entry
,
1553 ASSERT(entry
->nr_entries
== 0
1554 && entry
->nr_insn
== 1
1555 && entry
->opcode
== NULL
);
1556 dumpf(depth
*2, ".%d %s\n", entry
->opcode_nr
,
1557 entry
->insns
->file_entry
->fields
[insn_format
]);
1561 dump_traverse_end(insn_table
*table
,
1565 dumpf(depth
*2, ")\n");
1569 dump_traverse_padding(insn_table
*table
,
1574 dumpf(depth
*2, ".<%d>\n", opcode_nr
);
1579 dump_traverse(insn_table
*table
)
1581 insn_table_traverse_tree(table
, NULL
, 1,
1582 dump_traverse_start
,
1585 dump_traverse_padding
);
1589 /****************************************************************/
1593 semantics_h_print_function(lf
*file
,
1595 insn_bits
*expanded_bits
)
1597 lf_printf(file
, "\n");
1598 lf_printf(file
, "STATIC_SEMANTICS unsigned_word ");
1599 lf_print_function_name(file
,
1602 function_name_prefix_semantics
);
1603 lf_printf(file
, "\n(%s);\n",
1604 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
1609 semantics_h_leaf(insn_table
*entry
,
1613 lf
*file
= (lf
*)data
;
1614 ASSERT(entry
->nr_insn
== 1);
1615 semantics_h_print_function(file
,
1616 entry
->insns
->file_entry
->fields
[insn_name
],
1617 entry
->expanded_bits
);
1621 semantics_h_insn(insn_table
*entry
,
1625 lf
*file
= (lf
*)data
;
1626 semantics_h_print_function(file
,
1627 instruction
->file_entry
->fields
[insn_name
],
1632 semantics_h_function(insn_table
*entry
,
1634 table_entry
*function
)
1636 lf
*file
= (lf
*)data
;
1637 if (function
->fields
[function_type
] == NULL
1638 || function
->fields
[function_type
][0] == '\0') {
1639 semantics_h_print_function(file
,
1640 function
->fields
[function_name
],
1644 lf_printf(file
, "\n");
1645 lf_printf(file
, "INLINE_SEMANTICS %s %s\n(%s);\n",
1646 function
->fields
[function_type
],
1647 function
->fields
[function_name
],
1648 function
->fields
[function_param
]);
1654 gen_semantics_h(insn_table
*table
, lf
*file
)
1657 lf_print_copyleft(file
);
1658 lf_printf(file
, "\n");
1659 lf_printf(file
, "#ifndef _SEMANTICS_H_\n");
1660 lf_printf(file
, "#define _SEMANTICS_H_\n");
1661 lf_printf(file
, "\n");
1662 lf_printf(file
, "#ifndef INLINE_SEMANTICS\n");
1663 lf_printf(file
, "#define INLINE_SEMANTICS\n");
1664 lf_printf(file
, "#endif\n");
1665 lf_printf(file
, "\n");
1666 lf_printf(file
, "#ifndef STATIC_SEMANTICS\n");
1667 lf_printf(file
, "#define STATIC_SEMANTICS\n");
1668 lf_printf(file
, "#endif\n");
1669 lf_printf(file
, "\n");
1670 lf_printf(file
, "\n");
1672 /* output a declaration for all functions */
1673 insn_table_traverse_function(table
,
1675 semantics_h_function
);
1677 /* output a declaration for all instructions */
1678 if (idecode_expand_semantics
)
1679 insn_table_traverse_tree(table
,
1683 semantics_h_leaf
, /* leaf */
1685 NULL
); /* padding */
1687 insn_table_traverse_insn(table
,
1691 lf_printf(file
, "\n");
1692 lf_printf(file
, "#endif /* _SEMANTICS_H_ */\n");
1696 /****************************************************************/
1698 typedef struct _icache_tree icache_tree
;
1699 struct _icache_tree
{
1702 icache_tree
*children
;
1705 static icache_tree
*
1706 icache_tree_insert(icache_tree
*tree
,
1709 icache_tree
*new_tree
;
1711 icache_tree
**ptr_to_cur_tree
= &tree
->children
;
1712 icache_tree
*cur_tree
= *ptr_to_cur_tree
;
1713 while (cur_tree
!= NULL
1714 && strcmp(cur_tree
->name
, name
) < 0) {
1715 ptr_to_cur_tree
= &cur_tree
->next
;
1716 cur_tree
= *ptr_to_cur_tree
;
1718 ASSERT(cur_tree
== NULL
1719 || strcmp(cur_tree
->name
, name
) >= 0);
1720 /* already in the tree */
1721 if (cur_tree
!= NULL
1722 && strcmp(cur_tree
->name
, name
) == 0)
1724 /* missing, insert it */
1725 ASSERT(cur_tree
== NULL
1726 || strcmp(cur_tree
->name
, name
) > 0);
1727 new_tree
= ZALLOC(icache_tree
);
1728 new_tree
->name
= name
;
1729 new_tree
->next
= cur_tree
;
1730 *ptr_to_cur_tree
= new_tree
;
1735 static icache_tree
*
1736 insn_table_cache_fields(insn_table
*table
)
1738 icache_tree
*tree
= ZALLOC(icache_tree
);
1740 for (instruction
= table
->insns
;
1741 instruction
!= NULL
;
1742 instruction
= instruction
->next
) {
1745 icache_tree_insert(tree
,
1746 instruction
->file_entry
->fields
[insn_form
]);
1747 for (field
= instruction
->fields
->first
;
1749 field
= field
->next
) {
1750 if (field
->is_string
)
1751 icache_tree_insert(form
, field
->val_string
);
1760 gen_icache_h(icache_tree
*tree
,
1763 lf_print_copyleft(file
);
1764 lf_printf(file
, "\n");
1765 lf_printf(file
, "#ifndef _ICACHE_H_\n");
1766 lf_printf(file
, "#define _ICACHE_H_\n");
1767 lf_printf(file
, "\n");
1768 lf_printf(file
, "#ifndef INLINE_ICACHE\n");
1769 lf_printf(file
, "#define INLINE_ICACHE\n");
1770 lf_printf(file
, "#endif\n");
1771 lf_printf(file
, "\n");
1773 lf_printf(file
, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1775 lf_printf(file
, "\n");
1777 /* create an instruction cache if being used */
1778 if (idecode_cache
) {
1780 lf_printf(file
, "typedef struct _idecode_cache {\n");
1781 lf_printf(file
, " unsigned_word address;\n");
1782 lf_printf(file
, " void *semantic;\n");
1783 lf_printf(file
, " union {\n");
1784 for (form
= tree
->children
;
1786 form
= form
->next
) {
1788 lf_printf(file
, " struct {\n");
1789 for (field
= form
->children
;
1791 field
= field
->next
) {
1792 cache_rules
*cache_rule
;
1794 for (cache_rule
= cache_table
;
1796 cache_rule
= cache_rule
->next
) {
1797 if (strcmp(field
->name
, cache_rule
->old_name
) == 0) {
1799 if (cache_rule
->new_name
!= NULL
)
1800 lf_printf(file
, " %s %s; /* %s */\n",
1801 (cache_rule
->type
== NULL
1803 : cache_rule
->type
),
1804 cache_rule
->new_name
,
1805 cache_rule
->old_name
);
1809 lf_printf(file
, " unsigned %s;\n", field
->name
);
1811 lf_printf(file
, " } %s;\n", form
->name
);
1813 lf_printf(file
, " } crack;\n");
1814 lf_printf(file
, "} idecode_cache;\n");
1817 /* alernativly, since no cache, #define the fields to be
1818 extractions from the instruction variable */
1819 cache_rules
*cache_rule
;
1820 lf_printf(file
, "\n");
1821 for (cache_rule
= cache_table
;
1823 cache_rule
= cache_rule
->next
) {
1824 if (cache_rule
->expression
!= NULL
1825 && strlen(cache_rule
->expression
) > 0)
1826 lf_printf(file
, "#define %s %s\n",
1827 cache_rule
->new_name
, cache_rule
->expression
);
1831 lf_printf(file
, "\n");
1832 lf_printf(file
, "#endif /* _ICACHE_H_ */\n");
1838 /****************************************************************/
1842 lf_print_c_extraction(lf
*file
,
1846 char *field_expression
,
1847 insn_field
*cur_field
,
1849 int get_value_from_cache
,
1850 int put_value_in_cache
)
1852 ASSERT(field_name
!= NULL
);
1854 && (!bits
->opcode
->is_boolean
|| bits
->value
== 0)
1855 && strcmp(field_name
, cur_field
->val_string
) == 0) {
1856 ASSERT(bits
->field
== cur_field
);
1857 ASSERT(field_type
== NULL
);
1858 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1859 lf_printf(file
, "const unsigned %s = ",
1861 if (bits
->opcode
->last
< bits
->field
->last
)
1862 lf_printf(file
, "%d;\n",
1863 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1865 lf_printf(file
, "%d;\n", bits
->value
);
1868 /* put the field in the local variable */
1869 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1870 lf_printf(file
, "%s const %s = ",
1871 field_type
== NULL
? "unsigned" : field_type
,
1873 /* getting it from the cache */
1874 if (get_value_from_cache
|| put_value_in_cache
) {
1875 lf_printf(file
, "cache_entry->crack.%s.%s",
1876 instruction
->file_entry
->fields
[insn_form
],
1878 if (put_value_in_cache
) /* also put it in the cache? */
1879 lf_printf(file
, " = ");
1881 if (!get_value_from_cache
) {
1882 if (strcmp(field_name
, cur_field
->val_string
) == 0)
1883 lf_printf(file
, "EXTRACTED32(instruction, %d, %d)",
1884 i2target(hi_bit_nr
, cur_field
->first
),
1885 i2target(hi_bit_nr
, cur_field
->last
));
1886 else if (field_expression
!= NULL
)
1887 lf_printf(file
, "%s", field_expression
);
1889 lf_printf(file
, "eval_%s", field_name
);
1891 lf_printf(file
, ";\n");
1897 lf_print_c_extractions(lf
*file
,
1899 insn_bits
*expanded_bits
,
1900 int get_value_from_cache
,
1901 int put_value_in_cache
)
1903 insn_field
*cur_field
;
1905 /* extract instruction fields */
1906 lf_printf(file
, "/* extraction: %s */\n",
1907 instruction
->file_entry
->fields
[insn_format
]);
1909 for (cur_field
= instruction
->fields
->first
;
1910 cur_field
->first
< insn_size
;
1911 cur_field
= cur_field
->next
) {
1912 if (cur_field
->is_string
) {
1915 /* find any corresponding value */
1916 for (bits
= expanded_bits
;
1918 bits
= bits
->last
) {
1919 if (bits
->field
== cur_field
)
1922 /* try the cache rule table for what to do */
1923 if (get_value_from_cache
|| put_value_in_cache
) {
1924 cache_rules
*cache_rule
;
1925 for (cache_rule
= cache_table
;
1927 cache_rule
= cache_rule
->next
) {
1928 if (strcmp(cur_field
->val_string
, cache_rule
->old_name
) == 0) {
1930 if (cache_rule
->valid
> 1 && put_value_in_cache
)
1931 lf_print_c_extraction(file
,
1933 cache_rule
->new_name
,
1935 cache_rule
->expression
,
1940 else if (cache_rule
->valid
== 1)
1941 lf_print_c_extraction(file
,
1943 cache_rule
->new_name
,
1945 cache_rule
->expression
,
1948 get_value_from_cache
,
1949 put_value_in_cache
);
1953 if (found_rule
== 0)
1954 lf_print_c_extraction(file
,
1956 cur_field
->val_string
,
1961 get_value_from_cache
,
1962 put_value_in_cache
);
1963 /* if any (XXX == 0), output a corresponding test */
1964 if (instruction
->file_entry
->annex
!= NULL
) {
1965 char *field_name
= cur_field
->val_string
;
1966 char *is_0_ptr
= instruction
->file_entry
->annex
;
1967 int field_len
= strlen(field_name
);
1968 if (strlen(is_0_ptr
) >= (strlen("_is_0") + field_len
)) {
1969 is_0_ptr
+= field_len
;
1970 while ((is_0_ptr
= strstr(is_0_ptr
, "_is_0")) != NULL
) {
1971 if (strncmp(is_0_ptr
- field_len
, field_name
, field_len
) == 0
1972 && !isalpha(is_0_ptr
[ - field_len
- 1])) {
1973 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1974 lf_printf(file
, "const unsigned %s_is_0 = (", field_name
);
1976 lf_printf(file
, "%d", bits
->value
);
1978 lf_printf(file
, "%s", field_name
);
1979 lf_printf(file
, " == 0);\n");
1982 is_0_ptr
+= strlen("_is_0");
1986 /* any thing else ... */
1989 lf_print_lf_c_line_nr(file
);
1994 lf_print_idecode_illegal(lf
*file
)
1997 lf_printf(file
, "return idecode_illegal(%s);\n", cache_idecode_actual
);
1999 lf_printf(file
, "return semantic_illegal(%s);\n", semantic_actual
);
2004 lf_print_idecode_floating_point_unavailable(lf
*file
)
2007 lf_printf(file
, "return idecode_floating_point_unavailable(%s);\n",
2008 cache_idecode_actual
);
2010 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
2015 /* Output code to do any final checks on the decoded instruction.
2016 This includes things like verifying any on decoded fields have the
2017 correct value and checking that (for floating point) floating point
2018 hardware isn't disabled */
2021 lf_print_c_validate(lf
*file
,
2023 opcode_field
*opcodes
)
2025 /* Validate: unchecked instruction fields
2027 If any constant fields in the instruction were not checked by the
2028 idecode tables, output code to check that they have the correct
2031 unsigned check_mask
= 0;
2032 unsigned check_val
= 0;
2034 opcode_field
*opcode
;
2036 /* form check_mask/check_val containing what needs to be checked
2037 in the instruction */
2038 for (field
= instruction
->fields
->first
;
2039 field
->first
< insn_size
;
2040 field
= field
->next
) {
2042 check_mask
<<= field
->width
;
2043 check_val
<<= field
->width
;
2045 /* is it a constant that could need validating? */
2046 if (!field
->is_int
&& !field
->is_slash
)
2049 /* has it been checked by a table? */
2050 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
2051 if (field
->first
>= opcode
->first
2052 && field
->last
<= opcode
->last
)
2058 check_mask
|= (1 << field
->width
)-1;
2059 check_val
|= field
->val_int
;
2062 /* if any bits not checked by opcode tables, output code to check them */
2064 lf_printf(file
, "\n");
2065 lf_printf(file
, "/* validate: %s */\n",
2066 instruction
->file_entry
->fields
[insn_format
]);
2067 lf_printf(file
, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
2068 check_mask
, check_val
);
2069 lf_indent(file
, +2);
2070 lf_print_idecode_illegal(file
);
2071 lf_indent(file
, -2);
2075 /* Validate floating point hardware
2077 If the simulator is being built with out floating point hardware
2078 (different to it being disabled in the MSR) then floating point
2079 instructions are invalid */
2081 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2082 lf_printf(file
, "\n");
2083 lf_printf(file
, "/* Validate: FP hardware exists */\n");
2084 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
2085 lf_indent(file
, +2);
2086 lf_print_idecode_illegal(file
);
2087 lf_indent(file
, -2);
2091 /* Validate: Floating Point available
2093 If floating point is not available, we enter a floating point
2094 unavailable interrupt into the cache instead of the instruction
2097 The PowerPC spec requires a CSI after MSR[FP] is changed and when
2098 ever a CSI occures we flush the instruction cache. */
2101 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2102 lf_printf(file
, "\n");
2103 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
2104 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
2105 lf_indent(file
, +2);
2106 lf_print_idecode_floating_point_unavailable(file
);
2107 lf_indent(file
, -2);
2114 lf_print_c_cracker(lf
*file
,
2116 insn_bits
*expanded_bits
,
2117 opcode_field
*opcodes
)
2120 /* function header */
2121 lf_printf(file
, "{\n");
2122 lf_indent(file
, +2);
2124 lf_print_my_prefix(file
,
2125 instruction
->file_entry
,
2126 1/*putting-value-in-cache*/);
2128 lf_print_ptrace(file
,
2129 1/*putting-value-in-cache*/);
2131 lf_print_c_validate(file
, instruction
, opcodes
);
2133 lf_printf(file
, "\n");
2134 lf_printf(file
, "{\n");
2135 lf_indent(file
, +2);
2136 lf_print_c_extractions(file
,
2139 0/*get_value_from_cache*/,
2140 1/*put_value_in_cache*/);
2141 lf_indent(file
, -2);
2142 lf_printf(file
, "}\n");
2144 /* return the function propper (main sorts this one out) */
2145 lf_printf(file
, "\n");
2146 lf_printf(file
, "/* semantic routine */\n");
2147 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2148 lf_printf(file
, "return ");
2149 lf_print_function_name(file
,
2150 instruction
->file_entry
->fields
[insn_name
],
2152 function_name_prefix_semantics
);
2153 lf_printf(file
, ";\n");
2155 lf_print_lf_c_line_nr(file
);
2156 lf_indent(file
, -2);
2157 lf_printf(file
, "}\n");
2162 lf_print_c_semantic(lf
*file
,
2164 insn_bits
*expanded_bits
,
2165 opcode_field
*opcodes
)
2168 lf_printf(file
, "{\n");
2169 lf_indent(file
, +2);
2171 lf_print_my_prefix(file
,
2172 instruction
->file_entry
,
2173 0/*not putting value in cache*/);
2174 lf_printf(file
, "unsigned_word nia = cia + %d;\n", insn_size
/ 8);
2176 lf_printf(file
, "\n");
2177 lf_print_c_extractions(file
,
2180 idecode_cache
/*get_value_from_cache*/,
2181 0/*put_value_in_cache*/);
2183 lf_print_ptrace(file
,
2184 0/*put_value_in_cache*/);
2186 /* validate the instruction, if a cache this has already been done */
2188 lf_print_c_validate(file
, instruction
, opcodes
);
2190 /* generate the profileing call - this is delayed until after the
2191 instruction has been verified */
2192 lf_printf(file
, "\n");
2193 lf_printf(file
, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
2194 lf_printf(file
, " mon_issue(");
2195 lf_print_function_name(file
,
2196 instruction
->file_entry
->fields
[insn_name
],
2198 function_name_prefix_itable
);
2199 lf_printf(file
, ", processor, cia);\n");
2201 /* generate the code (or at least something */
2202 if (instruction
->file_entry
->annex
!= NULL
) {
2204 lf_printf(file
, "\n");
2205 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2206 lf_printf(file
, "{\n");
2207 lf_indent(file
, +2);
2208 lf_print_c_code(file
, instruction
->file_entry
->annex
);
2209 lf_indent(file
, -2);
2210 lf_printf(file
, "}\n");
2211 lf_print_lf_c_line_nr(file
);
2213 else if (it_is("nop", instruction
->file_entry
->fields
[insn_flags
])) {
2214 lf_print_lf_c_line_nr(file
);
2216 else if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2217 /* unimplemented floating point instruction - call for assistance */
2218 lf_printf(file
, "\n");
2219 lf_printf(file
, "/* unimplemented floating point instruction - call for assistance */\n");
2220 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2221 lf_putstr(file
, "floating_point_assist_interrupt(processor, cia);\n");
2222 lf_print_lf_c_line_nr(file
);
2225 /* abort so it is implemented now */
2226 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2227 lf_putstr(file
, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2228 lf_print_lf_c_line_nr(file
);
2229 lf_printf(file
, "\n");
2232 /* the function footer */
2233 lf_printf(file
, "return nia;\n");
2234 lf_indent(file
, -2);
2235 lf_printf(file
, "}\n");
2239 lf_print_c_semantic_function_header(lf
*file
,
2241 insn_bits
*expanded_bits
)
2243 lf_printf(file
, "\n");
2244 lf_printf(file
, "STATIC_SEMANTICS unsigned_word\n");
2245 lf_print_function_name(file
,
2248 function_name_prefix_semantics
);
2249 lf_printf(file
, "\n(%s)\n",
2250 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2254 lf_print_c_semantic_function(lf
*file
,
2256 insn_bits
*expanded_bits
,
2257 opcode_field
*opcodes
)
2260 /* build the semantic routine to execute the instruction */
2261 lf_print_c_semantic_function_header(file
,
2262 instruction
->file_entry
->fields
[insn_name
],
2264 lf_print_c_semantic(file
,
2272 semantics_c_leaf(insn_table
*entry
,
2276 lf
*file
= (lf
*)data
;
2277 ASSERT(entry
->nr_insn
== 1
2278 && entry
->opcode
== NULL
2279 && entry
->parent
!= NULL
2280 && entry
->parent
->opcode
!= NULL
);
2281 lf_print_c_semantic_function(file
,
2283 entry
->expanded_bits
,
2284 entry
->parent
->opcode
);
2288 semantics_c_insn(insn_table
*table
,
2292 lf
*file
= (lf
*)data
;
2293 lf_print_c_semantic_function(file
, instruction
,
2298 semantics_c_function(insn_table
*table
,
2300 table_entry
*function
)
2302 lf
*file
= (lf
*)data
;
2303 if (function
->fields
[function_type
] == NULL
2304 || function
->fields
[function_type
][0] == '\0') {
2305 lf_print_c_semantic_function_header(file
,
2306 function
->fields
[function_name
],
2310 lf_printf(file
, "\n");
2311 lf_printf(file
, "INLINE_SEMANTICS %s\n%s(%s)\n",
2312 function
->fields
[function_type
],
2313 function
->fields
[function_name
],
2314 function
->fields
[function_param
]);
2316 table_entry_lf_c_line_nr(file
, function
);
2317 lf_printf(file
, "{\n");
2318 lf_indent(file
, +2);
2319 lf_print_c_code(file
, function
->annex
);
2320 lf_indent(file
, -2);
2321 lf_printf(file
, "}\n");
2322 lf_print_lf_c_line_nr(file
);
2328 gen_semantics_c(insn_table
*table
, lf
*file
)
2330 lf_print_copyleft(file
);
2331 lf_printf(file
, "\n");
2332 lf_printf(file
, "#ifndef _SEMANTICS_C_\n");
2333 lf_printf(file
, "#define _SEMANTICS_C_\n");
2334 lf_printf(file
, "\n");
2335 lf_printf(file
, "#ifndef STATIC_INLINE_SEMANTICS\n");
2336 lf_printf(file
, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2337 lf_printf(file
, "#endif\n");
2338 lf_printf(file
, "\n");
2339 lf_printf(file
, "#include \"cpu.h\"\n");
2340 lf_printf(file
, "#include \"idecode.h\"\n");
2341 lf_printf(file
, "#include \"semantics.h\"\n");
2342 lf_printf(file
, "\n");
2344 /* output a definition (c-code) for all functions */
2345 insn_table_traverse_function(table
,
2347 semantics_c_function
);
2349 /* output a definition (c-code) for all instructions */
2350 if (idecode_expand_semantics
)
2351 insn_table_traverse_tree(table
,
2357 NULL
); /* padding */
2359 insn_table_traverse_insn(table
,
2363 lf_printf(file
, "\n");
2364 lf_printf(file
, "#endif /* _SEMANTICS_C_ */\n");
2368 /****************************************************************/
2371 gen_idecode_h(insn_table
*table
, lf
*file
)
2373 lf_print_copyleft(file
);
2374 lf_printf(file
, "\n");
2375 lf_printf(file
, "#ifndef _IDECODE_H_\n");
2376 lf_printf(file
, "#define _IDECODE_H_\n");
2377 lf_printf(file
, "\n");
2378 lf_printf(file
, "#ifndef INLINE_IDECODE\n");
2379 lf_printf(file
, "#define INLINE_IDECODE\n");
2380 lf_printf(file
, "#endif\n");
2381 lf_printf(file
, "\n");
2382 lf_printf(file
, "#include \"idecode_expression.h\"\n");
2383 lf_printf(file
, "#include \"idecode_fields.h\"\n");
2384 lf_printf(file
, "#include \"idecode_branch.h\"\n");
2385 lf_printf(file
, "\n");
2386 lf_printf(file
, "#include \"icache.h\"\n");
2387 lf_printf(file
, "\n");
2388 lf_printf(file
, "typedef unsigned_word idecode_semantic\n(%s);\n",
2389 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2390 lf_printf(file
, "\n");
2392 lf_printf(file
, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2393 cache_idecode_formal
);
2395 lf_printf(file
, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2397 lf_printf(file
, "\n");
2398 lf_printf(file
, "#endif /* _IDECODE_H_ */\n");
2402 /****************************************************************/
2406 idecode_table_start(insn_table
*table
,
2410 lf
*file
= (lf
*)data
;
2412 /* start of the table */
2413 if (!table
->opcode_rule
->use_switch
) {
2414 lf_printf(file
, "\n");
2415 lf_printf(file
, "static idecode_table_entry ");
2416 lf_print_table_name(file
, table
);
2417 lf_printf(file
, "[] = {\n");
2422 idecode_table_leaf(insn_table
*entry
,
2426 lf
*file
= (lf
*)data
;
2427 ASSERT(entry
->parent
!= NULL
);
2430 /* add an entry to the table */
2431 if (!entry
->parent
->opcode_rule
->use_switch
) {
2432 if (entry
->opcode
== NULL
) {
2433 /* table leaf entry */
2434 lf_printf(file
, " /*%d*/ { 0, 0, ", entry
->opcode_nr
);
2435 lf_print_function_name(file
,
2436 entry
->insns
->file_entry
->fields
[insn_name
],
2437 entry
->expanded_bits
,
2439 ? function_name_prefix_idecode
2440 : function_name_prefix_semantics
));
2441 lf_printf(file
, " },\n");
2443 else if (entry
->opcode_rule
->use_switch
) {
2444 /* table calling switch statement */
2445 lf_printf(file
, " /*%d*/ { -1, 0, ",
2447 lf_print_table_name(file
, entry
);
2448 lf_printf(file
, " },\n");
2451 /* table `calling' another table */
2452 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
2453 if (entry
->opcode
->is_boolean
)
2454 lf_printf(file
, "MASK32(%d,%d), 0, ",
2455 i2target(hi_bit_nr
, entry
->opcode
->first
),
2456 i2target(hi_bit_nr
, entry
->opcode
->last
));
2458 lf_printf(file
, "%d, MASK32(%d,%d), ",
2459 insn_size
- entry
->opcode
->last
- 1,
2460 i2target(hi_bit_nr
, entry
->opcode
->first
),
2461 i2target(hi_bit_nr
, entry
->opcode
->last
));
2462 lf_print_table_name(file
, entry
);
2463 lf_printf(file
, " },\n");
2469 idecode_table_end(insn_table
*table
,
2473 lf
*file
= (lf
*)data
;
2476 if (!table
->opcode_rule
->use_switch
) {
2477 lf_printf(file
, "};\n");
2482 idecode_table_padding(insn_table
*table
,
2487 lf
*file
= (lf
*)data
;
2490 if (!table
->opcode_rule
->use_switch
) {
2491 lf_printf(file
, " /*%d*/ { 0, 0, %s_illegal },\n",
2492 opcode_nr
, (idecode_cache
? "idecode" : "semantic"));
2497 /****************************************************************/
2500 void lf_print_idecode_switch
2506 idecode_switch_start(insn_table
*table
,
2510 lf
*file
= (lf
*)data
;
2512 ASSERT(table
->opcode_rule
->use_switch
);
2514 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2515 i2target(hi_bit_nr
, table
->opcode
->first
),
2516 i2target(hi_bit_nr
, table
->opcode
->last
));
2521 idecode_switch_leaf(insn_table
*entry
,
2525 lf
*file
= (lf
*)data
;
2526 ASSERT(entry
->parent
!= NULL
);
2528 ASSERT(entry
->parent
->opcode_rule
->use_switch
);
2530 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
2531 lf_indent(file
, +2);
2533 if (entry
->opcode
== NULL
) {
2534 /* switch calling leaf */
2535 lf_printf(file
, "return ");
2536 lf_print_function_name(file
,
2537 entry
->insns
->file_entry
->fields
[insn_name
],
2538 entry
->expanded_bits
,
2540 ? function_name_prefix_idecode
2541 : function_name_prefix_semantics
));
2543 lf_printf(file
, "(%s);\n", cache_idecode_actual
);
2545 lf_printf(file
, "(%s);\n", semantic_actual
);
2547 else if (entry
->opcode_rule
->use_switch
) {
2548 /* switch calling switch */
2549 lf_print_idecode_switch(file
, entry
);
2552 /* switch calling table */
2553 lf_printf(file
, "return ");
2554 lf_print_idecode_table(file
, entry
);
2556 lf_printf(file
, "break;\n");
2558 lf_indent(file
, -2);
2563 lf_print_idecode_switch_illegal(lf
*file
)
2565 lf_indent(file
, +2);
2566 lf_print_idecode_illegal(file
);
2567 lf_printf(file
, "break;\n");
2568 lf_indent(file
, -2);
2572 idecode_switch_end(insn_table
*table
,
2576 lf
*file
= (lf
*)data
;
2578 ASSERT(table
->opcode_rule
->use_switch
);
2580 if (table
->opcode_rule
->use_switch
== 1) {
2581 lf_printf(file
, "default:\n");
2582 lf_print_idecode_switch_illegal(file
);
2584 lf_printf(file
, "}\n");
2588 idecode_switch_padding(insn_table
*table
,
2593 lf
*file
= (lf
*)data
;
2596 ASSERT(table
->opcode_rule
->use_switch
);
2598 if (table
->opcode_rule
->use_switch
> 1) {
2599 lf_printf(file
, "case %d:\n", opcode_nr
);
2600 lf_print_idecode_switch_illegal(file
);
2606 lf_print_idecode_switch(lf
*file
,
2609 insn_table_traverse_tree(table
,
2612 idecode_switch_start
,
2613 idecode_switch_leaf
,
2615 idecode_switch_padding
);
2620 idecode_expand_if_switch(insn_table
*table
,
2624 lf
*file
= (lf
*)data
;
2626 if (table
->opcode_rule
->use_switch
2627 && table
->parent
!= NULL
/* don't expand the top one yet */
2628 && !table
->parent
->opcode_rule
->use_switch
) {
2629 lf_printf(file
, "\n");
2630 lf_printf(file
, "STATIC_INLINE_IDECODE void\n");
2631 lf_print_table_name(file
, table
);
2632 lf_printf(file
, "\n(%s)\n",
2633 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2634 lf_printf(file
, "{\n");
2636 lf_indent(file
, +2);
2637 lf_print_idecode_switch(file
, table
);
2638 lf_indent(file
, -2);
2640 lf_printf(file
, "}\n");
2646 lf_print_c_cracker_function(lf
*file
,
2648 insn_bits
*expanded_bits
,
2649 opcode_field
*opcodes
)
2651 /* if needed, generate code to enter this routine into a cache */
2652 lf_printf(file
, "\n");
2653 lf_printf(file
, "STATIC_IDECODE idecode_semantic *\n");
2654 lf_print_function_name(file
,
2655 instruction
->file_entry
->fields
[insn_name
],
2657 function_name_prefix_idecode
);
2658 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2660 lf_print_c_cracker(file
,
2667 idecode_crack_leaf(insn_table
*entry
,
2671 lf
*file
= (lf
*)data
;
2672 ASSERT(entry
->nr_insn
== 1
2673 && entry
->opcode
== NULL
2674 && entry
->parent
!= NULL
2675 && entry
->parent
->opcode
!= NULL
);
2676 lf_print_c_cracker_function(file
,
2678 entry
->expanded_bits
,
2683 idecode_crack_insn(insn_table
*entry
,
2687 lf
*file
= (lf
*)data
;
2688 lf_print_c_cracker_function(file
,
2695 idecode_c_internal_function(insn_table
*table
,
2697 table_entry
*function
)
2699 lf
*file
= (lf
*)data
;
2700 ASSERT(idecode_cache
!= 0);
2701 if (it_is("internal", function
->fields
[insn_flags
])) {
2702 lf_printf(file
, "\n");
2703 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2704 lf_print_function_name(file
,
2705 function
->fields
[insn_name
],
2707 function_name_prefix_idecode
);
2708 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2709 lf_printf(file
, "{\n");
2710 lf_indent(file
, +2);
2711 lf_printf(file
, "/* semantic routine */\n");
2712 table_entry_lf_c_line_nr(file
, function
);
2713 lf_printf(file
, "return ");
2714 lf_print_function_name(file
,
2715 function
->fields
[insn_name
],
2717 function_name_prefix_semantics
);
2718 lf_printf(file
, ";\n");
2720 lf_print_lf_c_line_nr(file
);
2721 lf_indent(file
, -2);
2722 lf_printf(file
, "}\n");
2727 /****************************************************************/
2730 gen_idecode_c(insn_table
*table
, lf
*file
)
2735 lf_print_copyleft(file
);
2736 lf_printf(file
, "\n");
2737 lf_printf(file
, "\n");
2738 lf_printf(file
, "#ifndef _IDECODE_C_\n");
2739 lf_printf(file
, "#define _IDECODE_C_\n");
2740 lf_printf(file
, "\n");
2741 lf_printf(file
, "#ifndef STATIC_INLINE_IDECODE\n");
2742 lf_printf(file
, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2743 lf_printf(file
, "#endif\n");
2744 lf_printf(file
, "\n");
2745 lf_printf(file
, "#ifndef STATIC_IDECODE\n");
2746 lf_printf(file
, "#define STATIC_IDECODE\n");
2747 lf_printf(file
, "#endif\n");
2748 lf_printf(file
, "\n");
2749 lf_printf(file
, "#include \"cpu.h\"\n");
2750 lf_printf(file
, "#include \"idecode.h\"\n");
2751 lf_printf(file
, "#include \"semantics.h\"\n");
2752 lf_printf(file
, "\n");
2753 lf_printf(file
, "\n");
2754 lf_printf(file
, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2755 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2756 lf_printf(file
, "\n");
2757 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
2758 lf_printf(file
, " unsigned shift;\n");
2759 lf_printf(file
, " unsigned mask;\n");
2760 lf_printf(file
, " void *function_or_table;\n");
2761 lf_printf(file
, "} idecode_table_entry;\n");
2762 lf_printf(file
, "\n");
2763 lf_printf(file
, "\n");
2765 /* output `internal' invalid/floating-point unavailable functions
2767 if (idecode_cache
) {
2768 insn_table_traverse_function(table
,
2770 idecode_c_internal_function
);
2773 /* output cracking functions where needed */
2774 if (idecode_cache
) {
2775 if (idecode_expand_semantics
)
2776 insn_table_traverse_tree(table
,
2784 insn_table_traverse_insn(table
,
2786 idecode_crack_insn
);
2790 /* output tables where needed */
2791 for (depth
= insn_table_depth(table
);
2794 insn_table_traverse_tree(table
,
2797 idecode_table_start
,
2800 idecode_table_padding
);
2803 /* output switch functions where needed */
2804 insn_table_traverse_tree(table
,
2807 idecode_expand_if_switch
, /* START */
2810 /* output the main idecode routine */
2811 lf_printf(file
, "\n");
2813 lf_printf(file
, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2814 cache_idecode_formal
);
2816 lf_printf(file
, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2818 lf_printf(file
, "{\n");
2819 lf_indent(file
, +2);
2820 if (table
->opcode_rule
->use_switch
)
2821 lf_print_idecode_switch(file
, table
);
2823 lf_print_idecode_table(file
, table
);
2824 lf_indent(file
, -2);
2825 lf_printf(file
, "}\n");
2826 lf_printf(file
, "\n");
2827 lf_printf(file
, "#endif\n");
2831 /****************************************************************/
2834 itable_h_insn(insn_table
*entry
,
2838 lf
*file
= (lf
*)data
;
2839 lf_printf(file
, " ");
2840 lf_print_function_name(file
,
2841 instruction
->file_entry
->fields
[insn_name
],
2843 function_name_prefix_itable
);
2844 lf_printf(file
, ",\n");
2849 gen_itable_h(insn_table
*table
, lf
*file
)
2852 lf_print_copyleft(file
);
2853 lf_printf(file
, "\n");
2854 lf_printf(file
, "#ifndef _ITABLE_H_\n");
2855 lf_printf(file
, "#define _ITABLE_H_\n");
2856 lf_printf(file
, "\n");
2857 lf_printf(file
, "#ifndef INLINE_ITABLE\n");
2858 lf_printf(file
, "#define INLINE_ITABLE\n");
2859 lf_printf(file
, "#endif\n");
2860 lf_printf(file
, "\n");
2861 lf_printf(file
, "\n");
2863 /* output an enumerated type for each instruction */
2864 lf_printf(file
, "typedef enum {\n");
2865 insn_table_traverse_insn(table
,
2868 lf_printf(file
, " nr_itable_entries,\n");
2869 lf_printf(file
, "} itable_index;\n");
2870 lf_printf(file
, "\n");
2872 /* output the table that contains the actual instruction info */
2873 lf_printf(file
, "typedef struct _itable_instruction_info {\n");
2874 lf_printf(file
, " itable_index nr;\n");
2875 lf_printf(file
, " char *format;\n");
2876 lf_printf(file
, " char *form;\n");
2877 lf_printf(file
, " char *flags;\n");
2878 lf_printf(file
, " char *nmemonic;\n");
2879 lf_printf(file
, " char *name;\n");
2880 lf_printf(file
, "} itable_info;\n");
2881 lf_printf(file
, "\n");
2882 lf_printf(file
, "extern itable_info itable[nr_itable_entries];\n");
2884 lf_printf(file
, "\n");
2885 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2889 /****************************************************************/
2892 itable_c_insn(insn_table
*entry
,
2896 lf
*file
= (lf
*)data
;
2897 char **fields
= instruction
->file_entry
->fields
;
2898 lf_printf(file
, " { ");
2899 lf_print_function_name(file
,
2900 instruction
->file_entry
->fields
[insn_name
],
2902 function_name_prefix_itable
);
2903 lf_printf(file
, ",\n");
2904 lf_printf(file
, " \"%s\",\n", fields
[insn_format
]);
2905 lf_printf(file
, " \"%s\",\n", fields
[insn_form
]);
2906 lf_printf(file
, " \"%s\",\n", fields
[insn_flags
]);
2907 lf_printf(file
, " \"%s\",\n", fields
[insn_nmemonic
]);
2908 lf_printf(file
, " \"%s\",\n", fields
[insn_name
]);
2909 lf_printf(file
, " },\n");
2914 gen_itable_c(insn_table
*table
, lf
*file
)
2917 lf_print_copyleft(file
);
2918 lf_printf(file
, "\n");
2919 lf_printf(file
, "#ifndef _ITABLE_C_\n");
2920 lf_printf(file
, "#define _ITABLE_C_\n");
2921 lf_printf(file
, "\n");
2922 lf_printf(file
, "#ifndef STATIC_INLINE_ITABLE\n");
2923 lf_printf(file
, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2924 lf_printf(file
, "#endif\n");
2925 lf_printf(file
, "\n");
2926 lf_printf(file
, "#include \"itable.h\"\n");
2927 lf_printf(file
, "\n");
2929 /* output the table that contains the actual instruction info */
2930 lf_printf(file
, "itable_info itable[nr_itable_entries] = {\n");
2931 insn_table_traverse_insn(table
,
2934 lf_printf(file
, "};\n");
2935 lf_printf(file
, "\n");
2937 lf_printf(file
, "\n");
2938 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2941 /****************************************************************/
2944 gen_model_h(insn_table
*table
, lf
*file
)
2947 model_func_unit
*func_unit_ptr
;
2951 lf_print_copyleft(file
);
2952 lf_printf(file
, "\n");
2953 lf_printf(file
, "#ifndef _MODEL_H_\n");
2954 lf_printf(file
, "#define _MODEL_H_\n");
2955 lf_printf(file
, "\n");
2956 lf_printf(file
, "#ifndef INLINE_MODEL\n");
2957 lf_printf(file
, "#define INLINE_MODEL\n");
2958 lf_printf(file
, "#endif\n");
2959 lf_printf(file
, "#ifndef STATIC_INLINE_MODEL\n");
2960 lf_printf(file
, "#define STATIC_INLINE_MODEL STATIC_INLINE\n");
2961 lf_printf(file
, "#endif\n");
2962 lf_printf(file
, "\n");
2963 lf_printf(file
, "\n");
2965 if (table
->max_func_unit_mask
> 0xffff) {
2967 lf_printf(file
, "#ifndef MODEL_UNITS\n");
2968 lf_printf(file
, "#define MODEL_UNITS unsigned32\n");
2969 lf_printf(file
, "#endif\n");
2970 lf_printf(file
, "\n");
2972 lf_printf(file
, "#ifndef MODEL_CYCLES\n");
2973 lf_printf(file
, "#define MODEL_CYCLES unsigned16\n");
2974 lf_printf(file
, "#endif\n");
2975 lf_printf(file
, "\n");
2978 lf_printf(file
, "#ifndef MODEL_UNITS\n");
2979 lf_printf(file
, "#define MODEL_UNITS unsigned16\n");
2980 lf_printf(file
, "#endif\n");
2981 lf_printf(file
, "\n");
2983 lf_printf(file
, "#ifndef MODEL_CYCLES\n");
2984 lf_printf(file
, "#define MODEL_CYCLES unsigned8\n");
2985 lf_printf(file
, "#endif\n");
2986 lf_printf(file
, "\n");
2989 lf_printf(file
, "#ifndef MODEL_FLAGS\n");
2990 lf_printf(file
, "#define MODEL_FLAGS unsigned32\n");
2991 lf_printf(file
, "#endif\n");
2992 lf_printf(file
, "\n");
2994 lf_printf(file
, "typedef struct _model_time {\t/* Instruction cycle time */\n");
2995 lf_printf(file
, " MODEL_UNITS units;\n");
2996 lf_printf(file
, " MODEL_CYCLES initial;\n");
2997 lf_printf(file
, " MODEL_CYCLES finish;\n");
2998 lf_printf(file
, " MODEL_FLAGS flags;\n");
2999 lf_printf(file
, "} model_time;\n");
3000 lf_printf(file
, "\n");
3002 lf_printf(file
, "typedef enum _model_enum {\n");
3003 lf_printf(file
, " MODEL_NONE,\n");
3004 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3005 lf_printf(file
, " MODEL_%s,\n", model_ptr
->name
);
3007 lf_printf(file
, " nr_models\n");
3008 lf_printf(file
, "} model_enum;\n");
3009 lf_printf(file
, "\n");
3011 lf_printf(file
, "#define DEFAULT_MODEL MODEL_%s\n", (models
) ? models
->name
: "NONE");
3012 lf_printf(file
, "\n");
3014 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3015 for (func_unit_ptr
= model_ptr
->func_unit_start
; func_unit_ptr
; func_unit_ptr
= func_unit_ptr
->next
) {
3016 if (func_unit_ptr
->comment
) {
3017 lf_printf(file
, "#define %-*s 0x%.*x /* %s functional unit */\n",
3018 table
->max_func_unit_name_len
, func_unit_ptr
->name
,
3019 hex_size
, func_unit_ptr
->mask
,
3020 func_unit_ptr
->comment
);
3022 lf_printf(file
, "#define %-*s 0x%.*x\n",
3023 table
->max_func_unit_name_len
, func_unit_ptr
->name
,
3024 hex_size
, func_unit_ptr
->mask
);
3027 lf_printf(file
, "\n");
3031 for(macro
= model_macros
; macro
; macro
= macro
->next
)
3032 lf_printf(file
, "%s\n", macro
->file_entry
->fields
[insn_comment
]);
3033 lf_printf(file
, "\n");
3036 lf_printf(file
, "extern model_enum current_model;\n");
3037 lf_printf(file
, "extern const char *model_name[ (int)nr_models ];\n");
3038 lf_printf(file
, "extern const char *const *const model_func_unit_name[ (int)nr_models ];\n");
3039 lf_printf(file
, "extern const model_time *const model_time_mapping[ (int)nr_models ];\n");
3040 lf_printf(file
, "\n");
3041 lf_printf(file
, "INLINE_MODEL void model_set\n");
3042 lf_printf(file
, "(const char *name);\n");
3043 lf_printf(file
, "\n");
3044 lf_printf(file
, "#endif /* _MODEL_H_ */\n");
3047 /****************************************************************/
3049 typedef struct _model_c_data model_c_data
;
3050 struct _model_c_data
{
3056 model_c_insn(insn_table
*entry
,
3060 model_c_data
*data_ptr
= (model_c_data
*)data
;
3061 lf
*file
= data_ptr
->file
;
3062 char *current_name
= data_ptr
->model_ptr
->name
;
3063 table_model_entry
*model_ptr
= instruction
->file_entry
->model_first
;
3067 if (model_ptr
->fields
[insn_model_name
] == current_name
) {
3068 lf_printf(file
, " {");
3069 for(i
= insn_model_unit
; i
< nr_insn_model_table_fields
; i
++) {
3070 lf_printf(file
, " %s,", model_ptr
->fields
[i
]);
3072 lf_printf(file
, " },\n");
3076 model_ptr
= model_ptr
->next
;
3079 lf_printf(file
, " { %s_SENTINEL },\n", current_name
);
3083 gen_model_c(insn_table
*table
, lf
*file
)
3086 model_func_unit
*func_unit_ptr
;
3089 lf_print_copyleft(file
);
3090 lf_printf(file
, "\n");
3091 lf_printf(file
, "#ifndef _MODEL_C_\n");
3092 lf_printf(file
, "#define _MODEL_C_\n");
3093 lf_printf(file
, "\n");
3094 lf_printf(file
, "#include \"cpu.h\"\n");
3095 lf_printf(file
, "\n");
3097 lf_printf(file
, "/* map model enumeration into printable string */\n");
3098 lf_printf(file
, "const char *model_name[ (int)nr_models ] = {\n");
3099 lf_printf(file
, " \"NONE\",\n");
3100 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3101 lf_printf(file
, " \"%s\",\n", model_ptr
->printable_name
);
3103 lf_printf(file
, "};\n");
3104 lf_printf(file
, "\n");
3106 lf_printf(file
, "/* Emit each model's individual function unit names */\n");
3107 lf_printf(file
, "static const char *const model_func_unit_name_NONE[] = {\n");
3108 lf_printf(file
, " \"none\",\n");
3109 lf_printf(file
, " (const char *)0\n");
3110 lf_printf(file
, "};\n");
3111 lf_printf(file
, "\n");
3113 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3114 lf_printf(file
, "static const char *const model_func_unit_name_%s[] = {\n", model_ptr
->name
);
3115 lf_printf(file
, " \"none\",\n");
3116 for (func_unit_ptr
= model_ptr
->func_unit_start
; func_unit_ptr
; func_unit_ptr
= func_unit_ptr
->next
) {
3118 if (func_unit_ptr
->comment
)
3119 lf_printf(file
, " \"%s %s functional unit\",\n", func_unit_ptr
->name
, func_unit_ptr
->comment
);
3121 lf_printf(file
, " \"%s\",\n", func_unit_ptr
->name
);
3123 for(i
= 2; i
< func_unit_ptr
->number
; i
++) {
3124 if (func_unit_ptr
->comment
)
3125 lf_printf(file
, " \"%s %s functional unit #%d\",\n", func_unit_ptr
->name
,
3126 func_unit_ptr
->comment
, i
);
3128 lf_printf(file
, " \"%s #%d\",\n", func_unit_ptr
->name
, i
);
3132 lf_printf(file
, " (const char *)0\n");
3133 lf_printf(file
, "};\n");
3134 lf_printf(file
, "\n");
3137 lf_printf(file
, "/* Array to map model,function unit number to printable string. */\n");
3138 lf_printf(file
, "const char *const *const model_func_unit_name[] = {\n");
3139 lf_printf(file
, " model_func_unit_name_NONE,\n");
3140 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3141 lf_printf(file
, " model_func_unit_name_%s,\n", model_ptr
->name
);
3143 lf_printf(file
, "};\n");
3144 lf_printf(file
, "\n");
3146 lf_printf(file
, "/* Insn functional unit info */\n");
3147 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3150 lf_printf(file
, "static const model_time model_time_%s[] = {\n", model_ptr
->name
);
3152 data
.model_ptr
= model_ptr
;
3153 insn_table_traverse_insn(table
,
3157 lf_printf(file
, "};\n");
3158 lf_printf(file
, "\n");
3161 lf_printf(file
, "const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3162 lf_printf(file
, " (const model_time *const)0,\n");
3163 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3164 lf_printf(file
, " model_time_%s,\n", model_ptr
->name
);
3166 lf_printf(file
, "};\n");
3167 lf_printf(file
, "\n");
3169 lf_printf(file
, "INLINE_MODEL void\n");
3170 lf_printf(file
, "model_set(const char *name)\n");
3171 lf_printf(file
, "{\n");
3173 lf_printf(file
, " model_enum model;\n");
3174 lf_printf(file
, " for(model = MODEL_%s; model < nr_models; model++) {\n", models
->name
);
3175 lf_printf(file
, " if(strcasecmp(name, model_name[model]) == 0) {\n");
3176 lf_printf(file
, " current_model = model;\n");
3177 lf_printf(file
, " return;\n");
3178 lf_printf(file
, " }\n");
3179 lf_printf(file
, " }\n");
3180 lf_printf(file
, "\n");
3181 lf_printf(file
, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3182 lf_printf(file
, " name,\n");
3183 lf_printf(file
, " \"");
3184 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3185 lf_printf(file
, "\\n\\t%s", model_ptr
->printable_name
);
3187 lf_printf(file
, "\");\n");
3189 lf_printf(file
, " error(\"No models are currently known about\");\n");
3192 lf_printf(file
, "}\n");
3193 lf_printf(file
, "\n");
3195 lf_printf(file
, "#endif /* _MODEL_C_ */\n");
3199 /****************************************************************/
3207 insn_table
*instructions
= NULL
;
3208 icache_tree
*cache_fields
= NULL
;
3209 char *real_file_name
= NULL
;
3214 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
3215 printf("Config options:\n");
3216 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
3217 printf(" -e Expand (duplicate) semantic functions\n");
3218 printf(" -r <icache-size> Generate cracking cache version\n");
3219 printf(" -l Supress line numbering in output files\n");
3220 printf(" -b <bit-size> Set the number of bits in an instruction\n");
3221 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
3222 printf("Input options (ucase version also dumps loaded table):\n");
3223 printf(" -[Oo] <opcode-rules>\n");
3224 printf(" -[Kk] <cache-rules>\n");
3225 printf(" -[Ii] <instruction-table>\n");
3226 printf("Output options:\n");
3227 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
3228 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
3229 printf(" -[Mm] <output-file> output model.h(M) model.c(M)\n");
3230 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
3231 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
3234 while ((ch
= getopt(argc
, argv
,
3235 "leb:h:r:f:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
3236 fprintf(stderr
, "\t-%c %s\n", ch
, (optarg
? optarg
: ""));
3242 idecode_expand_semantics
= 1;
3245 idecode_cache
= a2i(optarg
);
3248 insn_size
= a2i(optarg
);
3249 ASSERT(insn_size
> 0 && insn_size
<= max_insn_size
3250 && (hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0));
3253 hi_bit_nr
= a2i(optarg
);
3254 ASSERT(hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0);
3258 filter
*new_filter
= ZALLOC(filter
);
3259 new_filter
->flag
= strdup(optarg
);
3260 new_filter
->next
= filters
;
3261 filters
= new_filter
;
3266 ASSERT(opcode_table
!= NULL
);
3267 ASSERT(cache_table
!= NULL
);
3268 instructions
= insn_table_load_insns(optarg
);
3269 fprintf(stderr
, "\texpanding ...\n");
3270 insn_table_expand_insns(instructions
);
3271 fprintf(stderr
, "\tcache fields ...\n");
3272 cache_fields
= insn_table_cache_fields(instructions
);
3274 dump_traverse(instructions
);
3275 dump_insn_table(instructions
, 0, 1);
3280 opcode_table
= load_opcode_rules(optarg
);
3282 dump_opcode_rules(opcode_table
, 0);
3286 cache_table
= load_cache_rules(optarg
);
3288 dump_cache_rules(cache_table
, 0);
3291 real_file_name
= strdup(optarg
);
3303 lf
*file
= lf_open(optarg
, real_file_name
, number_lines
);
3304 ASSERT(instructions
!= NULL
);
3307 gen_semantics_h(instructions
, file
);
3310 gen_semantics_c(instructions
, file
);
3313 gen_idecode_h(instructions
, file
);
3316 gen_idecode_c(instructions
, file
);
3319 gen_model_h(instructions
, file
);
3322 gen_model_c(instructions
, file
);
3325 gen_itable_h(instructions
, file
);
3328 gen_itable_c(instructions
, file
);
3331 gen_icache_h(cache_fields
, file
);
3336 real_file_name
= NULL
;
3339 error("unknown option\n");