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
;
517 dump_opcode_field(opcode_field
*field
, int indent
, int levels
)
519 printf("(opcode_field*)%p\n", field
);
520 if (levels
&& field
!= NULL
) {
521 dumpf(indent
, "(first %d)\n", field
->first
);
522 dumpf(indent
, "(last %d)\n", field
->last
);
523 dumpf(indent
, "(is_boolean %d)\n", field
->is_boolean
);
524 dumpf(indent
, "(parent ");
525 dump_opcode_field(field
->parent
, indent
, levels
-1);
530 /****************************************************************/
532 typedef struct _insn_bits insn_bits
;
537 opcode_field
*opcode
;
543 dump_insn_bits(insn_bits
*bits
, int indent
, int levels
)
545 printf("(insn_bits*)%p\n", bits
);
547 if (levels
&& bits
!= NULL
) {
548 dumpf(indent
, "(value %d)\n", bits
->value
);
549 dumpf(indent
, "(opcode ");
550 dump_opcode_field(bits
->opcode
, indent
+1, 0);
551 dumpf(indent
, " )\n");
552 dumpf(indent
, "(field ");
553 dump_insn_field(bits
->field
, indent
+1);
554 dumpf(indent
, " )\n");
555 dumpf(indent
, "(last ");
556 dump_insn_bits(bits
->last
, indent
+1, levels
-1);
561 /****************************************************************/
575 function_type
= insn_format
,
576 function_name
= insn_name
,
577 function_param
= insn_comment
578 } function_table_fields
;
581 model_name
= insn_mnemonic
,
582 model_identifer
= insn_name
,
583 model_default
= insn_comment
,
584 } model_table_fields
;
586 typedef struct _insn insn
;
588 table_entry
*file_entry
;
593 typedef struct _model model
;
597 char *printable_name
;
599 table_model_entry
*func_unit_start
;
600 table_model_entry
*func_unit_end
;
603 typedef struct _insn_table insn_table
;
606 insn_bits
*expanded_bits
;
611 opcode_rules
*opcode_rule
;
612 opcode_field
*opcode
;
622 nr_insn_model_table_fields
623 } insn_model_table_fields
;
625 static model
*models
;
626 static model
*last_model
;
628 static insn
*model_macros
;
629 static insn
*last_model_macro
;
631 static insn
*model_functions
;
632 static insn
*last_model_function
;
634 static insn
*model_internal
;
635 static insn
*last_model_internal
;
637 static insn
*model_data
;
638 static insn
*last_model_data
;
640 static int max_model_fields_len
;
643 insn_table_insert_function(insn_table
*table
,
644 table_entry
*file_entry
)
646 /* create a new function */
647 insn
*new_function
= ZALLOC(insn
);
648 new_function
->file_entry
= file_entry
;
650 /* append it to the end of the function list */
651 if (table
->last_function
)
652 table
->last_function
->next
= new_function
;
654 table
->functions
= new_function
;
655 table
->last_function
= new_function
;
659 insn_table_insert_insn(insn_table
*table
,
660 table_entry
*file_entry
,
663 insn
**ptr_to_cur_insn
= &table
->insns
;
664 insn
*cur_insn
= *ptr_to_cur_insn
;
665 table_model_entry
*insn_model_ptr
;
668 /* create a new instruction */
669 insn
*new_insn
= ZALLOC(insn
);
670 new_insn
->file_entry
= file_entry
;
671 new_insn
->fields
= fields
;
673 /* Check out any model information returned to make sure the model
675 for(insn_model_ptr
= file_entry
->model_first
; insn_model_ptr
; insn_model_ptr
= insn_model_ptr
->next
) {
676 char *name
= insn_model_ptr
->fields
[insn_model_name
];
677 int len
= strlen (insn_model_ptr
->fields
[insn_model_fields
]);
679 while (len
> 0 && isspace(*insn_model_ptr
->fields
[insn_model_fields
])) {
681 insn_model_ptr
->fields
[insn_model_fields
]++;
684 if (max_model_fields_len
< len
)
685 max_model_fields_len
= len
;
687 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
688 if (strcmp(name
, model_ptr
->printable_name
) == 0) {
690 /* Replace the name field with that of the global model, so that when we
691 want to print it out, we can just compare pointers. */
692 insn_model_ptr
->fields
[insn_model_name
] = model_ptr
->printable_name
;
698 error("%s:%d: machine model `%s' was not known about\n",
699 file_entry
->file_name
, file_entry
->line_nr
, name
);
702 /* insert it according to the order of the fields */
703 while (cur_insn
!= NULL
704 && new_insn
->fields
->value
>= cur_insn
->fields
->value
) {
705 ptr_to_cur_insn
= &cur_insn
->next
;
706 cur_insn
= *ptr_to_cur_insn
;
709 new_insn
->next
= cur_insn
;
710 *ptr_to_cur_insn
= new_insn
;
716 static opcode_field
*
717 insn_table_find_opcode_field(insn
*insns
,
721 opcode_field
*curr_opcode
= ZALLOC(opcode_field
);
725 curr_opcode
->first
= insn_size
;
726 curr_opcode
->last
= -1;
727 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
) {
728 insn_fields
*fields
= entry
->fields
;
729 opcode_field new_opcode
;
731 /* find a start point for the opcode field */
732 new_opcode
.first
= rule
->first
;
733 while (new_opcode
.first
<= rule
->last
735 || insn_field_is_constant(fields
->bits
[new_opcode
.first
],
736 rule
) != field_constant_string
)
738 || !insn_field_is_constant(fields
->bits
[new_opcode
.first
],
740 new_opcode
.first
= fields
->bits
[new_opcode
.first
]->last
+ 1;
741 ASSERT(new_opcode
.first
> rule
->last
743 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
744 rule
) == field_constant_string
)
746 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
749 /* find the end point for the opcode field */
750 new_opcode
.last
= rule
->last
;
751 while (new_opcode
.last
>= rule
->first
753 || insn_field_is_constant(fields
->bits
[new_opcode
.last
],
754 rule
) != field_constant_string
)
756 || !insn_field_is_constant(fields
->bits
[new_opcode
.last
],
758 new_opcode
.last
= fields
->bits
[new_opcode
.last
]->first
- 1;
759 ASSERT(new_opcode
.last
< rule
->first
761 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
762 rule
) == field_constant_string
)
764 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
767 /* now see if our current opcode needs expanding */
768 if (new_opcode
.first
<= rule
->last
769 && curr_opcode
->first
> new_opcode
.first
)
770 curr_opcode
->first
= new_opcode
.first
;
771 if (new_opcode
.last
>= rule
->first
772 && curr_opcode
->last
< new_opcode
.last
)
773 curr_opcode
->last
= new_opcode
.last
;
777 /* was any thing interesting found? */
778 if (curr_opcode
->first
> rule
->last
) {
779 ASSERT(curr_opcode
->last
< rule
->first
);
782 ASSERT(curr_opcode
->last
>= rule
->first
);
783 ASSERT(curr_opcode
->first
<= rule
->last
);
785 /* if something was found, check it includes the forced field range */
787 && curr_opcode
->first
> rule
->force_first
) {
788 curr_opcode
->first
= rule
->force_first
;
791 && curr_opcode
->last
< rule
->force_last
) {
792 curr_opcode
->last
= rule
->force_last
;
794 /* handle special case elminating any need to do shift after mask */
796 && rule
->force_last
== insn_size
-1) {
797 curr_opcode
->last
= insn_size
-1;
800 /* handle any special cases */
801 switch (rule
->special_rule
) {
802 case 0: /* let the above apply */
804 case 1: /* expand a limited nr of bits, ignoring the rest */
805 curr_opcode
->first
= rule
->force_first
;
806 curr_opcode
->last
= rule
->force_last
;
808 case 2: /* boolean field */
809 curr_opcode
->is_boolean
= 1;
818 insn_table_insert_expanded(insn_table
*table
,
823 insn_table
**ptr_to_cur_entry
= &table
->entries
;
824 insn_table
*cur_entry
= *ptr_to_cur_entry
;
826 /* find the new table for this entry */
827 while (cur_entry
!= NULL
828 && cur_entry
->opcode_nr
< new_opcode_nr
) {
829 ptr_to_cur_entry
= &cur_entry
->sibling
;
830 cur_entry
= *ptr_to_cur_entry
;
833 if (cur_entry
== NULL
|| cur_entry
->opcode_nr
!= new_opcode_nr
) {
834 insn_table
*new_entry
= ZALLOC(insn_table
);
835 new_entry
->opcode_nr
= new_opcode_nr
;
836 new_entry
->expanded_bits
= new_bits
;
837 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
838 new_entry
->sibling
= cur_entry
;
839 new_entry
->parent
= table
;
840 *ptr_to_cur_entry
= new_entry
;
841 cur_entry
= new_entry
;
844 /* ASSERT new_bits == cur_entry bits */
845 ASSERT(cur_entry
!= NULL
&& cur_entry
->opcode_nr
== new_opcode_nr
);
846 insn_table_insert_insn(cur_entry
,
847 old_insn
->file_entry
,
852 insn_table_expand_opcode(insn_table
*table
,
859 if (field_nr
> table
->opcode
->last
) {
860 insn_table_insert_expanded(table
, instruction
, opcode_nr
, bits
);
863 insn_field
*field
= instruction
->fields
->bits
[field_nr
];
864 if (field
->is_int
|| field
->is_slash
) {
865 ASSERT(field
->first
>= table
->opcode
->first
866 && field
->last
<= table
->opcode
->last
);
867 insn_table_expand_opcode(table
, instruction
, field
->last
+1,
868 ((opcode_nr
<< field
->width
) + field
->val_int
),
873 int last_pos
= ((field
->last
< table
->opcode
->last
)
874 ? field
->last
: table
->opcode
->last
);
875 int first_pos
= ((field
->first
> table
->opcode
->first
)
876 ? field
->first
: table
->opcode
->first
);
877 int width
= last_pos
- first_pos
+ 1;
878 int last_val
= (table
->opcode
->is_boolean
880 for (val
= 0; val
< last_val
; val
++) {
881 insn_bits
*new_bits
= ZALLOC(insn_bits
);
882 new_bits
->field
= field
;
883 new_bits
->value
= val
;
884 new_bits
->last
= bits
;
885 new_bits
->opcode
= table
->opcode
;
886 insn_table_expand_opcode(table
, instruction
, last_pos
+1,
887 ((opcode_nr
<< width
) | val
),
895 insn_table_insert_expanding(insn_table
*table
,
898 insn_table_expand_opcode(table
,
900 table
->opcode
->first
,
902 table
->expanded_bits
);
907 insn_table_expand_insns(insn_table
*table
)
910 ASSERT(table
->nr_insn
>= 1);
912 /* determine a valid opcode */
913 while (table
->opcode_rule
) {
914 /* specials only for single instructions */
915 if ((table
->nr_insn
> 1
916 && table
->opcode_rule
->special_mask
== 0
917 && table
->opcode_rule
->special_rule
== 0)
918 || (table
->nr_insn
== 1
919 && table
->opcode_rule
->special_mask
!= 0
920 && ((table
->insns
->fields
->value
921 & table
->opcode_rule
->special_mask
)
922 == table
->opcode_rule
->special_value
))
923 || (idecode_expand_semantics
924 && table
->opcode_rule
->special_mask
== 0
925 && table
->opcode_rule
->special_rule
== 0))
927 insn_table_find_opcode_field(table
->insns
,
929 table
->nr_insn
== 1/*string*/
931 if (table
->opcode
!= NULL
)
933 table
->opcode_rule
= table
->opcode_rule
->next
;
936 /* did we find anything */
937 if (table
->opcode
== NULL
) {
940 ASSERT(table
->opcode
!= NULL
);
942 /* back link what we found to its parent */
943 if (table
->parent
!= NULL
) {
944 ASSERT(table
->parent
->opcode
!= NULL
);
945 table
->opcode
->parent
= table
->parent
->opcode
;
948 /* expand the raw instructions according to the opcode */
951 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
) {
952 insn_table_insert_expanding(table
, entry
);
956 /* and do the same for the sub entries */
959 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
) {
960 insn_table_expand_insns(entry
);
967 model_table_insert(insn_table
*table
,
968 table_entry
*file_entry
)
972 /* create a new model */
973 model
*new_model
= ZALLOC(model
);
975 new_model
->name
= file_entry
->fields
[model_identifer
];
976 new_model
->printable_name
= file_entry
->fields
[model_name
];
977 new_model
->insn_default
= file_entry
->fields
[model_default
];
979 while (*new_model
->insn_default
&& isspace(*new_model
->insn_default
))
980 new_model
->insn_default
++;
982 len
= strlen(new_model
->insn_default
);
983 if (max_model_fields_len
< len
)
984 max_model_fields_len
= len
;
986 /* append it to the end of the model list */
988 last_model
->next
= new_model
;
991 last_model
= new_model
;
995 model_table_insert_specific(insn_table
*table
,
996 table_entry
*file_entry
,
1000 insn
*ptr
= ZALLOC(insn
);
1001 ptr
->file_entry
= file_entry
;
1003 (*end_ptr
)->next
= ptr
;
1012 insn_table_load_insns(char *file_name
)
1014 table
*file
= table_open(file_name
, nr_insn_table_fields
, nr_insn_model_table_fields
);
1015 insn_table
*table
= ZALLOC(insn_table
);
1016 table_entry
*file_entry
;
1017 table
->opcode_rule
= opcode_table
;
1019 while ((file_entry
= table_entry_read(file
)) != NULL
) {
1020 if (it_is("function", file_entry
->fields
[insn_flags
])
1021 || it_is("internal", file_entry
->fields
[insn_flags
])) {
1022 insn_table_insert_function(table
, file_entry
);
1024 else if (it_is("model", file_entry
->fields
[insn_flags
])) {
1025 model_table_insert(table
, file_entry
);
1027 else if (it_is("model-macro", file_entry
->fields
[insn_flags
])) {
1028 model_table_insert_specific(table
, file_entry
, &model_macros
, &last_model_macro
);
1030 else if (it_is("model-function", file_entry
->fields
[insn_flags
])) {
1031 model_table_insert_specific(table
, file_entry
, &model_functions
, &last_model_function
);
1033 else if (it_is("model-internal", file_entry
->fields
[insn_flags
])) {
1034 model_table_insert_specific(table
, file_entry
, &model_internal
, &last_model_internal
);
1036 else if (it_is("model-data", file_entry
->fields
[insn_flags
])) {
1037 model_table_insert_specific(table
, file_entry
, &model_data
, &last_model_data
);
1040 insn_fields
*fields
;
1041 /* skip instructions that aren't relevant to the mode */
1042 filter
*filt
= filters
;
1043 while (filt
!= NULL
) {
1044 if (it_is(filt
->flag
, file_entry
->fields
[insn_flags
]))
1049 /* create/insert the new instruction */
1050 fields
= parse_insn_format(file_entry
,
1051 file_entry
->fields
[insn_format
]);
1052 insn_table_insert_insn(table
, file_entry
, fields
);
1061 dump_insn(insn
*entry
, int indent
, int levels
)
1063 printf("(insn*)%p\n", entry
);
1065 if (levels
&& entry
!= NULL
) {
1067 dumpf(indent
, "(file_entry ");
1068 dump_table_entry(entry
->file_entry
, indent
+1);
1069 dumpf(indent
, " )\n");
1071 dumpf(indent
, "(fields ");
1072 dump_insn_fields(entry
->fields
, indent
+1);
1073 dumpf(indent
, " )\n");
1075 dumpf(indent
, "(next ");
1076 dump_insn(entry
->next
, indent
+1, levels
-1);
1077 dumpf(indent
, " )\n");
1085 dump_insn_table(insn_table
*table
,
1086 int indent
, int levels
)
1089 printf("(insn_table*)%p\n", table
);
1091 if (levels
&& table
!= NULL
) {
1093 dumpf(indent
, "(opcode_nr %d)\n", table
->opcode_nr
);
1095 dumpf(indent
, "(expanded_bits ");
1096 dump_insn_bits(table
->expanded_bits
, indent
+1, -1);
1097 dumpf(indent
, " )\n");
1099 dumpf(indent
, "(int nr_insn %d)\n", table
->nr_insn
);
1101 dumpf(indent
, "(insns ");
1102 dump_insn(table
->insns
, indent
+1, table
->nr_insn
);
1103 dumpf(indent
, " )\n");
1105 dumpf(indent
, "(opcode_rule ");
1106 dump_opcode_rule(table
->opcode_rule
, indent
+1);
1107 dumpf(indent
, " )\n");
1109 dumpf(indent
, "(opcode ");
1110 dump_opcode_field(table
->opcode
, indent
+1, 1);
1111 dumpf(indent
, " )\n");
1113 dumpf(indent
, "(nr_entries %d)\n", table
->entries
);
1114 dumpf(indent
, "(entries ");
1115 dump_insn_table(table
->entries
, indent
+1, table
->nr_entries
);
1116 dumpf(indent
, " )\n");
1118 dumpf(indent
, "(sibling ", table
->sibling
);
1119 dump_insn_table(table
->sibling
, indent
+1, levels
-1);
1120 dumpf(indent
, " )\n");
1122 dumpf(indent
, "(parent ", table
->parent
);
1123 dump_insn_table(table
->parent
, indent
+1, 0);
1124 dumpf(indent
, " )\n");
1130 /****************************************************************/
1134 lf_print_insn_bits(lf
*file
, insn_bits
*bits
)
1138 lf_print_insn_bits(file
, bits
->last
);
1139 lf_putchr(file
, '_');
1140 lf_putstr(file
, bits
->field
->val_string
);
1141 if (!bits
->opcode
->is_boolean
|| bits
->value
== 0) {
1142 if (bits
->opcode
->last
< bits
->field
->last
)
1143 lf_putint(file
, bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1145 lf_putint(file
, bits
->value
);
1150 lf_print_opcodes(lf
*file
,
1153 if (table
!= NULL
) {
1155 lf_printf(file
, "_%d_%d",
1156 table
->opcode
->first
,
1157 table
->opcode
->last
);
1158 if (table
->parent
== NULL
) break;
1159 lf_printf(file
, "__%d", table
->opcode_nr
);
1160 table
= table
->parent
;
1166 lf_print_table_name(lf
*file
,
1169 lf_printf(file
, "idecode_table");
1170 lf_print_opcodes(file
, table
);
1176 function_name_prefix_semantics
,
1177 function_name_prefix_idecode
,
1178 function_name_prefix_itable
,
1179 function_name_prefix_none
1180 } lf_function_name_prefixes
;
1183 lf_print_function_name(lf
*file
,
1185 insn_bits
*expanded_bits
,
1186 lf_function_name_prefixes prefix
)
1191 case function_name_prefix_semantics
:
1192 lf_putstr(file
, "semantic_");
1194 case function_name_prefix_idecode
:
1195 lf_printf(file
, "idecode_");
1197 case function_name_prefix_itable
:
1198 lf_putstr(file
, "itable_");
1204 /* the function name */
1207 for (pos
= basename
;
1215 lf_putchr(file
, '_');
1218 lf_putchr(file
, *pos
);
1225 if (idecode_expand_semantics
)
1226 lf_print_insn_bits(file
, expanded_bits
);
1231 lf_print_idecode_table(lf
*file
,
1234 int can_assume_leaf
;
1235 opcode_rules
*opcode_rule
;
1237 /* have a look at the rule table, if all table rules follow all
1238 switch rules, I can assume that all end points are leaves */
1239 opcode_rule
= opcode_table
;
1240 while (opcode_rule
!= NULL
1241 && opcode_rule
->use_switch
)
1242 opcode_rule
= opcode_rule
->next
;
1243 while (opcode_rule
!= NULL
1244 && opcode_rule
->use_switch
1245 && opcode_rule
->special_rule
)
1246 opcode_rule
= opcode_rule
->next
;
1247 can_assume_leaf
= opcode_rule
== NULL
;
1249 lf_printf(file
, "{\n");
1250 lf_indent(file
, +2);
1252 lf_printf(file
, "idecode_table_entry *table = ");
1253 lf_print_table_name(file
, entry
);
1254 lf_printf(file
, ";\n");
1255 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1256 i2target(hi_bit_nr
, entry
->opcode
->first
),
1257 i2target(hi_bit_nr
, entry
->opcode
->last
));
1258 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
1259 lf_printf(file
, "while (1) {\n");
1260 lf_indent(file
, +2);
1262 lf_printf(file
, "/* nonzero mask -> another table */\n");
1263 lf_printf(file
, "while (table_entry->mask != 0) {\n");
1264 lf_indent(file
, +2);
1266 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1267 lf_printf(file
, " table_entry->function_or_table);\n");
1268 lf_printf(file
, "opcode = ((instruction & table_entry->mask)\n");
1269 lf_printf(file
, " >> table_entry->shift);\n");
1270 lf_printf(file
, "table_entry = table + opcode;\n");
1272 lf_indent(file
, -2);
1273 lf_printf(file
, "}\n");
1274 lf_printf(file
, "ASSERT(table_entry->mask == 0);\n");
1275 if (can_assume_leaf
)
1276 lf_printf(file
, "ASSERT(table_entry->shift == 0);\n");
1278 lf_printf(file
, "if (table_entry->shift == 0)\n");
1279 lf_indent(file
, +2);
1281 if (idecode_cache
) {
1282 lf_printf(file
, "return (((idecode_crack*)\n");
1283 lf_printf(file
, " table_entry->function_or_table)\n");
1284 lf_printf(file
, " (%s));\n", cache_idecode_actual
);
1287 lf_printf(file
, "return (((idecode_semantic*)\n");
1288 lf_printf(file
, " table_entry->function_or_table)\n");
1289 lf_printf(file
, " (%s));\n", semantic_actual
);
1291 if (!can_assume_leaf
) {
1292 lf_indent(file
, -2);
1293 lf_printf(file
, "/* must be a boolean */\n");
1294 lf_printf(file
, "opcode = (instruction & table_entry->shift) != 0;\n");
1295 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1296 lf_printf(file
, " table_entry->function_or_table);\n");
1297 lf_printf(file
, "table_entry = table + opcode;\n");
1300 lf_indent(file
, -2);
1301 lf_printf(file
, "}\n");
1303 lf_indent(file
, -2);
1304 lf_printf(file
, "}\n");
1309 lf_print_my_prefix(lf
*file
,
1310 table_entry
*file_entry
,
1313 lf_printf(file
, "const char *const my_prefix = \n");
1314 lf_printf(file
, " \"%s:%s:%s:%d\";\n",
1315 filter_filename (file_entry
->file_name
),
1316 (idecode
? "idecode" : "semantics"),
1317 file_entry
->fields
[insn_name
],
1318 file_entry
->line_nr
);
1323 lf_print_ptrace(lf
*file
,
1326 lf_printf(file
, "\n");
1327 lf_printf(file
, "ITRACE(trace_%s, (\"\\n\"));\n",
1328 (idecode
? "idecode" : "semantics"));
1332 /****************************************************************/
1334 typedef void leaf_handler
1338 typedef void padding_handler
1346 insn_table_traverse_tree(insn_table
*table
,
1349 leaf_handler
*start
,
1352 padding_handler
*padding
)
1357 ASSERT(table
!= NULL
1358 && table
->opcode
!= NULL
1359 && table
->nr_entries
> 0
1360 && table
->entries
!= 0);
1362 if (start
!= NULL
&& depth
>= 0)
1363 start(table
, data
, depth
);
1365 for (entry_nr
= 0, entry
= table
->entries
;
1366 entry_nr
< (table
->opcode
->is_boolean
1368 : (1 << (table
->opcode
->last
- table
->opcode
->first
+ 1)));
1371 || (!table
->opcode
->is_boolean
1372 && entry_nr
< entry
->opcode_nr
)) {
1373 if (padding
!= NULL
&& depth
>= 0)
1374 padding(table
, data
, depth
, entry_nr
);
1377 ASSERT(entry
!= NULL
&& (entry
->opcode_nr
== entry_nr
1378 || table
->opcode
->is_boolean
));
1379 if (entry
->opcode
!= NULL
&& depth
!= 0) {
1380 insn_table_traverse_tree(entry
, data
, depth
+1,
1381 start
, leaf
, end
, padding
);
1383 else if (depth
>= 0) {
1385 leaf(entry
, data
, depth
);
1387 entry
= entry
->sibling
;
1390 if (end
!= NULL
&& depth
>= 0)
1391 end(table
, data
, depth
);
1395 typedef void function_handler
1398 table_entry
*function
);
1401 insn_table_traverse_function(insn_table
*table
,
1403 function_handler
*leaf
)
1406 for (function
= table
->functions
;
1408 function
= function
->next
) {
1409 leaf(table
, data
, function
->file_entry
);
1414 typedef void insn_handler
1420 insn_table_traverse_insn(insn_table
*table
,
1425 for (instruction
= table
->insns
;
1426 instruction
!= NULL
;
1427 instruction
= instruction
->next
) {
1428 leaf(table
, data
, instruction
);
1434 update_depth(insn_table
*entry
,
1438 int *max_depth
= (int*)data
;
1439 if (*max_depth
< depth
)
1445 insn_table_depth(insn_table
*table
)
1448 insn_table_traverse_tree(table
,
1459 /****************************************************************/
1462 dump_traverse_start(insn_table
*table
,
1466 dumpf(depth
*2, "(%d\n", table
->opcode_nr
);
1470 dump_traverse_leaf(insn_table
*entry
,
1474 ASSERT(entry
->nr_entries
== 0
1475 && entry
->nr_insn
== 1
1476 && entry
->opcode
== NULL
);
1477 dumpf(depth
*2, ".%d %s\n", entry
->opcode_nr
,
1478 entry
->insns
->file_entry
->fields
[insn_format
]);
1482 dump_traverse_end(insn_table
*table
,
1486 dumpf(depth
*2, ")\n");
1490 dump_traverse_padding(insn_table
*table
,
1495 dumpf(depth
*2, ".<%d>\n", opcode_nr
);
1500 dump_traverse(insn_table
*table
)
1502 insn_table_traverse_tree(table
, NULL
, 1,
1503 dump_traverse_start
,
1506 dump_traverse_padding
);
1510 /****************************************************************/
1514 lf_print_semantic_function_header(lf
*file
,
1516 insn_bits
*expanded_bits
,
1517 int is_function_definition
,
1518 int is_inline_function
)
1520 lf_printf(file
, "\n");
1521 lf_printf(file
, "STATIC_SEMANTICS unsigned_word ");
1522 lf_print_function_name(file
,
1525 function_name_prefix_semantics
);
1526 lf_printf(file
, "\n(%s)",
1527 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
1528 if (!is_function_definition
)
1529 lf_printf(file
, ";");
1530 lf_printf(file
, "\n");
1535 semantics_h_leaf(insn_table
*entry
,
1539 lf
*file
= (lf
*)data
;
1540 ASSERT(entry
->nr_insn
== 1);
1541 lf_print_semantic_function_header(file
,
1542 entry
->insns
->file_entry
->fields
[insn_name
],
1543 entry
->expanded_bits
,
1544 0/* isnt function definition*/,
1545 !idecode_cache
&& entry
->parent
->opcode_rule
->use_switch
);
1549 semantics_h_insn(insn_table
*entry
,
1553 lf
*file
= (lf
*)data
;
1554 lf_print_semantic_function_header(file
,
1555 instruction
->file_entry
->fields
[insn_name
],
1557 0/*isnt function definition*/,
1558 0/*isnt inline function*/);
1562 semantics_h_function(insn_table
*entry
,
1564 table_entry
*function
)
1566 lf
*file
= (lf
*)data
;
1567 if (function
->fields
[function_type
] == NULL
1568 || function
->fields
[function_type
][0] == '\0') {
1569 lf_print_semantic_function_header(file
,
1570 function
->fields
[function_name
],
1572 0/*isnt function definition*/,
1573 1/*is inline function*/);
1576 lf_printf(file
, "\n");
1577 lf_printf(file
, "INLINE_SEMANTICS %s %s\n(%s);\n",
1578 function
->fields
[function_type
],
1579 function
->fields
[function_name
],
1580 function
->fields
[function_param
]);
1586 gen_semantics_h(insn_table
*table
, lf
*file
)
1589 lf_print_copyleft(file
);
1590 lf_printf(file
, "\n");
1591 lf_printf(file
, "#ifndef _SEMANTICS_H_\n");
1592 lf_printf(file
, "#define _SEMANTICS_H_\n");
1593 lf_printf(file
, "\n");
1594 lf_printf(file
, "#ifndef INLINE_SEMANTICS\n");
1595 lf_printf(file
, "#define INLINE_SEMANTICS\n");
1596 lf_printf(file
, "#endif\n");
1597 lf_printf(file
, "\n");
1598 lf_printf(file
, "#ifndef STATIC_SEMANTICS\n");
1599 lf_printf(file
, "#define STATIC_SEMANTICS\n");
1600 lf_printf(file
, "#endif\n");
1601 lf_printf(file
, "\n");
1602 lf_printf(file
, "\n");
1604 /* output a declaration for all functions */
1605 insn_table_traverse_function(table
,
1607 semantics_h_function
);
1609 /* output a declaration for all instructions */
1610 if (idecode_expand_semantics
)
1611 insn_table_traverse_tree(table
,
1615 semantics_h_leaf
, /* leaf */
1617 NULL
); /* padding */
1619 insn_table_traverse_insn(table
,
1623 lf_printf(file
, "\n");
1624 lf_printf(file
, "#endif /* _SEMANTICS_H_ */\n");
1628 /****************************************************************/
1630 typedef struct _icache_tree icache_tree
;
1631 struct _icache_tree
{
1634 icache_tree
*children
;
1637 static icache_tree
*
1638 icache_tree_insert(icache_tree
*tree
,
1641 icache_tree
*new_tree
;
1643 icache_tree
**ptr_to_cur_tree
= &tree
->children
;
1644 icache_tree
*cur_tree
= *ptr_to_cur_tree
;
1645 while (cur_tree
!= NULL
1646 && strcmp(cur_tree
->name
, name
) < 0) {
1647 ptr_to_cur_tree
= &cur_tree
->next
;
1648 cur_tree
= *ptr_to_cur_tree
;
1650 ASSERT(cur_tree
== NULL
1651 || strcmp(cur_tree
->name
, name
) >= 0);
1652 /* already in the tree */
1653 if (cur_tree
!= NULL
1654 && strcmp(cur_tree
->name
, name
) == 0)
1656 /* missing, insert it */
1657 ASSERT(cur_tree
== NULL
1658 || strcmp(cur_tree
->name
, name
) > 0);
1659 new_tree
= ZALLOC(icache_tree
);
1660 new_tree
->name
= name
;
1661 new_tree
->next
= cur_tree
;
1662 *ptr_to_cur_tree
= new_tree
;
1667 static icache_tree
*
1668 insn_table_cache_fields(insn_table
*table
)
1670 icache_tree
*tree
= ZALLOC(icache_tree
);
1672 for (instruction
= table
->insns
;
1673 instruction
!= NULL
;
1674 instruction
= instruction
->next
) {
1677 icache_tree_insert(tree
,
1678 instruction
->file_entry
->fields
[insn_form
]);
1679 for (field
= instruction
->fields
->first
;
1681 field
= field
->next
) {
1682 if (field
->is_string
)
1683 icache_tree_insert(form
, field
->val_string
);
1692 gen_icache_h(icache_tree
*tree
,
1695 lf_print_copyleft(file
);
1696 lf_printf(file
, "\n");
1697 lf_printf(file
, "#ifndef _ICACHE_H_\n");
1698 lf_printf(file
, "#define _ICACHE_H_\n");
1699 lf_printf(file
, "\n");
1700 lf_printf(file
, "#ifndef INLINE_ICACHE\n");
1701 lf_printf(file
, "#define INLINE_ICACHE\n");
1702 lf_printf(file
, "#endif\n");
1703 lf_printf(file
, "\n");
1705 lf_printf(file
, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1707 lf_printf(file
, "\n");
1709 /* create an instruction cache if being used */
1710 if (idecode_cache
) {
1712 lf_printf(file
, "typedef struct _idecode_cache {\n");
1713 lf_printf(file
, " unsigned_word address;\n");
1714 lf_printf(file
, " void *semantic;\n");
1715 lf_printf(file
, " union {\n");
1716 for (form
= tree
->children
;
1718 form
= form
->next
) {
1720 lf_printf(file
, " struct {\n");
1721 for (field
= form
->children
;
1723 field
= field
->next
) {
1724 cache_rules
*cache_rule
;
1726 for (cache_rule
= cache_table
;
1728 cache_rule
= cache_rule
->next
) {
1729 if (strcmp(field
->name
, cache_rule
->old_name
) == 0) {
1731 if (cache_rule
->new_name
!= NULL
)
1732 lf_printf(file
, " %s %s; /* %s */\n",
1733 (cache_rule
->type
== NULL
1735 : cache_rule
->type
),
1736 cache_rule
->new_name
,
1737 cache_rule
->old_name
);
1741 lf_printf(file
, " unsigned %s;\n", field
->name
);
1743 lf_printf(file
, " } %s;\n", form
->name
);
1745 lf_printf(file
, " } crack;\n");
1746 lf_printf(file
, "} idecode_cache;\n");
1749 /* alernativly, since no cache, #define the fields to be
1750 extractions from the instruction variable */
1751 cache_rules
*cache_rule
;
1752 lf_printf(file
, "\n");
1753 for (cache_rule
= cache_table
;
1755 cache_rule
= cache_rule
->next
) {
1756 if (cache_rule
->expression
!= NULL
1757 && strlen(cache_rule
->expression
) > 0)
1758 lf_printf(file
, "#define %s %s\n",
1759 cache_rule
->new_name
, cache_rule
->expression
);
1763 lf_printf(file
, "\n");
1764 lf_printf(file
, "#endif /* _ICACHE_H_ */\n");
1770 /****************************************************************/
1774 lf_print_c_extraction(lf
*file
,
1778 char *field_expression
,
1779 insn_field
*cur_field
,
1781 int get_value_from_cache
,
1782 int put_value_in_cache
)
1784 ASSERT(field_name
!= NULL
);
1786 && (!bits
->opcode
->is_boolean
|| bits
->value
== 0)
1787 && strcmp(field_name
, cur_field
->val_string
) == 0) {
1788 ASSERT(bits
->field
== cur_field
);
1789 ASSERT(field_type
== NULL
);
1790 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1791 lf_printf(file
, "const unsigned %s = ",
1793 if (bits
->opcode
->last
< bits
->field
->last
)
1794 lf_printf(file
, "%d;\n",
1795 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1797 lf_printf(file
, "%d;\n", bits
->value
);
1800 /* put the field in the local variable */
1801 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1802 lf_printf(file
, "%s const %s = ",
1803 field_type
== NULL
? "unsigned" : field_type
,
1805 /* getting it from the cache */
1806 if (get_value_from_cache
|| put_value_in_cache
) {
1807 lf_printf(file
, "cache_entry->crack.%s.%s",
1808 instruction
->file_entry
->fields
[insn_form
],
1810 if (put_value_in_cache
) /* also put it in the cache? */
1811 lf_printf(file
, " = ");
1813 if (!get_value_from_cache
) {
1814 if (strcmp(field_name
, cur_field
->val_string
) == 0)
1815 lf_printf(file
, "EXTRACTED32(instruction, %d, %d)",
1816 i2target(hi_bit_nr
, cur_field
->first
),
1817 i2target(hi_bit_nr
, cur_field
->last
));
1818 else if (field_expression
!= NULL
)
1819 lf_printf(file
, "%s", field_expression
);
1821 lf_printf(file
, "eval_%s", field_name
);
1823 lf_printf(file
, ";\n");
1829 lf_print_c_extractions(lf
*file
,
1831 insn_bits
*expanded_bits
,
1832 int get_value_from_cache
,
1833 int put_value_in_cache
)
1835 insn_field
*cur_field
;
1837 /* extract instruction fields */
1838 lf_printf(file
, "/* extraction: %s */\n",
1839 instruction
->file_entry
->fields
[insn_format
]);
1841 for (cur_field
= instruction
->fields
->first
;
1842 cur_field
->first
< insn_size
;
1843 cur_field
= cur_field
->next
) {
1844 if (cur_field
->is_string
) {
1847 /* find any corresponding value */
1848 for (bits
= expanded_bits
;
1850 bits
= bits
->last
) {
1851 if (bits
->field
== cur_field
)
1854 /* try the cache rule table for what to do */
1855 if (get_value_from_cache
|| put_value_in_cache
) {
1856 cache_rules
*cache_rule
;
1857 for (cache_rule
= cache_table
;
1859 cache_rule
= cache_rule
->next
) {
1860 if (strcmp(cur_field
->val_string
, cache_rule
->old_name
) == 0) {
1862 if (cache_rule
->valid
> 1 && put_value_in_cache
)
1863 lf_print_c_extraction(file
,
1865 cache_rule
->new_name
,
1867 cache_rule
->expression
,
1872 else if (cache_rule
->valid
== 1)
1873 lf_print_c_extraction(file
,
1875 cache_rule
->new_name
,
1877 cache_rule
->expression
,
1880 get_value_from_cache
,
1881 put_value_in_cache
);
1885 if (found_rule
== 0)
1886 lf_print_c_extraction(file
,
1888 cur_field
->val_string
,
1893 get_value_from_cache
,
1894 put_value_in_cache
);
1895 /* if any (XXX == 0), output a corresponding test */
1896 if (instruction
->file_entry
->annex
!= NULL
) {
1897 char *field_name
= cur_field
->val_string
;
1898 char *is_0_ptr
= instruction
->file_entry
->annex
;
1899 int field_len
= strlen(field_name
);
1900 if (strlen(is_0_ptr
) >= (strlen("_is_0") + field_len
)) {
1901 is_0_ptr
+= field_len
;
1902 while ((is_0_ptr
= strstr(is_0_ptr
, "_is_0")) != NULL
) {
1903 if (strncmp(is_0_ptr
- field_len
, field_name
, field_len
) == 0
1904 && !isalpha(is_0_ptr
[ - field_len
- 1])) {
1905 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1906 lf_printf(file
, "const unsigned %s_is_0 = (", field_name
);
1908 lf_printf(file
, "%d", bits
->value
);
1910 lf_printf(file
, "%s", field_name
);
1911 lf_printf(file
, " == 0);\n");
1914 is_0_ptr
+= strlen("_is_0");
1918 /* any thing else ... */
1921 lf_print_lf_c_line_nr(file
);
1926 lf_print_idecode_illegal(lf
*file
)
1929 lf_printf(file
, "return idecode_illegal(%s);\n", cache_idecode_actual
);
1931 lf_printf(file
, "return semantic_illegal(%s);\n", semantic_actual
);
1936 lf_print_idecode_floating_point_unavailable(lf
*file
)
1939 lf_printf(file
, "return idecode_floating_point_unavailable(%s);\n",
1940 cache_idecode_actual
);
1942 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
1947 /* Output code to do any final checks on the decoded instruction.
1948 This includes things like verifying any on decoded fields have the
1949 correct value and checking that (for floating point) floating point
1950 hardware isn't disabled */
1953 lf_print_c_validate(lf
*file
,
1955 opcode_field
*opcodes
)
1957 /* Validate: unchecked instruction fields
1959 If any constant fields in the instruction were not checked by the
1960 idecode tables, output code to check that they have the correct
1963 unsigned check_mask
= 0;
1964 unsigned check_val
= 0;
1966 opcode_field
*opcode
;
1968 /* form check_mask/check_val containing what needs to be checked
1969 in the instruction */
1970 for (field
= instruction
->fields
->first
;
1971 field
->first
< insn_size
;
1972 field
= field
->next
) {
1974 check_mask
<<= field
->width
;
1975 check_val
<<= field
->width
;
1977 /* is it a constant that could need validating? */
1978 if (!field
->is_int
&& !field
->is_slash
)
1981 /* has it been checked by a table? */
1982 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1983 if (field
->first
>= opcode
->first
1984 && field
->last
<= opcode
->last
)
1990 check_mask
|= (1 << field
->width
)-1;
1991 check_val
|= field
->val_int
;
1994 /* if any bits not checked by opcode tables, output code to check them */
1996 lf_printf(file
, "\n");
1997 lf_printf(file
, "/* validate: %s */\n",
1998 instruction
->file_entry
->fields
[insn_format
]);
1999 lf_printf(file
, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
2000 check_mask
, check_val
);
2001 lf_indent(file
, +2);
2002 lf_print_idecode_illegal(file
);
2003 lf_indent(file
, -2);
2007 /* Validate floating point hardware
2009 If the simulator is being built with out floating point hardware
2010 (different to it being disabled in the MSR) then floating point
2011 instructions are invalid */
2013 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2014 lf_printf(file
, "\n");
2015 lf_printf(file
, "/* Validate: FP hardware exists */\n");
2016 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
2017 lf_indent(file
, +2);
2018 lf_print_idecode_illegal(file
);
2019 lf_indent(file
, -2);
2023 /* Validate: Floating Point available
2025 If floating point is not available, we enter a floating point
2026 unavailable interrupt into the cache instead of the instruction
2029 The PowerPC spec requires a CSI after MSR[FP] is changed and when
2030 ever a CSI occures we flush the instruction cache. */
2033 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2034 lf_printf(file
, "\n");
2035 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
2036 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
2037 lf_indent(file
, +2);
2038 lf_print_idecode_floating_point_unavailable(file
);
2039 lf_indent(file
, -2);
2046 lf_print_c_cracker(lf
*file
,
2048 insn_bits
*expanded_bits
,
2049 opcode_field
*opcodes
)
2052 /* function header */
2053 lf_printf(file
, "{\n");
2054 lf_indent(file
, +2);
2056 lf_print_my_prefix(file
,
2057 instruction
->file_entry
,
2058 1/*putting-value-in-cache*/);
2060 lf_print_ptrace(file
,
2061 1/*putting-value-in-cache*/);
2063 lf_print_c_validate(file
, instruction
, opcodes
);
2065 lf_printf(file
, "\n");
2066 lf_printf(file
, "{\n");
2067 lf_indent(file
, +2);
2068 lf_print_c_extractions(file
,
2071 0/*get_value_from_cache*/,
2072 1/*put_value_in_cache*/);
2073 lf_indent(file
, -2);
2074 lf_printf(file
, "}\n");
2076 /* return the function propper (main sorts this one out) */
2077 lf_printf(file
, "\n");
2078 lf_printf(file
, "/* semantic routine */\n");
2079 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2080 lf_printf(file
, "return ");
2081 lf_print_function_name(file
,
2082 instruction
->file_entry
->fields
[insn_name
],
2084 function_name_prefix_semantics
);
2085 lf_printf(file
, ";\n");
2087 lf_print_lf_c_line_nr(file
);
2088 lf_indent(file
, -2);
2089 lf_printf(file
, "}\n");
2094 lf_print_c_semantic(lf
*file
,
2096 insn_bits
*expanded_bits
,
2097 opcode_field
*opcodes
)
2100 lf_printf(file
, "{\n");
2101 lf_indent(file
, +2);
2103 lf_print_my_prefix(file
,
2104 instruction
->file_entry
,
2105 0/*not putting value in cache*/);
2106 lf_printf(file
, "unsigned_word nia = cia + %d;\n", insn_size
/ 8);
2108 lf_printf(file
, "\n");
2109 lf_print_c_extractions(file
,
2112 idecode_cache
/*get_value_from_cache*/,
2113 0/*put_value_in_cache*/);
2115 lf_print_ptrace(file
,
2116 0/*put_value_in_cache*/);
2118 /* validate the instruction, if a cache this has already been done */
2120 lf_print_c_validate(file
, instruction
, opcodes
);
2122 /* generate the profileing call - this is delayed until after the
2123 instruction has been verified */
2124 lf_printf(file
, "\n");
2125 lf_printf(file
, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
2126 lf_printf(file
, " mon_issue(");
2127 lf_print_function_name(file
,
2128 instruction
->file_entry
->fields
[insn_name
],
2130 function_name_prefix_itable
);
2131 lf_printf(file
, ", processor, cia);\n");
2133 /* generate the code (or at least something */
2134 if (instruction
->file_entry
->annex
!= NULL
) {
2136 lf_printf(file
, "\n");
2137 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2138 lf_printf(file
, "{\n");
2139 lf_indent(file
, +2);
2140 lf_print_c_code(file
, instruction
->file_entry
->annex
);
2141 lf_indent(file
, -2);
2142 lf_printf(file
, "}\n");
2143 lf_print_lf_c_line_nr(file
);
2145 else if (it_is("nop", instruction
->file_entry
->fields
[insn_flags
])) {
2146 lf_print_lf_c_line_nr(file
);
2148 else if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2149 /* unimplemented floating point instruction - call for assistance */
2150 lf_printf(file
, "\n");
2151 lf_printf(file
, "/* unimplemented floating point instruction - call for assistance */\n");
2152 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2153 lf_putstr(file
, "floating_point_assist_interrupt(processor, cia);\n");
2154 lf_print_lf_c_line_nr(file
);
2157 /* abort so it is implemented now */
2158 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2159 lf_putstr(file
, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2160 lf_print_lf_c_line_nr(file
);
2161 lf_printf(file
, "\n");
2164 /* the function footer */
2165 lf_printf(file
, "return nia;\n");
2166 lf_indent(file
, -2);
2167 lf_printf(file
, "}\n");
2171 lf_print_c_semantic_function(lf
*file
,
2173 insn_bits
*expanded_bits
,
2174 opcode_field
*opcodes
,
2175 int is_inline_function
)
2178 /* build the semantic routine to execute the instruction */
2179 lf_print_semantic_function_header(file
,
2180 instruction
->file_entry
->fields
[insn_name
],
2182 1/*is-function-definition*/,
2183 is_inline_function
);
2184 lf_print_c_semantic(file
,
2192 semantics_c_leaf(insn_table
*entry
,
2196 lf
*file
= (lf
*)data
;
2197 ASSERT(entry
->nr_insn
== 1
2198 && entry
->opcode
== NULL
2199 && entry
->parent
!= NULL
2200 && entry
->parent
->opcode
!= NULL
);
2201 lf_print_c_semantic_function(file
,
2203 entry
->expanded_bits
,
2204 entry
->parent
->opcode
,
2205 !idecode_cache
&& entry
->parent
->opcode_rule
->use_switch
);
2209 semantics_c_insn(insn_table
*table
,
2213 lf
*file
= (lf
*)data
;
2214 lf_print_c_semantic_function(file
, instruction
,
2216 0/*isnt_inline_function*/);
2220 semantics_c_function(insn_table
*table
,
2222 table_entry
*function
)
2224 lf
*file
= (lf
*)data
;
2225 if (function
->fields
[function_type
] == NULL
2226 || function
->fields
[function_type
][0] == '\0') {
2227 lf_print_semantic_function_header(file
,
2228 function
->fields
[function_name
],
2230 1/*is function definition*/,
2231 1/*is inline function*/);
2234 lf_printf(file
, "\n");
2235 lf_printf(file
, "INLINE_SEMANTICS %s\n%s(%s)\n",
2236 function
->fields
[function_type
],
2237 function
->fields
[function_name
],
2238 function
->fields
[function_param
]);
2240 table_entry_lf_c_line_nr(file
, function
);
2241 lf_printf(file
, "{\n");
2242 lf_indent(file
, +2);
2243 lf_print_c_code(file
, function
->annex
);
2244 lf_indent(file
, -2);
2245 lf_printf(file
, "}\n");
2246 lf_print_lf_c_line_nr(file
);
2252 gen_semantics_c(insn_table
*table
, lf
*file
)
2254 lf_print_copyleft(file
);
2255 lf_printf(file
, "\n");
2256 lf_printf(file
, "#ifndef _SEMANTICS_C_\n");
2257 lf_printf(file
, "#define _SEMANTICS_C_\n");
2258 lf_printf(file
, "\n");
2259 lf_printf(file
, "#ifndef STATIC_INLINE_SEMANTICS\n");
2260 lf_printf(file
, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2261 lf_printf(file
, "#endif\n");
2262 lf_printf(file
, "\n");
2263 lf_printf(file
, "#include \"cpu.h\"\n");
2264 lf_printf(file
, "#include \"idecode.h\"\n");
2265 lf_printf(file
, "#include \"semantics.h\"\n");
2266 lf_printf(file
, "\n");
2268 /* output a definition (c-code) for all functions */
2269 insn_table_traverse_function(table
,
2271 semantics_c_function
);
2273 /* output a definition (c-code) for all instructions */
2274 if (idecode_expand_semantics
)
2275 insn_table_traverse_tree(table
,
2281 NULL
); /* padding */
2283 insn_table_traverse_insn(table
,
2287 lf_printf(file
, "\n");
2288 lf_printf(file
, "#endif /* _SEMANTICS_C_ */\n");
2292 /****************************************************************/
2295 gen_idecode_h(insn_table
*table
, lf
*file
)
2297 lf_print_copyleft(file
);
2298 lf_printf(file
, "\n");
2299 lf_printf(file
, "#ifndef _IDECODE_H_\n");
2300 lf_printf(file
, "#define _IDECODE_H_\n");
2301 lf_printf(file
, "\n");
2302 lf_printf(file
, "#ifndef INLINE_IDECODE\n");
2303 lf_printf(file
, "#define INLINE_IDECODE\n");
2304 lf_printf(file
, "#endif\n");
2305 lf_printf(file
, "\n");
2306 lf_printf(file
, "#include \"idecode_expression.h\"\n");
2307 lf_printf(file
, "#include \"idecode_fields.h\"\n");
2308 lf_printf(file
, "#include \"idecode_branch.h\"\n");
2309 lf_printf(file
, "\n");
2310 lf_printf(file
, "#include \"icache.h\"\n");
2311 lf_printf(file
, "\n");
2312 lf_printf(file
, "typedef unsigned_word idecode_semantic\n(%s);\n",
2313 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2314 lf_printf(file
, "\n");
2316 lf_printf(file
, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2317 cache_idecode_formal
);
2319 lf_printf(file
, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2321 lf_printf(file
, "\n");
2322 lf_printf(file
, "#endif /* _IDECODE_H_ */\n");
2326 /****************************************************************/
2330 idecode_table_start(insn_table
*table
,
2334 lf
*file
= (lf
*)data
;
2336 /* start of the table */
2337 if (!table
->opcode_rule
->use_switch
) {
2338 lf_printf(file
, "\n");
2339 lf_printf(file
, "static idecode_table_entry ");
2340 lf_print_table_name(file
, table
);
2341 lf_printf(file
, "[] = {\n");
2346 idecode_table_leaf(insn_table
*entry
,
2350 lf
*file
= (lf
*)data
;
2351 ASSERT(entry
->parent
!= NULL
);
2354 /* add an entry to the table */
2355 if (!entry
->parent
->opcode_rule
->use_switch
) {
2356 if (entry
->opcode
== NULL
) {
2357 /* table leaf entry */
2358 lf_printf(file
, " /*%d*/ { 0, 0, ", entry
->opcode_nr
);
2359 lf_print_function_name(file
,
2360 entry
->insns
->file_entry
->fields
[insn_name
],
2361 entry
->expanded_bits
,
2363 ? function_name_prefix_idecode
2364 : function_name_prefix_semantics
));
2365 lf_printf(file
, " },\n");
2367 else if (entry
->opcode_rule
->use_switch
) {
2368 /* table calling switch statement */
2369 lf_printf(file
, " /*%d*/ { 0, 0, ",
2371 lf_print_table_name(file
, entry
);
2372 lf_printf(file
, " },\n");
2375 /* table `calling' another table */
2376 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
2377 if (entry
->opcode
->is_boolean
)
2378 lf_printf(file
, "MASK32(%d,%d), 0, ",
2379 i2target(hi_bit_nr
, entry
->opcode
->first
),
2380 i2target(hi_bit_nr
, entry
->opcode
->last
));
2382 lf_printf(file
, "%d, MASK32(%d,%d), ",
2383 insn_size
- entry
->opcode
->last
- 1,
2384 i2target(hi_bit_nr
, entry
->opcode
->first
),
2385 i2target(hi_bit_nr
, entry
->opcode
->last
));
2386 lf_print_table_name(file
, entry
);
2387 lf_printf(file
, " },\n");
2393 idecode_table_end(insn_table
*table
,
2397 lf
*file
= (lf
*)data
;
2400 if (!table
->opcode_rule
->use_switch
) {
2401 lf_printf(file
, "};\n");
2406 idecode_table_padding(insn_table
*table
,
2411 lf
*file
= (lf
*)data
;
2414 if (!table
->opcode_rule
->use_switch
) {
2415 lf_printf(file
, " /*%d*/ { 0, 0, %s_illegal },\n",
2416 opcode_nr
, (idecode_cache
? "idecode" : "semantic"));
2421 /****************************************************************/
2424 void lf_print_idecode_switch
2430 idecode_switch_start(insn_table
*table
,
2434 lf
*file
= (lf
*)data
;
2436 ASSERT(table
->opcode_rule
->use_switch
);
2438 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2439 i2target(hi_bit_nr
, table
->opcode
->first
),
2440 i2target(hi_bit_nr
, table
->opcode
->last
));
2445 idecode_switch_leaf(insn_table
*entry
,
2449 lf
*file
= (lf
*)data
;
2450 ASSERT(entry
->parent
!= NULL
);
2452 ASSERT(entry
->parent
->opcode_rule
->use_switch
);
2453 ASSERT(entry
->parent
->opcode
);
2455 if (!entry
->parent
->opcode
->is_boolean
2456 || entry
->opcode_nr
== 0)
2457 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
2459 lf_printf(file
, "default:\n");
2460 lf_indent(file
, +2);
2462 if (entry
->opcode
== NULL
) {
2463 /* switch calling leaf */
2464 lf_printf(file
, "return ");
2465 lf_print_function_name(file
,
2466 entry
->insns
->file_entry
->fields
[insn_name
],
2467 entry
->expanded_bits
,
2469 ? function_name_prefix_idecode
2470 : function_name_prefix_semantics
));
2472 lf_printf(file
, "(%s);\n", cache_idecode_actual
);
2474 lf_printf(file
, "(%s);\n", semantic_actual
);
2476 else if (entry
->opcode_rule
->use_switch
) {
2477 /* switch calling switch */
2478 lf_print_idecode_switch(file
, entry
);
2481 /* switch looking up a table */
2482 lf_print_idecode_table(file
, entry
);
2484 lf_printf(file
, "break;\n");
2486 lf_indent(file
, -2);
2491 lf_print_idecode_switch_illegal(lf
*file
)
2493 lf_indent(file
, +2);
2494 lf_print_idecode_illegal(file
);
2495 lf_printf(file
, "break;\n");
2496 lf_indent(file
, -2);
2500 idecode_switch_end(insn_table
*table
,
2504 lf
*file
= (lf
*)data
;
2506 ASSERT(table
->opcode_rule
->use_switch
);
2507 ASSERT(table
->opcode
);
2509 if (table
->opcode_rule
->use_switch
== 1
2510 && !table
->opcode
->is_boolean
) {
2511 lf_printf(file
, "default:\n");
2512 lf_print_idecode_switch_illegal(file
);
2514 lf_printf(file
, "}\n");
2518 idecode_switch_padding(insn_table
*table
,
2523 lf
*file
= (lf
*)data
;
2526 ASSERT(table
->opcode_rule
->use_switch
);
2528 if (table
->opcode_rule
->use_switch
> 1) {
2529 lf_printf(file
, "case %d:\n", opcode_nr
);
2530 lf_print_idecode_switch_illegal(file
);
2536 lf_print_idecode_switch(lf
*file
,
2539 insn_table_traverse_tree(table
,
2542 idecode_switch_start
,
2543 idecode_switch_leaf
,
2545 idecode_switch_padding
);
2550 lf_print_idecode_switch_function_header(lf
*file
,
2552 int is_function_definition
)
2554 lf_printf(file
, "\n");
2555 lf_printf(file
, "static ");
2557 lf_printf(file
, "idecode_semantic *");
2559 lf_printf(file
, "unsigned_word");
2560 if (is_function_definition
)
2561 lf_printf(file
, "\n");
2563 lf_printf(file
, " ");
2564 lf_print_table_name(file
, table
);
2565 lf_printf(file
, "\n(%s)",
2566 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2567 if (!is_function_definition
)
2568 lf_printf(file
, ";");
2569 lf_printf(file
, "\n");
2574 idecode_declare_if_switch(insn_table
*table
,
2578 lf
*file
= (lf
*)data
;
2580 if (table
->opcode_rule
->use_switch
2581 && table
->parent
!= NULL
/* don't declare the top one yet */
2582 && !table
->parent
->opcode_rule
->use_switch
) {
2583 lf_print_idecode_switch_function_header(file
,
2585 0/*isnt function definition*/);
2591 idecode_expand_if_switch(insn_table
*table
,
2595 lf
*file
= (lf
*)data
;
2597 if (table
->opcode_rule
->use_switch
2598 && table
->parent
!= NULL
/* don't expand the top one yet */
2599 && !table
->parent
->opcode_rule
->use_switch
) {
2600 lf_print_idecode_switch_function_header(file
,
2602 1/*is function definition*/);
2603 lf_printf(file
, "{\n");
2605 lf_indent(file
, +2);
2606 lf_print_idecode_switch(file
, table
);
2607 lf_indent(file
, -2);
2609 lf_printf(file
, "}\n");
2615 lf_print_c_cracker_function(lf
*file
,
2617 insn_bits
*expanded_bits
,
2618 opcode_field
*opcodes
,
2619 int is_inline_function
)
2621 /* if needed, generate code to enter this routine into a cache */
2622 lf_printf(file
, "\n");
2623 lf_printf(file
, "STATIC_IDECODE idecode_semantic *\n");
2624 lf_print_function_name(file
,
2625 instruction
->file_entry
->fields
[insn_name
],
2627 function_name_prefix_idecode
);
2628 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2630 lf_print_c_cracker(file
,
2637 idecode_crack_leaf(insn_table
*entry
,
2641 lf
*file
= (lf
*)data
;
2642 ASSERT(entry
->nr_insn
== 1
2643 && entry
->opcode
== NULL
2644 && entry
->parent
!= NULL
2645 && entry
->parent
->opcode
!= NULL
2646 && entry
->parent
->opcode_rule
!= NULL
);
2647 lf_print_c_cracker_function(file
,
2649 entry
->expanded_bits
,
2651 entry
->parent
->opcode_rule
->use_switch
);
2655 idecode_crack_insn(insn_table
*entry
,
2659 lf
*file
= (lf
*)data
;
2660 lf_print_c_cracker_function(file
,
2664 0/*isnt inline function*/);
2668 idecode_c_internal_function(insn_table
*table
,
2670 table_entry
*function
)
2672 lf
*file
= (lf
*)data
;
2673 ASSERT(idecode_cache
!= 0);
2674 if (it_is("internal", function
->fields
[insn_flags
])) {
2675 lf_printf(file
, "\n");
2676 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2677 lf_print_function_name(file
,
2678 function
->fields
[insn_name
],
2680 function_name_prefix_idecode
);
2681 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2682 lf_printf(file
, "{\n");
2683 lf_indent(file
, +2);
2684 lf_printf(file
, "/* semantic routine */\n");
2685 table_entry_lf_c_line_nr(file
, function
);
2686 lf_printf(file
, "return ");
2687 lf_print_function_name(file
,
2688 function
->fields
[insn_name
],
2690 function_name_prefix_semantics
);
2691 lf_printf(file
, ";\n");
2693 lf_print_lf_c_line_nr(file
);
2694 lf_indent(file
, -2);
2695 lf_printf(file
, "}\n");
2700 /****************************************************************/
2703 gen_idecode_c(insn_table
*table
, lf
*file
)
2708 lf_print_copyleft(file
);
2709 lf_printf(file
, "\n");
2710 lf_printf(file
, "\n");
2711 lf_printf(file
, "#ifndef _IDECODE_C_\n");
2712 lf_printf(file
, "#define _IDECODE_C_\n");
2713 lf_printf(file
, "\n");
2714 lf_printf(file
, "#ifndef STATIC_INLINE_IDECODE\n");
2715 lf_printf(file
, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2716 lf_printf(file
, "#endif\n");
2717 lf_printf(file
, "\n");
2718 lf_printf(file
, "#ifndef STATIC_IDECODE\n");
2719 lf_printf(file
, "#define STATIC_IDECODE\n");
2720 lf_printf(file
, "#endif\n");
2721 lf_printf(file
, "\n");
2722 lf_printf(file
, "#include \"cpu.h\"\n");
2723 lf_printf(file
, "#include \"idecode.h\"\n");
2724 lf_printf(file
, "#include \"semantics.h\"\n");
2725 lf_printf(file
, "\n");
2726 lf_printf(file
, "\n");
2727 lf_printf(file
, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2728 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2729 lf_printf(file
, "\n");
2730 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
2731 lf_printf(file
, " unsigned shift;\n");
2732 lf_printf(file
, " unsigned mask;\n");
2733 lf_printf(file
, " void *function_or_table;\n");
2734 lf_printf(file
, "} idecode_table_entry;\n");
2735 lf_printf(file
, "\n");
2736 lf_printf(file
, "\n");
2738 /* output `internal' invalid/floating-point unavailable functions
2740 if (idecode_cache
) {
2741 insn_table_traverse_function(table
,
2743 idecode_c_internal_function
);
2746 /* output cracking functions where needed */
2747 if (idecode_cache
) {
2748 if (idecode_expand_semantics
)
2749 insn_table_traverse_tree(table
,
2757 insn_table_traverse_insn(table
,
2759 idecode_crack_insn
);
2762 /* output switch function declarations where needed by tables */
2763 insn_table_traverse_tree(table
,
2766 idecode_declare_if_switch
, /* START */
2769 /* output tables where needed */
2770 for (depth
= insn_table_depth(table
);
2773 insn_table_traverse_tree(table
,
2776 idecode_table_start
,
2779 idecode_table_padding
);
2782 /* output switch functions where needed */
2783 insn_table_traverse_tree(table
,
2786 idecode_expand_if_switch
, /* START */
2789 /* output the main idecode routine */
2790 lf_printf(file
, "\n");
2792 lf_printf(file
, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2793 cache_idecode_formal
);
2795 lf_printf(file
, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2797 lf_printf(file
, "{\n");
2798 lf_indent(file
, +2);
2799 if (table
->opcode_rule
->use_switch
)
2800 lf_print_idecode_switch(file
, table
);
2802 lf_print_idecode_table(file
, table
);
2803 lf_indent(file
, -2);
2804 lf_printf(file
, "}\n");
2805 lf_printf(file
, "\n");
2806 lf_printf(file
, "#endif /* _IDECODE_C_ */\n");
2810 /****************************************************************/
2813 itable_h_insn(insn_table
*entry
,
2817 lf
*file
= (lf
*)data
;
2818 lf_printf(file
, " ");
2819 lf_print_function_name(file
,
2820 instruction
->file_entry
->fields
[insn_name
],
2822 function_name_prefix_itable
);
2823 lf_printf(file
, ",\n");
2828 gen_itable_h(insn_table
*table
, lf
*file
)
2831 lf_print_copyleft(file
);
2832 lf_printf(file
, "\n");
2833 lf_printf(file
, "#ifndef _ITABLE_H_\n");
2834 lf_printf(file
, "#define _ITABLE_H_\n");
2835 lf_printf(file
, "\n");
2836 lf_printf(file
, "#ifndef INLINE_ITABLE\n");
2837 lf_printf(file
, "#define INLINE_ITABLE\n");
2838 lf_printf(file
, "#endif\n");
2839 lf_printf(file
, "\n");
2840 lf_printf(file
, "\n");
2842 /* output an enumerated type for each instruction */
2843 lf_printf(file
, "typedef enum {\n");
2844 insn_table_traverse_insn(table
,
2847 lf_printf(file
, " nr_itable_entries,\n");
2848 lf_printf(file
, "} itable_index;\n");
2849 lf_printf(file
, "\n");
2851 /* output the table that contains the actual instruction info */
2852 lf_printf(file
, "typedef struct _itable_instruction_info {\n");
2853 lf_printf(file
, " itable_index nr;\n");
2854 lf_printf(file
, " char *format;\n");
2855 lf_printf(file
, " char *form;\n");
2856 lf_printf(file
, " char *flags;\n");
2857 lf_printf(file
, " char *mnemonic;\n");
2858 lf_printf(file
, " char *name;\n");
2859 lf_printf(file
, "} itable_info;\n");
2860 lf_printf(file
, "\n");
2861 lf_printf(file
, "extern itable_info itable[nr_itable_entries];\n");
2863 lf_printf(file
, "\n");
2864 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2868 /****************************************************************/
2871 itable_c_insn(insn_table
*entry
,
2875 lf
*file
= (lf
*)data
;
2876 char **fields
= instruction
->file_entry
->fields
;
2877 lf_printf(file
, " { ");
2878 lf_print_function_name(file
,
2879 instruction
->file_entry
->fields
[insn_name
],
2881 function_name_prefix_itable
);
2882 lf_printf(file
, ",\n");
2883 lf_printf(file
, " \"%s\",\n", fields
[insn_format
]);
2884 lf_printf(file
, " \"%s\",\n", fields
[insn_form
]);
2885 lf_printf(file
, " \"%s\",\n", fields
[insn_flags
]);
2886 lf_printf(file
, " \"%s\",\n", fields
[insn_mnemonic
]);
2887 lf_printf(file
, " \"%s\",\n", fields
[insn_name
]);
2888 lf_printf(file
, " },\n");
2893 gen_itable_c(insn_table
*table
, lf
*file
)
2896 lf_print_copyleft(file
);
2897 lf_printf(file
, "\n");
2898 lf_printf(file
, "#ifndef _ITABLE_C_\n");
2899 lf_printf(file
, "#define _ITABLE_C_\n");
2900 lf_printf(file
, "\n");
2901 lf_printf(file
, "#ifndef STATIC_INLINE_ITABLE\n");
2902 lf_printf(file
, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2903 lf_printf(file
, "#endif\n");
2904 lf_printf(file
, "\n");
2905 lf_printf(file
, "#include \"itable.h\"\n");
2906 lf_printf(file
, "\n");
2908 /* output the table that contains the actual instruction info */
2909 lf_printf(file
, "itable_info itable[nr_itable_entries] = {\n");
2910 insn_table_traverse_insn(table
,
2913 lf_printf(file
, "};\n");
2914 lf_printf(file
, "\n");
2916 lf_printf(file
, "\n");
2917 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2920 /****************************************************************/
2923 model_c_or_h_data(insn_table
*table
,
2928 table_entry_lf_c_line_nr(file
, data
);
2929 lf_print_c_code(file
, data
->annex
);
2930 lf_print_lf_c_line_nr(file
);
2931 lf_printf(file
, "\n");
2936 model_c_or_h_function(insn_table
*entry
,
2938 table_entry
*function
,
2941 if (function
->fields
[function_type
] == NULL
2942 || function
->fields
[function_type
][0] == '\0') {
2943 error("Model function type not specified for %s", function
->fields
[function_name
]);
2946 lf_printf(file
, "\n");
2947 lf_printf(file
, "%s %s %s\n(%s);\n",
2949 function
->fields
[function_type
],
2950 function
->fields
[function_name
],
2951 function
->fields
[function_param
]);
2953 lf_printf(file
, "\n");
2957 gen_model_h(insn_table
*table
, lf
*file
)
2963 int model_create_p
= 0;
2964 int model_init_p
= 0;
2965 int model_halt_p
= 0;
2966 int model_issue_p
= 0;
2967 int model_mon_info_p
= 0;
2968 int model_mon_info_free_p
= 0;
2970 lf_print_copyleft(file
);
2971 lf_printf(file
, "\n");
2972 lf_printf(file
, "#ifndef _MODEL_H_\n");
2973 lf_printf(file
, "#define _MODEL_H_\n");
2974 lf_printf(file
, "\n");
2976 for(macro
= model_macros
; macro
; macro
= macro
->next
) {
2977 model_c_or_h_data(table
, file
, macro
->file_entry
);
2980 lf_printf(file
, "#ifndef INLINE_MODEL\n");
2981 lf_printf(file
, "#define INLINE_MODEL\n");
2982 lf_printf(file
, "#endif\n");
2983 lf_printf(file
, "#ifndef STATIC_INLINE_MODEL\n");
2984 lf_printf(file
, "#define STATIC_INLINE_MODEL STATIC_INLINE\n");
2985 lf_printf(file
, "#endif\n");
2986 lf_printf(file
, "\n");
2987 lf_printf(file
, "#ifndef STATIC_MODEL\n");
2988 lf_printf(file
, "#define STATIC_MODEL\n");
2989 lf_printf(file
, "#endif\n");
2990 lf_printf(file
, "\n");
2991 lf_printf(file
, "#ifndef EXTERN_MODEL\n");
2992 lf_printf(file
, "#define EXTERN_MODEL extern\n");
2993 lf_printf(file
, "#endif\n");
2994 lf_printf(file
, "\n");
2996 lf_printf(file
, "typedef enum _model_enum {\n");
2997 lf_printf(file
, " MODEL_NONE,\n");
2998 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
2999 lf_printf(file
, " MODEL_%s,\n", model_ptr
->name
);
3001 lf_printf(file
, " nr_models\n");
3002 lf_printf(file
, "} model_enum;\n");
3003 lf_printf(file
, "\n");
3005 lf_printf(file
, "#define DEFAULT_MODEL MODEL_%s\n", (models
) ? models
->name
: "NONE");
3006 lf_printf(file
, "\n");
3008 lf_printf(file
, "typedef struct _model_data model_data;\n");
3009 lf_printf(file
, "typedef struct _model_time model_time;\n");
3010 lf_printf(file
, "\n");
3012 lf_printf(file
, "extern model_enum current_model;\n");
3013 lf_printf(file
, "EXTERN_MODEL const char *model_name[ (int)nr_models ];\n");
3014 lf_printf(file
, "EXTERN_MODEL const char *const *const model_func_unit_name[ (int)nr_models ];\n");
3015 lf_printf(file
, "EXTERN_MODEL const model_time *const model_time_mapping[ (int)nr_models ];\n");
3016 lf_printf(file
, "\n");
3018 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3019 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3020 name
= insn_ptr
->file_entry
->fields
[function_name
];
3021 if (strcmp (name
, "model_create") == 0)
3023 else if (strcmp (name
, "model_init") == 0)
3025 else if (strcmp (name
, "model_halt") == 0)
3027 else if (strcmp (name
, "model_issue") == 0)
3029 else if (strcmp (name
, "model_mon_info") == 0)
3030 model_mon_info_p
= 1;
3031 else if (strcmp (name
, "model_mon_info_free") == 0)
3032 model_mon_info_free_p
= 1;
3035 if (!model_create_p
) {
3036 lf_printf(file
, "INLINE_MODEL model_data *model_create\n");
3037 lf_printf(file
, "(cpu *processor);\n");
3038 lf_printf(file
, "\n");
3041 if (!model_init_p
) {
3042 lf_printf(file
, "INLINE_MODEL void model_init\n");
3043 lf_printf(file
, "(cpu *processor,\n");
3044 lf_printf(file
, " model_data *model_ptr);\n");
3045 lf_printf(file
, "\n");
3048 if (!model_halt_p
) {
3049 lf_printf(file
, "INLINE_MODEL void model_halt\n");
3050 lf_printf(file
, "(cpu *processor,\n");
3051 lf_printf(file
, " model_data *model_ptr);\n");
3052 lf_printf(file
, "\n");
3055 if (!model_issue_p
) {
3056 lf_printf(file
, "INLINE_MODEL void model_issue\n");
3057 lf_printf(file
, "(itable_index index,\n");
3058 lf_printf(file
, " cpu *processor,\n");
3059 lf_printf(file
, " model_data *model_ptr,\n");
3060 lf_printf(file
, " unsigned_word cia);\n");
3061 lf_printf(file
, "\n");
3064 if (!model_mon_info_p
) {
3065 lf_printf(file
, "INLINE_MODEL model_print *model_mon_info\n");
3066 lf_printf(file
, "(model_data *model_ptr);\n");
3067 lf_printf(file
, "\n");
3070 if (!model_mon_info_free_p
) {
3071 lf_printf(file
, "INLINE_MODEL void model_mon_info_free\n");
3072 lf_printf(file
, "(model_data *model_ptr,\n");
3073 lf_printf(file
, " model_print *info_ptr);\n");
3074 lf_printf(file
, "\n");
3077 lf_printf(file
, "INLINE_MODEL void model_set\n");
3078 lf_printf(file
, "(const char *name);\n");
3079 lf_printf(file
, "\n");
3080 lf_printf(file
, "#endif /* _MODEL_H_ */\n");
3083 /****************************************************************/
3085 typedef struct _model_c_passed_data model_c_passed_data
;
3086 struct _model_c_passed_data
{
3092 model_c_insn(insn_table
*entry
,
3096 model_c_passed_data
*data_ptr
= (model_c_passed_data
*)data
;
3097 lf
*file
= data_ptr
->file
;
3098 char *current_name
= data_ptr
->model_ptr
->printable_name
;
3099 table_model_entry
*model_ptr
= instruction
->file_entry
->model_first
;
3102 if (model_ptr
->fields
[insn_model_name
] == current_name
) {
3103 lf_printf(file
, " { %-*s }, /* %s */\n",
3104 max_model_fields_len
,
3105 model_ptr
->fields
[insn_model_fields
],
3106 instruction
->file_entry
->fields
[insn_name
]);
3110 model_ptr
= model_ptr
->next
;
3113 lf_printf(file
, " { %-*s }, /* %s */\n",
3114 max_model_fields_len
,
3115 data_ptr
->model_ptr
->insn_default
,
3116 instruction
->file_entry
->fields
[insn_name
]);
3120 model_c_function(insn_table
*table
,
3122 table_entry
*function
,
3125 if (function
->fields
[function_type
] == NULL
3126 || function
->fields
[function_type
][0] == '\0') {
3127 error("Model function return type not specified for %s", function
->fields
[function_name
]);
3130 lf_printf(file
, "\n");
3131 lf_printf(file
, "%s %s\n%s(%s)\n",
3133 function
->fields
[function_type
],
3134 function
->fields
[function_name
],
3135 function
->fields
[function_param
]);
3137 table_entry_lf_c_line_nr(file
, function
);
3138 lf_printf(file
, "{\n");
3139 if (function
->annex
) {
3140 lf_indent(file
, +2);
3141 lf_print_c_code(file
, function
->annex
);
3142 lf_indent(file
, -2);
3144 lf_printf(file
, "}\n");
3145 lf_print_lf_c_line_nr(file
);
3146 lf_printf(file
, "\n");
3150 gen_model_c(insn_table
*table
, lf
*file
)
3155 int model_create_p
= 0;
3156 int model_init_p
= 0;
3157 int model_halt_p
= 0;
3158 int model_issue_p
= 0;
3159 int model_mon_info_p
= 0;
3160 int model_mon_info_free_p
= 0;
3162 lf_print_copyleft(file
);
3163 lf_printf(file
, "\n");
3164 lf_printf(file
, "#ifndef _MODEL_C_\n");
3165 lf_printf(file
, "#define _MODEL_C_\n");
3166 lf_printf(file
, "\n");
3167 lf_printf(file
, "#include \"cpu.h\"\n");
3168 lf_printf(file
, "#include \"mon.h\"\n");
3169 lf_printf(file
, "\n");
3170 lf_printf(file
, "#ifdef HAVE_STDLIB_H\n");
3171 lf_printf(file
, "#include <stdlib.h>\n");
3172 lf_printf(file
, "#endif\n");
3173 lf_printf(file
, "\n");
3175 for(insn_ptr
= model_data
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3176 model_c_or_h_data(table
, file
, insn_ptr
->file_entry
);
3179 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3180 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3183 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3184 model_c_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3187 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3188 model_c_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3189 name
= insn_ptr
->file_entry
->fields
[function_name
];
3190 if (strcmp (name
, "model_create") == 0)
3192 else if (strcmp (name
, "model_init") == 0)
3194 else if (strcmp (name
, "model_halt") == 0)
3196 else if (strcmp (name
, "model_issue") == 0)
3198 else if (strcmp (name
, "model_mon_info") == 0)
3199 model_mon_info_p
= 1;
3200 else if (strcmp (name
, "model_mon_info_free") == 0)
3201 model_mon_info_free_p
= 1;
3204 if (!model_create_p
) {
3205 lf_printf(file
, "INLINE_MODEL model_data *model_create(cpu *processor)\n");
3206 lf_printf(file
, "{\n");
3207 lf_printf(file
, " return (model_data *)0;\n");
3208 lf_printf(file
, "}\n");
3209 lf_printf(file
, "\n");
3212 if (!model_init_p
) {
3213 lf_printf(file
, "INLINE_MODEL void model_init(cpu *processor,\n");
3214 lf_printf(file
, " model_data *model_ptr)\n");
3215 lf_printf(file
, "{\n");
3216 lf_printf(file
, "}\n");
3217 lf_printf(file
, "\n");
3220 if (!model_halt_p
) {
3221 lf_printf(file
, "INLINE_MODEL void model_halt(cpu *processor,\n");
3222 lf_printf(file
, " model_data *model_ptr)\n");
3223 lf_printf(file
, "{\n");
3224 lf_printf(file
, "}\n");
3225 lf_printf(file
, "\n");
3228 if (!model_issue_p
) {
3229 lf_printf(file
, "INLINE_MODEL void model_issue(itable_index index,\n");
3230 lf_printf(file
, " cpu *processor,\n");
3231 lf_printf(file
, " model_data *model_ptr,\n");
3232 lf_printf(file
, " unsigned_word cia);\n");
3233 lf_printf(file
, "{\n");
3234 lf_printf(file
, "}\n");
3235 lf_printf(file
, "\n");
3238 if (!model_mon_info_p
) {
3239 lf_printf(file
, "INLINE_MODEL model_print *model_mon_info(model_data *model_ptr)\n");
3240 lf_printf(file
, "{\n");
3241 lf_printf(file
, " return (model_print *)0;\n");
3242 lf_printf(file
, "}\n");
3243 lf_printf(file
, "\n");
3246 if (!model_mon_info_free_p
) {
3247 lf_printf(file
, "INLINE_MODEL void model_mon_info_free(model_data *model_ptr,\n");
3248 lf_printf(file
, " model_print *info_ptr)\n");
3249 lf_printf(file
, "{\n");
3250 lf_printf(file
, "}\n");
3251 lf_printf(file
, "\n");
3254 lf_printf(file
, "/* Insn functional unit info */\n");
3255 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3256 model_c_passed_data data
;
3258 lf_printf(file
, "static const model_time model_time_%s[] = {\n", model_ptr
->name
);
3260 data
.model_ptr
= model_ptr
;
3261 insn_table_traverse_insn(table
,
3265 lf_printf(file
, "};\n");
3266 lf_printf(file
, "\n");
3267 lf_printf(file
, "\f\n");
3270 lf_printf(file
, "STATIC_MODEL const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3271 lf_printf(file
, " (const model_time *const)0,\n");
3272 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3273 lf_printf(file
, " model_time_%s,\n", model_ptr
->name
);
3275 lf_printf(file
, "};\n");
3276 lf_printf(file
, "\n");
3278 lf_printf(file
, "\f\n");
3279 lf_printf(file
, "/* map model enumeration into printable string */\n");
3280 lf_printf(file
, "STATIC_MODEL const char *model_name[ (int)nr_models ] = {\n");
3281 lf_printf(file
, " \"NONE\",\n");
3282 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3283 lf_printf(file
, " \"%s\",\n", model_ptr
->printable_name
);
3285 lf_printf(file
, "};\n");
3286 lf_printf(file
, "\n");
3288 lf_printf(file
, "INLINE_MODEL void\n");
3289 lf_printf(file
, "model_set(const char *name)\n");
3290 lf_printf(file
, "{\n");
3292 lf_printf(file
, " model_enum model;\n");
3293 lf_printf(file
, " for(model = MODEL_%s; model < nr_models; model++) {\n", models
->name
);
3294 lf_printf(file
, " if(strcmp(name, model_name[model]) == 0) {\n");
3295 lf_printf(file
, " current_model = model;\n");
3296 lf_printf(file
, " return;\n");
3297 lf_printf(file
, " }\n");
3298 lf_printf(file
, " }\n");
3299 lf_printf(file
, "\n");
3300 lf_printf(file
, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3301 lf_printf(file
, " name,\n");
3302 lf_printf(file
, " \"");
3303 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3304 lf_printf(file
, "\\n\\t%s", model_ptr
->printable_name
);
3306 lf_printf(file
, "\");\n");
3308 lf_printf(file
, " error(\"No models are currently known about\");\n");
3311 lf_printf(file
, "}\n");
3312 lf_printf(file
, "\n");
3314 lf_printf(file
, "#endif /* _MODEL_C_ */\n");
3318 /****************************************************************/
3326 insn_table
*instructions
= NULL
;
3327 icache_tree
*cache_fields
= NULL
;
3328 char *real_file_name
= NULL
;
3333 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
3334 printf("Config options:\n");
3335 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
3336 printf(" -e Expand (duplicate) semantic functions\n");
3337 printf(" -r <icache-size> Generate cracking cache version\n");
3338 printf(" -l Supress line numbering in output files\n");
3339 printf(" -b <bit-size> Set the number of bits in an instruction\n");
3340 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
3341 printf("Input options (ucase version also dumps loaded table):\n");
3342 printf(" -[Oo] <opcode-rules>\n");
3343 printf(" -[Kk] <cache-rules>\n");
3344 printf(" -[Ii] <instruction-table>\n");
3345 printf("Output options:\n");
3346 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
3347 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
3348 printf(" -[Mm] <output-file> output model.h(M) model.c(M)\n");
3349 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
3350 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
3353 while ((ch
= getopt(argc
, argv
,
3354 "leb:h:r:f:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
3355 fprintf(stderr
, "\t-%c %s\n", ch
, (optarg
? optarg
: ""));
3361 idecode_expand_semantics
= 1;
3364 idecode_cache
= a2i(optarg
);
3367 insn_size
= a2i(optarg
);
3368 ASSERT(insn_size
> 0 && insn_size
<= max_insn_size
3369 && (hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0));
3372 hi_bit_nr
= a2i(optarg
);
3373 ASSERT(hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0);
3377 filter
*new_filter
= ZALLOC(filter
);
3378 new_filter
->flag
= strdup(optarg
);
3379 new_filter
->next
= filters
;
3380 filters
= new_filter
;
3385 ASSERT(opcode_table
!= NULL
);
3386 ASSERT(cache_table
!= NULL
);
3387 instructions
= insn_table_load_insns(optarg
);
3388 fprintf(stderr
, "\texpanding ...\n");
3389 insn_table_expand_insns(instructions
);
3390 fprintf(stderr
, "\tcache fields ...\n");
3391 cache_fields
= insn_table_cache_fields(instructions
);
3393 dump_traverse(instructions
);
3394 dump_insn_table(instructions
, 0, 1);
3399 opcode_table
= load_opcode_rules(optarg
);
3401 dump_opcode_rules(opcode_table
, 0);
3405 cache_table
= load_cache_rules(optarg
);
3407 dump_cache_rules(cache_table
, 0);
3410 real_file_name
= strdup(optarg
);
3422 lf
*file
= lf_open(optarg
, real_file_name
, number_lines
);
3423 ASSERT(instructions
!= NULL
);
3426 gen_semantics_h(instructions
, file
);
3429 gen_semantics_c(instructions
, file
);
3432 gen_idecode_h(instructions
, file
);
3435 gen_idecode_c(instructions
, file
);
3438 gen_model_h(instructions
, file
);
3441 gen_model_c(instructions
, file
);
3444 gen_itable_h(instructions
, file
);
3447 gen_itable_c(instructions
, file
);
3450 gen_icache_h(cache_fields
, file
);
3455 real_file_name
= NULL
;
3458 error("unknown option\n");