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
;
641 insn_table_insert_function(insn_table
*table
,
642 table_entry
*file_entry
)
644 /* create a new function */
645 insn
*new_function
= ZALLOC(insn
);
646 new_function
->file_entry
= file_entry
;
648 /* append it to the end of the function list */
649 if (table
->last_function
)
650 table
->last_function
->next
= new_function
;
652 table
->functions
= new_function
;
653 table
->last_function
= new_function
;
657 insn_table_insert_insn(insn_table
*table
,
658 table_entry
*file_entry
,
661 insn
**ptr_to_cur_insn
= &table
->insns
;
662 insn
*cur_insn
= *ptr_to_cur_insn
;
663 table_model_entry
*insn_model_ptr
;
666 /* create a new instruction */
667 insn
*new_insn
= ZALLOC(insn
);
668 new_insn
->file_entry
= file_entry
;
669 new_insn
->fields
= fields
;
671 /* Check out any model information returned to make sure the model
673 for(insn_model_ptr
= file_entry
->model_first
; insn_model_ptr
; insn_model_ptr
= insn_model_ptr
->next
) {
674 char *name
= insn_model_ptr
->fields
[insn_model_name
];
676 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
677 if (strcmp(name
, model_ptr
->printable_name
) == 0) {
679 /* Replace the name field with that of the global model, so that when we
680 want to print it out, we can just compare pointers. */
681 insn_model_ptr
->fields
[insn_model_name
] = model_ptr
->printable_name
;
687 error("%s:%d: machine model `%s' was not known about\n",
688 file_entry
->file_name
, file_entry
->line_nr
, name
);
691 /* insert it according to the order of the fields */
692 while (cur_insn
!= NULL
693 && new_insn
->fields
->value
>= cur_insn
->fields
->value
) {
694 ptr_to_cur_insn
= &cur_insn
->next
;
695 cur_insn
= *ptr_to_cur_insn
;
698 new_insn
->next
= cur_insn
;
699 *ptr_to_cur_insn
= new_insn
;
705 static opcode_field
*
706 insn_table_find_opcode_field(insn
*insns
,
710 opcode_field
*curr_opcode
= ZALLOC(opcode_field
);
714 curr_opcode
->first
= insn_size
;
715 curr_opcode
->last
= -1;
716 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
) {
717 insn_fields
*fields
= entry
->fields
;
718 opcode_field new_opcode
;
720 /* find a start point for the opcode field */
721 new_opcode
.first
= rule
->first
;
722 while (new_opcode
.first
<= rule
->last
724 || insn_field_is_constant(fields
->bits
[new_opcode
.first
],
725 rule
) != field_constant_string
)
727 || !insn_field_is_constant(fields
->bits
[new_opcode
.first
],
729 new_opcode
.first
= fields
->bits
[new_opcode
.first
]->last
+ 1;
730 ASSERT(new_opcode
.first
> rule
->last
732 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
733 rule
) == field_constant_string
)
735 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
738 /* find the end point for the opcode field */
739 new_opcode
.last
= rule
->last
;
740 while (new_opcode
.last
>= rule
->first
742 || insn_field_is_constant(fields
->bits
[new_opcode
.last
],
743 rule
) != field_constant_string
)
745 || !insn_field_is_constant(fields
->bits
[new_opcode
.last
],
747 new_opcode
.last
= fields
->bits
[new_opcode
.last
]->first
- 1;
748 ASSERT(new_opcode
.last
< rule
->first
750 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
751 rule
) == field_constant_string
)
753 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
756 /* now see if our current opcode needs expanding */
757 if (new_opcode
.first
<= rule
->last
758 && curr_opcode
->first
> new_opcode
.first
)
759 curr_opcode
->first
= new_opcode
.first
;
760 if (new_opcode
.last
>= rule
->first
761 && curr_opcode
->last
< new_opcode
.last
)
762 curr_opcode
->last
= new_opcode
.last
;
766 /* was any thing interesting found? */
767 if (curr_opcode
->first
> rule
->last
) {
768 ASSERT(curr_opcode
->last
< rule
->first
);
771 ASSERT(curr_opcode
->last
>= rule
->first
);
772 ASSERT(curr_opcode
->first
<= rule
->last
);
774 /* if something was found, check it includes the forced field range */
776 && curr_opcode
->first
> rule
->force_first
) {
777 curr_opcode
->first
= rule
->force_first
;
780 && curr_opcode
->last
< rule
->force_last
) {
781 curr_opcode
->last
= rule
->force_last
;
783 /* handle special case elminating any need to do shift after mask */
785 && rule
->force_last
== insn_size
-1) {
786 curr_opcode
->last
= insn_size
-1;
789 /* handle any special cases */
790 switch (rule
->special_rule
) {
791 case 0: /* let the above apply */
793 case 1: /* expand a limited nr of bits, ignoring the rest */
794 curr_opcode
->first
= rule
->force_first
;
795 curr_opcode
->last
= rule
->force_last
;
797 case 2: /* boolean field */
798 curr_opcode
->is_boolean
= 1;
807 insn_table_insert_expanded(insn_table
*table
,
812 insn_table
**ptr_to_cur_entry
= &table
->entries
;
813 insn_table
*cur_entry
= *ptr_to_cur_entry
;
815 /* find the new table for this entry */
816 while (cur_entry
!= NULL
817 && cur_entry
->opcode_nr
< new_opcode_nr
) {
818 ptr_to_cur_entry
= &cur_entry
->sibling
;
819 cur_entry
= *ptr_to_cur_entry
;
822 if (cur_entry
== NULL
|| cur_entry
->opcode_nr
!= new_opcode_nr
) {
823 insn_table
*new_entry
= ZALLOC(insn_table
);
824 new_entry
->opcode_nr
= new_opcode_nr
;
825 new_entry
->expanded_bits
= new_bits
;
826 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
827 new_entry
->sibling
= cur_entry
;
828 new_entry
->parent
= table
;
829 *ptr_to_cur_entry
= new_entry
;
830 cur_entry
= new_entry
;
833 /* ASSERT new_bits == cur_entry bits */
834 ASSERT(cur_entry
!= NULL
&& cur_entry
->opcode_nr
== new_opcode_nr
);
835 insn_table_insert_insn(cur_entry
,
836 old_insn
->file_entry
,
841 insn_table_expand_opcode(insn_table
*table
,
848 if (field_nr
> table
->opcode
->last
) {
849 insn_table_insert_expanded(table
, instruction
, opcode_nr
, bits
);
852 insn_field
*field
= instruction
->fields
->bits
[field_nr
];
853 if (field
->is_int
|| field
->is_slash
) {
854 ASSERT(field
->first
>= table
->opcode
->first
855 && field
->last
<= table
->opcode
->last
);
856 insn_table_expand_opcode(table
, instruction
, field
->last
+1,
857 ((opcode_nr
<< field
->width
) + field
->val_int
),
862 int last_pos
= ((field
->last
< table
->opcode
->last
)
863 ? field
->last
: table
->opcode
->last
);
864 int first_pos
= ((field
->first
> table
->opcode
->first
)
865 ? field
->first
: table
->opcode
->first
);
866 int width
= last_pos
- first_pos
+ 1;
867 int last_val
= (table
->opcode
->is_boolean
869 for (val
= 0; val
< last_val
; val
++) {
870 insn_bits
*new_bits
= ZALLOC(insn_bits
);
871 new_bits
->field
= field
;
872 new_bits
->value
= val
;
873 new_bits
->last
= bits
;
874 new_bits
->opcode
= table
->opcode
;
875 insn_table_expand_opcode(table
, instruction
, last_pos
+1,
876 ((opcode_nr
<< width
) | val
),
884 insn_table_insert_expanding(insn_table
*table
,
887 insn_table_expand_opcode(table
,
889 table
->opcode
->first
,
891 table
->expanded_bits
);
896 insn_table_expand_insns(insn_table
*table
)
899 ASSERT(table
->nr_insn
>= 1);
901 /* determine a valid opcode */
902 while (table
->opcode_rule
) {
903 /* specials only for single instructions */
904 if ((table
->nr_insn
> 1
905 && table
->opcode_rule
->special_mask
== 0
906 && table
->opcode_rule
->special_rule
== 0)
907 || (table
->nr_insn
== 1
908 && table
->opcode_rule
->special_mask
!= 0
909 && ((table
->insns
->fields
->value
910 & table
->opcode_rule
->special_mask
)
911 == table
->opcode_rule
->special_value
))
912 || (idecode_expand_semantics
913 && table
->opcode_rule
->special_mask
== 0
914 && table
->opcode_rule
->special_rule
== 0))
916 insn_table_find_opcode_field(table
->insns
,
918 table
->nr_insn
== 1/*string*/
920 if (table
->opcode
!= NULL
)
922 table
->opcode_rule
= table
->opcode_rule
->next
;
925 /* did we find anything */
926 if (table
->opcode
== NULL
) {
929 ASSERT(table
->opcode
!= NULL
);
931 /* back link what we found to its parent */
932 if (table
->parent
!= NULL
) {
933 ASSERT(table
->parent
->opcode
!= NULL
);
934 table
->opcode
->parent
= table
->parent
->opcode
;
937 /* expand the raw instructions according to the opcode */
940 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
) {
941 insn_table_insert_expanding(table
, entry
);
945 /* and do the same for the sub entries */
948 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
) {
949 insn_table_expand_insns(entry
);
956 model_table_insert(insn_table
*table
,
957 table_entry
*file_entry
)
959 /* create a new model */
960 model
*new_model
= ZALLOC(model
);
962 new_model
->name
= file_entry
->fields
[model_identifer
];
963 new_model
->printable_name
= file_entry
->fields
[model_name
];
964 new_model
->insn_default
= file_entry
->fields
[model_default
];
966 /* append it to the end of the model list */
968 last_model
->next
= new_model
;
971 last_model
= new_model
;
975 model_table_insert_specific(insn_table
*table
,
976 table_entry
*file_entry
,
980 insn
*ptr
= ZALLOC(insn
);
981 ptr
->file_entry
= file_entry
;
983 (*end_ptr
)->next
= ptr
;
992 insn_table_load_insns(char *file_name
)
994 table
*file
= table_open(file_name
, nr_insn_table_fields
, nr_insn_model_table_fields
);
995 insn_table
*table
= ZALLOC(insn_table
);
996 table_entry
*file_entry
;
997 table
->opcode_rule
= opcode_table
;
999 while ((file_entry
= table_entry_read(file
)) != NULL
) {
1000 if (it_is("function", file_entry
->fields
[insn_flags
])
1001 || it_is("internal", file_entry
->fields
[insn_flags
])) {
1002 insn_table_insert_function(table
, file_entry
);
1004 else if (it_is("model", file_entry
->fields
[insn_flags
])) {
1005 model_table_insert(table
, file_entry
);
1007 else if (it_is("model-macro", file_entry
->fields
[insn_flags
])) {
1008 model_table_insert_specific(table
, file_entry
, &model_macros
, &last_model_macro
);
1010 else if (it_is("model-function", file_entry
->fields
[insn_flags
])) {
1011 model_table_insert_specific(table
, file_entry
, &model_functions
, &last_model_function
);
1013 else if (it_is("model-internal", file_entry
->fields
[insn_flags
])) {
1014 model_table_insert_specific(table
, file_entry
, &model_internal
, &last_model_internal
);
1016 else if (it_is("model-data", file_entry
->fields
[insn_flags
])) {
1017 model_table_insert_specific(table
, file_entry
, &model_data
, &last_model_data
);
1020 insn_fields
*fields
;
1021 /* skip instructions that aren't relevant to the mode */
1022 filter
*filt
= filters
;
1023 while (filt
!= NULL
) {
1024 if (it_is(filt
->flag
, file_entry
->fields
[insn_flags
]))
1029 /* create/insert the new instruction */
1030 fields
= parse_insn_format(file_entry
,
1031 file_entry
->fields
[insn_format
]);
1032 insn_table_insert_insn(table
, file_entry
, fields
);
1041 dump_insn(insn
*entry
, int indent
, int levels
)
1043 printf("(insn*)%p\n", entry
);
1045 if (levels
&& entry
!= NULL
) {
1047 dumpf(indent
, "(file_entry ");
1048 dump_table_entry(entry
->file_entry
, indent
+1);
1049 dumpf(indent
, " )\n");
1051 dumpf(indent
, "(fields ");
1052 dump_insn_fields(entry
->fields
, indent
+1);
1053 dumpf(indent
, " )\n");
1055 dumpf(indent
, "(next ");
1056 dump_insn(entry
->next
, indent
+1, levels
-1);
1057 dumpf(indent
, " )\n");
1065 dump_insn_table(insn_table
*table
,
1066 int indent
, int levels
)
1069 printf("(insn_table*)%p\n", table
);
1071 if (levels
&& table
!= NULL
) {
1073 dumpf(indent
, "(opcode_nr %d)\n", table
->opcode_nr
);
1075 dumpf(indent
, "(expanded_bits ");
1076 dump_insn_bits(table
->expanded_bits
, indent
+1, -1);
1077 dumpf(indent
, " )\n");
1079 dumpf(indent
, "(int nr_insn %d)\n", table
->nr_insn
);
1081 dumpf(indent
, "(insns ");
1082 dump_insn(table
->insns
, indent
+1, table
->nr_insn
);
1083 dumpf(indent
, " )\n");
1085 dumpf(indent
, "(opcode_rule ");
1086 dump_opcode_rule(table
->opcode_rule
, indent
+1);
1087 dumpf(indent
, " )\n");
1089 dumpf(indent
, "(opcode ");
1090 dump_opcode_field(table
->opcode
, indent
+1, 1);
1091 dumpf(indent
, " )\n");
1093 dumpf(indent
, "(nr_entries %d)\n", table
->entries
);
1094 dumpf(indent
, "(entries ");
1095 dump_insn_table(table
->entries
, indent
+1, table
->nr_entries
);
1096 dumpf(indent
, " )\n");
1098 dumpf(indent
, "(sibling ", table
->sibling
);
1099 dump_insn_table(table
->sibling
, indent
+1, levels
-1);
1100 dumpf(indent
, " )\n");
1102 dumpf(indent
, "(parent ", table
->parent
);
1103 dump_insn_table(table
->parent
, indent
+1, 0);
1104 dumpf(indent
, " )\n");
1110 /****************************************************************/
1114 lf_print_insn_bits(lf
*file
, insn_bits
*bits
)
1118 lf_print_insn_bits(file
, bits
->last
);
1119 lf_putchr(file
, '_');
1120 lf_putstr(file
, bits
->field
->val_string
);
1121 if (!bits
->opcode
->is_boolean
|| bits
->value
== 0) {
1122 if (bits
->opcode
->last
< bits
->field
->last
)
1123 lf_putint(file
, bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1125 lf_putint(file
, bits
->value
);
1130 lf_print_opcodes(lf
*file
,
1133 if (table
!= NULL
) {
1135 lf_printf(file
, "_%d_%d",
1136 table
->opcode
->first
,
1137 table
->opcode
->last
);
1138 if (table
->parent
== NULL
) break;
1139 lf_printf(file
, "__%d", table
->opcode_nr
);
1140 table
= table
->parent
;
1146 lf_print_table_name(lf
*file
,
1149 lf_printf(file
, "idecode_table");
1150 lf_print_opcodes(file
, table
);
1156 function_name_prefix_semantics
,
1157 function_name_prefix_idecode
,
1158 function_name_prefix_itable
,
1159 function_name_prefix_none
1160 } lf_function_name_prefixes
;
1163 lf_print_function_name(lf
*file
,
1165 insn_bits
*expanded_bits
,
1166 lf_function_name_prefixes prefix
)
1171 case function_name_prefix_semantics
:
1172 lf_putstr(file
, "semantic_");
1174 case function_name_prefix_idecode
:
1175 lf_printf(file
, "idecode_");
1177 case function_name_prefix_itable
:
1178 lf_putstr(file
, "itable_");
1184 /* the function name */
1187 for (pos
= basename
;
1195 lf_putchr(file
, '_');
1198 lf_putchr(file
, *pos
);
1205 if (idecode_expand_semantics
)
1206 lf_print_insn_bits(file
, expanded_bits
);
1211 lf_print_idecode_table(lf
*file
,
1214 int can_assume_leaf
;
1215 opcode_rules
*opcode_rule
;
1217 /* have a look at the rule table, if all table rules follow all
1218 switch rules, I can assume that all end points are leaves */
1219 opcode_rule
= opcode_table
;
1220 while (opcode_rule
!= NULL
1221 && opcode_rule
->use_switch
)
1222 opcode_rule
= opcode_rule
->next
;
1223 while (opcode_rule
!= NULL
1224 && opcode_rule
->use_switch
1225 && opcode_rule
->special_rule
)
1226 opcode_rule
= opcode_rule
->next
;
1227 can_assume_leaf
= opcode_rule
== NULL
;
1229 lf_printf(file
, "{\n");
1230 lf_indent(file
, +2);
1232 lf_printf(file
, "idecode_table_entry *table = ");
1233 lf_print_table_name(file
, entry
);
1234 lf_printf(file
, ";\n");
1235 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1236 i2target(hi_bit_nr
, entry
->opcode
->first
),
1237 i2target(hi_bit_nr
, entry
->opcode
->last
));
1238 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
1239 lf_printf(file
, "while (1) {\n");
1240 lf_indent(file
, +2);
1242 lf_printf(file
, "/* nonzero mask -> another table */\n");
1243 lf_printf(file
, "while (table_entry->mask != 0) {\n");
1244 lf_indent(file
, +2);
1246 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1247 lf_printf(file
, " table_entry->function_or_table);\n");
1248 lf_printf(file
, "opcode = ((instruction & table_entry->mask)\n");
1249 lf_printf(file
, " >> table_entry->shift);\n");
1250 lf_printf(file
, "table_entry = table + opcode;\n");
1252 lf_indent(file
, -2);
1253 lf_printf(file
, "}\n");
1254 lf_printf(file
, "ASSERT(table_entry->mask == 0);\n");
1255 if (can_assume_leaf
)
1256 lf_printf(file
, "ASSERT(table_entry->shift == 0);\n");
1258 lf_printf(file
, "if (table_entry->shift == 0)\n");
1259 lf_indent(file
, +2);
1261 if (idecode_cache
) {
1262 lf_printf(file
, "return (((idecode_crack*)\n");
1263 lf_printf(file
, " table_entry->function_or_table)\n");
1264 lf_printf(file
, " (%s));\n", cache_idecode_actual
);
1267 lf_printf(file
, "return (((idecode_semantic*)\n");
1268 lf_printf(file
, " table_entry->function_or_table)\n");
1269 lf_printf(file
, " (%s));\n", semantic_actual
);
1271 if (!can_assume_leaf
) {
1272 lf_indent(file
, -2);
1273 lf_printf(file
, "/* must be a boolean */\n");
1274 lf_printf(file
, "opcode = (instruction & table_entry->shift) != 0;\n");
1275 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1276 lf_printf(file
, " table_entry->function_or_table);\n");
1277 lf_printf(file
, "table_entry = table + opcode;\n");
1280 lf_indent(file
, -2);
1281 lf_printf(file
, "}\n");
1283 lf_indent(file
, -2);
1284 lf_printf(file
, "}\n");
1289 lf_print_my_prefix(lf
*file
,
1290 table_entry
*file_entry
,
1293 lf_printf(file
, "const char *const my_prefix = \n");
1294 lf_printf(file
, " \"%s:%s:%s:%d\";\n",
1295 filter_filename (file_entry
->file_name
),
1296 (idecode
? "idecode" : "semantics"),
1297 file_entry
->fields
[insn_name
],
1298 file_entry
->line_nr
);
1303 lf_print_ptrace(lf
*file
,
1306 lf_printf(file
, "\n");
1307 lf_printf(file
, "ITRACE(trace_%s, (\"\\n\"));\n",
1308 (idecode
? "idecode" : "semantics"));
1312 /****************************************************************/
1314 typedef void leaf_handler
1318 typedef void padding_handler
1326 insn_table_traverse_tree(insn_table
*table
,
1329 leaf_handler
*start
,
1332 padding_handler
*padding
)
1337 ASSERT(table
!= NULL
1338 && table
->opcode
!= NULL
1339 && table
->nr_entries
> 0
1340 && table
->entries
!= 0);
1342 if (start
!= NULL
&& depth
>= 0)
1343 start(table
, data
, depth
);
1345 for (entry_nr
= 0, entry
= table
->entries
;
1346 entry_nr
< (table
->opcode
->is_boolean
1348 : (1 << (table
->opcode
->last
- table
->opcode
->first
+ 1)));
1351 || (!table
->opcode
->is_boolean
1352 && entry_nr
< entry
->opcode_nr
)) {
1353 if (padding
!= NULL
&& depth
>= 0)
1354 padding(table
, data
, depth
, entry_nr
);
1357 ASSERT(entry
!= NULL
&& (entry
->opcode_nr
== entry_nr
1358 || table
->opcode
->is_boolean
));
1359 if (entry
->opcode
!= NULL
&& depth
!= 0) {
1360 insn_table_traverse_tree(entry
, data
, depth
+1,
1361 start
, leaf
, end
, padding
);
1363 else if (depth
>= 0) {
1365 leaf(entry
, data
, depth
);
1367 entry
= entry
->sibling
;
1370 if (end
!= NULL
&& depth
>= 0)
1371 end(table
, data
, depth
);
1375 typedef void function_handler
1378 table_entry
*function
);
1381 insn_table_traverse_function(insn_table
*table
,
1383 function_handler
*leaf
)
1386 for (function
= table
->functions
;
1388 function
= function
->next
) {
1389 leaf(table
, data
, function
->file_entry
);
1394 typedef void insn_handler
1400 insn_table_traverse_insn(insn_table
*table
,
1405 for (instruction
= table
->insns
;
1406 instruction
!= NULL
;
1407 instruction
= instruction
->next
) {
1408 leaf(table
, data
, instruction
);
1414 update_depth(insn_table
*entry
,
1418 int *max_depth
= (int*)data
;
1419 if (*max_depth
< depth
)
1425 insn_table_depth(insn_table
*table
)
1428 insn_table_traverse_tree(table
,
1439 /****************************************************************/
1442 dump_traverse_start(insn_table
*table
,
1446 dumpf(depth
*2, "(%d\n", table
->opcode_nr
);
1450 dump_traverse_leaf(insn_table
*entry
,
1454 ASSERT(entry
->nr_entries
== 0
1455 && entry
->nr_insn
== 1
1456 && entry
->opcode
== NULL
);
1457 dumpf(depth
*2, ".%d %s\n", entry
->opcode_nr
,
1458 entry
->insns
->file_entry
->fields
[insn_format
]);
1462 dump_traverse_end(insn_table
*table
,
1466 dumpf(depth
*2, ")\n");
1470 dump_traverse_padding(insn_table
*table
,
1475 dumpf(depth
*2, ".<%d>\n", opcode_nr
);
1480 dump_traverse(insn_table
*table
)
1482 insn_table_traverse_tree(table
, NULL
, 1,
1483 dump_traverse_start
,
1486 dump_traverse_padding
);
1490 /****************************************************************/
1494 lf_print_semantic_function_header(lf
*file
,
1496 insn_bits
*expanded_bits
,
1497 int is_function_definition
,
1498 int is_inline_function
)
1500 lf_printf(file
, "\n");
1501 lf_printf(file
, "STATIC_SEMANTICS unsigned_word ");
1502 lf_print_function_name(file
,
1505 function_name_prefix_semantics
);
1506 lf_printf(file
, "\n(%s)",
1507 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
1508 if (!is_function_definition
)
1509 lf_printf(file
, ";");
1510 lf_printf(file
, "\n");
1515 semantics_h_leaf(insn_table
*entry
,
1519 lf
*file
= (lf
*)data
;
1520 ASSERT(entry
->nr_insn
== 1);
1521 lf_print_semantic_function_header(file
,
1522 entry
->insns
->file_entry
->fields
[insn_name
],
1523 entry
->expanded_bits
,
1524 0/* isnt function definition*/,
1525 !idecode_cache
&& entry
->parent
->opcode_rule
->use_switch
);
1529 semantics_h_insn(insn_table
*entry
,
1533 lf
*file
= (lf
*)data
;
1534 lf_print_semantic_function_header(file
,
1535 instruction
->file_entry
->fields
[insn_name
],
1537 0/*isnt function definition*/,
1538 0/*isnt inline function*/);
1542 semantics_h_function(insn_table
*entry
,
1544 table_entry
*function
)
1546 lf
*file
= (lf
*)data
;
1547 if (function
->fields
[function_type
] == NULL
1548 || function
->fields
[function_type
][0] == '\0') {
1549 lf_print_semantic_function_header(file
,
1550 function
->fields
[function_name
],
1552 0/*isnt function definition*/,
1553 1/*is inline function*/);
1556 lf_printf(file
, "\n");
1557 lf_printf(file
, "INLINE_SEMANTICS %s %s\n(%s);\n",
1558 function
->fields
[function_type
],
1559 function
->fields
[function_name
],
1560 function
->fields
[function_param
]);
1566 gen_semantics_h(insn_table
*table
, lf
*file
)
1569 lf_print_copyleft(file
);
1570 lf_printf(file
, "\n");
1571 lf_printf(file
, "#ifndef _SEMANTICS_H_\n");
1572 lf_printf(file
, "#define _SEMANTICS_H_\n");
1573 lf_printf(file
, "\n");
1574 lf_printf(file
, "#ifndef INLINE_SEMANTICS\n");
1575 lf_printf(file
, "#define INLINE_SEMANTICS\n");
1576 lf_printf(file
, "#endif\n");
1577 lf_printf(file
, "\n");
1578 lf_printf(file
, "#ifndef STATIC_SEMANTICS\n");
1579 lf_printf(file
, "#define STATIC_SEMANTICS\n");
1580 lf_printf(file
, "#endif\n");
1581 lf_printf(file
, "\n");
1582 lf_printf(file
, "\n");
1584 /* output a declaration for all functions */
1585 insn_table_traverse_function(table
,
1587 semantics_h_function
);
1589 /* output a declaration for all instructions */
1590 if (idecode_expand_semantics
)
1591 insn_table_traverse_tree(table
,
1595 semantics_h_leaf
, /* leaf */
1597 NULL
); /* padding */
1599 insn_table_traverse_insn(table
,
1603 lf_printf(file
, "\n");
1604 lf_printf(file
, "#endif /* _SEMANTICS_H_ */\n");
1608 /****************************************************************/
1610 typedef struct _icache_tree icache_tree
;
1611 struct _icache_tree
{
1614 icache_tree
*children
;
1617 static icache_tree
*
1618 icache_tree_insert(icache_tree
*tree
,
1621 icache_tree
*new_tree
;
1623 icache_tree
**ptr_to_cur_tree
= &tree
->children
;
1624 icache_tree
*cur_tree
= *ptr_to_cur_tree
;
1625 while (cur_tree
!= NULL
1626 && strcmp(cur_tree
->name
, name
) < 0) {
1627 ptr_to_cur_tree
= &cur_tree
->next
;
1628 cur_tree
= *ptr_to_cur_tree
;
1630 ASSERT(cur_tree
== NULL
1631 || strcmp(cur_tree
->name
, name
) >= 0);
1632 /* already in the tree */
1633 if (cur_tree
!= NULL
1634 && strcmp(cur_tree
->name
, name
) == 0)
1636 /* missing, insert it */
1637 ASSERT(cur_tree
== NULL
1638 || strcmp(cur_tree
->name
, name
) > 0);
1639 new_tree
= ZALLOC(icache_tree
);
1640 new_tree
->name
= name
;
1641 new_tree
->next
= cur_tree
;
1642 *ptr_to_cur_tree
= new_tree
;
1647 static icache_tree
*
1648 insn_table_cache_fields(insn_table
*table
)
1650 icache_tree
*tree
= ZALLOC(icache_tree
);
1652 for (instruction
= table
->insns
;
1653 instruction
!= NULL
;
1654 instruction
= instruction
->next
) {
1657 icache_tree_insert(tree
,
1658 instruction
->file_entry
->fields
[insn_form
]);
1659 for (field
= instruction
->fields
->first
;
1661 field
= field
->next
) {
1662 if (field
->is_string
)
1663 icache_tree_insert(form
, field
->val_string
);
1672 gen_icache_h(icache_tree
*tree
,
1675 lf_print_copyleft(file
);
1676 lf_printf(file
, "\n");
1677 lf_printf(file
, "#ifndef _ICACHE_H_\n");
1678 lf_printf(file
, "#define _ICACHE_H_\n");
1679 lf_printf(file
, "\n");
1680 lf_printf(file
, "#ifndef INLINE_ICACHE\n");
1681 lf_printf(file
, "#define INLINE_ICACHE\n");
1682 lf_printf(file
, "#endif\n");
1683 lf_printf(file
, "\n");
1685 lf_printf(file
, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1687 lf_printf(file
, "\n");
1689 /* create an instruction cache if being used */
1690 if (idecode_cache
) {
1692 lf_printf(file
, "typedef struct _idecode_cache {\n");
1693 lf_printf(file
, " unsigned_word address;\n");
1694 lf_printf(file
, " void *semantic;\n");
1695 lf_printf(file
, " union {\n");
1696 for (form
= tree
->children
;
1698 form
= form
->next
) {
1700 lf_printf(file
, " struct {\n");
1701 for (field
= form
->children
;
1703 field
= field
->next
) {
1704 cache_rules
*cache_rule
;
1706 for (cache_rule
= cache_table
;
1708 cache_rule
= cache_rule
->next
) {
1709 if (strcmp(field
->name
, cache_rule
->old_name
) == 0) {
1711 if (cache_rule
->new_name
!= NULL
)
1712 lf_printf(file
, " %s %s; /* %s */\n",
1713 (cache_rule
->type
== NULL
1715 : cache_rule
->type
),
1716 cache_rule
->new_name
,
1717 cache_rule
->old_name
);
1721 lf_printf(file
, " unsigned %s;\n", field
->name
);
1723 lf_printf(file
, " } %s;\n", form
->name
);
1725 lf_printf(file
, " } crack;\n");
1726 lf_printf(file
, "} idecode_cache;\n");
1729 /* alernativly, since no cache, #define the fields to be
1730 extractions from the instruction variable */
1731 cache_rules
*cache_rule
;
1732 lf_printf(file
, "\n");
1733 for (cache_rule
= cache_table
;
1735 cache_rule
= cache_rule
->next
) {
1736 if (cache_rule
->expression
!= NULL
1737 && strlen(cache_rule
->expression
) > 0)
1738 lf_printf(file
, "#define %s %s\n",
1739 cache_rule
->new_name
, cache_rule
->expression
);
1743 lf_printf(file
, "\n");
1744 lf_printf(file
, "#endif /* _ICACHE_H_ */\n");
1750 /****************************************************************/
1754 lf_print_c_extraction(lf
*file
,
1758 char *field_expression
,
1759 insn_field
*cur_field
,
1761 int get_value_from_cache
,
1762 int put_value_in_cache
)
1764 ASSERT(field_name
!= NULL
);
1766 && (!bits
->opcode
->is_boolean
|| bits
->value
== 0)
1767 && strcmp(field_name
, cur_field
->val_string
) == 0) {
1768 ASSERT(bits
->field
== cur_field
);
1769 ASSERT(field_type
== NULL
);
1770 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1771 lf_printf(file
, "const unsigned %s = ",
1773 if (bits
->opcode
->last
< bits
->field
->last
)
1774 lf_printf(file
, "%d;\n",
1775 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1777 lf_printf(file
, "%d;\n", bits
->value
);
1780 /* put the field in the local variable */
1781 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1782 lf_printf(file
, "%s const %s = ",
1783 field_type
== NULL
? "unsigned" : field_type
,
1785 /* getting it from the cache */
1786 if (get_value_from_cache
|| put_value_in_cache
) {
1787 lf_printf(file
, "cache_entry->crack.%s.%s",
1788 instruction
->file_entry
->fields
[insn_form
],
1790 if (put_value_in_cache
) /* also put it in the cache? */
1791 lf_printf(file
, " = ");
1793 if (!get_value_from_cache
) {
1794 if (strcmp(field_name
, cur_field
->val_string
) == 0)
1795 lf_printf(file
, "EXTRACTED32(instruction, %d, %d)",
1796 i2target(hi_bit_nr
, cur_field
->first
),
1797 i2target(hi_bit_nr
, cur_field
->last
));
1798 else if (field_expression
!= NULL
)
1799 lf_printf(file
, "%s", field_expression
);
1801 lf_printf(file
, "eval_%s", field_name
);
1803 lf_printf(file
, ";\n");
1809 lf_print_c_extractions(lf
*file
,
1811 insn_bits
*expanded_bits
,
1812 int get_value_from_cache
,
1813 int put_value_in_cache
)
1815 insn_field
*cur_field
;
1817 /* extract instruction fields */
1818 lf_printf(file
, "/* extraction: %s */\n",
1819 instruction
->file_entry
->fields
[insn_format
]);
1821 for (cur_field
= instruction
->fields
->first
;
1822 cur_field
->first
< insn_size
;
1823 cur_field
= cur_field
->next
) {
1824 if (cur_field
->is_string
) {
1827 /* find any corresponding value */
1828 for (bits
= expanded_bits
;
1830 bits
= bits
->last
) {
1831 if (bits
->field
== cur_field
)
1834 /* try the cache rule table for what to do */
1835 if (get_value_from_cache
|| put_value_in_cache
) {
1836 cache_rules
*cache_rule
;
1837 for (cache_rule
= cache_table
;
1839 cache_rule
= cache_rule
->next
) {
1840 if (strcmp(cur_field
->val_string
, cache_rule
->old_name
) == 0) {
1842 if (cache_rule
->valid
> 1 && put_value_in_cache
)
1843 lf_print_c_extraction(file
,
1845 cache_rule
->new_name
,
1847 cache_rule
->expression
,
1852 else if (cache_rule
->valid
== 1)
1853 lf_print_c_extraction(file
,
1855 cache_rule
->new_name
,
1857 cache_rule
->expression
,
1860 get_value_from_cache
,
1861 put_value_in_cache
);
1865 if (found_rule
== 0)
1866 lf_print_c_extraction(file
,
1868 cur_field
->val_string
,
1873 get_value_from_cache
,
1874 put_value_in_cache
);
1875 /* if any (XXX == 0), output a corresponding test */
1876 if (instruction
->file_entry
->annex
!= NULL
) {
1877 char *field_name
= cur_field
->val_string
;
1878 char *is_0_ptr
= instruction
->file_entry
->annex
;
1879 int field_len
= strlen(field_name
);
1880 if (strlen(is_0_ptr
) >= (strlen("_is_0") + field_len
)) {
1881 is_0_ptr
+= field_len
;
1882 while ((is_0_ptr
= strstr(is_0_ptr
, "_is_0")) != NULL
) {
1883 if (strncmp(is_0_ptr
- field_len
, field_name
, field_len
) == 0
1884 && !isalpha(is_0_ptr
[ - field_len
- 1])) {
1885 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1886 lf_printf(file
, "const unsigned %s_is_0 = (", field_name
);
1888 lf_printf(file
, "%d", bits
->value
);
1890 lf_printf(file
, "%s", field_name
);
1891 lf_printf(file
, " == 0);\n");
1894 is_0_ptr
+= strlen("_is_0");
1898 /* any thing else ... */
1901 lf_print_lf_c_line_nr(file
);
1906 lf_print_idecode_illegal(lf
*file
)
1909 lf_printf(file
, "return idecode_illegal(%s);\n", cache_idecode_actual
);
1911 lf_printf(file
, "return semantic_illegal(%s);\n", semantic_actual
);
1916 lf_print_idecode_floating_point_unavailable(lf
*file
)
1919 lf_printf(file
, "return idecode_floating_point_unavailable(%s);\n",
1920 cache_idecode_actual
);
1922 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
1927 /* Output code to do any final checks on the decoded instruction.
1928 This includes things like verifying any on decoded fields have the
1929 correct value and checking that (for floating point) floating point
1930 hardware isn't disabled */
1933 lf_print_c_validate(lf
*file
,
1935 opcode_field
*opcodes
)
1937 /* Validate: unchecked instruction fields
1939 If any constant fields in the instruction were not checked by the
1940 idecode tables, output code to check that they have the correct
1943 unsigned check_mask
= 0;
1944 unsigned check_val
= 0;
1946 opcode_field
*opcode
;
1948 /* form check_mask/check_val containing what needs to be checked
1949 in the instruction */
1950 for (field
= instruction
->fields
->first
;
1951 field
->first
< insn_size
;
1952 field
= field
->next
) {
1954 check_mask
<<= field
->width
;
1955 check_val
<<= field
->width
;
1957 /* is it a constant that could need validating? */
1958 if (!field
->is_int
&& !field
->is_slash
)
1961 /* has it been checked by a table? */
1962 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
1963 if (field
->first
>= opcode
->first
1964 && field
->last
<= opcode
->last
)
1970 check_mask
|= (1 << field
->width
)-1;
1971 check_val
|= field
->val_int
;
1974 /* if any bits not checked by opcode tables, output code to check them */
1976 lf_printf(file
, "\n");
1977 lf_printf(file
, "/* validate: %s */\n",
1978 instruction
->file_entry
->fields
[insn_format
]);
1979 lf_printf(file
, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
1980 check_mask
, check_val
);
1981 lf_indent(file
, +2);
1982 lf_print_idecode_illegal(file
);
1983 lf_indent(file
, -2);
1987 /* Validate floating point hardware
1989 If the simulator is being built with out floating point hardware
1990 (different to it being disabled in the MSR) then floating point
1991 instructions are invalid */
1993 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
1994 lf_printf(file
, "\n");
1995 lf_printf(file
, "/* Validate: FP hardware exists */\n");
1996 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
1997 lf_indent(file
, +2);
1998 lf_print_idecode_illegal(file
);
1999 lf_indent(file
, -2);
2003 /* Validate: Floating Point available
2005 If floating point is not available, we enter a floating point
2006 unavailable interrupt into the cache instead of the instruction
2009 The PowerPC spec requires a CSI after MSR[FP] is changed and when
2010 ever a CSI occures we flush the instruction cache. */
2013 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2014 lf_printf(file
, "\n");
2015 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
2016 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
2017 lf_indent(file
, +2);
2018 lf_print_idecode_floating_point_unavailable(file
);
2019 lf_indent(file
, -2);
2026 lf_print_c_cracker(lf
*file
,
2028 insn_bits
*expanded_bits
,
2029 opcode_field
*opcodes
)
2032 /* function header */
2033 lf_printf(file
, "{\n");
2034 lf_indent(file
, +2);
2036 lf_print_my_prefix(file
,
2037 instruction
->file_entry
,
2038 1/*putting-value-in-cache*/);
2040 lf_print_ptrace(file
,
2041 1/*putting-value-in-cache*/);
2043 lf_print_c_validate(file
, instruction
, opcodes
);
2045 lf_printf(file
, "\n");
2046 lf_printf(file
, "{\n");
2047 lf_indent(file
, +2);
2048 lf_print_c_extractions(file
,
2051 0/*get_value_from_cache*/,
2052 1/*put_value_in_cache*/);
2053 lf_indent(file
, -2);
2054 lf_printf(file
, "}\n");
2056 /* return the function propper (main sorts this one out) */
2057 lf_printf(file
, "\n");
2058 lf_printf(file
, "/* semantic routine */\n");
2059 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2060 lf_printf(file
, "return ");
2061 lf_print_function_name(file
,
2062 instruction
->file_entry
->fields
[insn_name
],
2064 function_name_prefix_semantics
);
2065 lf_printf(file
, ";\n");
2067 lf_print_lf_c_line_nr(file
);
2068 lf_indent(file
, -2);
2069 lf_printf(file
, "}\n");
2074 lf_print_c_semantic(lf
*file
,
2076 insn_bits
*expanded_bits
,
2077 opcode_field
*opcodes
)
2080 lf_printf(file
, "{\n");
2081 lf_indent(file
, +2);
2083 lf_print_my_prefix(file
,
2084 instruction
->file_entry
,
2085 0/*not putting value in cache*/);
2086 lf_printf(file
, "unsigned_word nia = cia + %d;\n", insn_size
/ 8);
2088 lf_printf(file
, "\n");
2089 lf_print_c_extractions(file
,
2092 idecode_cache
/*get_value_from_cache*/,
2093 0/*put_value_in_cache*/);
2095 lf_print_ptrace(file
,
2096 0/*put_value_in_cache*/);
2098 /* validate the instruction, if a cache this has already been done */
2100 lf_print_c_validate(file
, instruction
, opcodes
);
2102 /* generate the profileing call - this is delayed until after the
2103 instruction has been verified */
2104 lf_printf(file
, "\n");
2105 lf_printf(file
, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
2106 lf_printf(file
, " mon_issue(");
2107 lf_print_function_name(file
,
2108 instruction
->file_entry
->fields
[insn_name
],
2110 function_name_prefix_itable
);
2111 lf_printf(file
, ", processor, cia);\n");
2113 /* generate the code (or at least something */
2114 if (instruction
->file_entry
->annex
!= NULL
) {
2116 lf_printf(file
, "\n");
2117 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2118 lf_printf(file
, "{\n");
2119 lf_indent(file
, +2);
2120 lf_print_c_code(file
, instruction
->file_entry
->annex
);
2121 lf_indent(file
, -2);
2122 lf_printf(file
, "}\n");
2123 lf_print_lf_c_line_nr(file
);
2125 else if (it_is("nop", instruction
->file_entry
->fields
[insn_flags
])) {
2126 lf_print_lf_c_line_nr(file
);
2128 else if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2129 /* unimplemented floating point instruction - call for assistance */
2130 lf_printf(file
, "\n");
2131 lf_printf(file
, "/* unimplemented floating point instruction - call for assistance */\n");
2132 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2133 lf_putstr(file
, "floating_point_assist_interrupt(processor, cia);\n");
2134 lf_print_lf_c_line_nr(file
);
2137 /* abort so it is implemented now */
2138 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2139 lf_putstr(file
, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2140 lf_print_lf_c_line_nr(file
);
2141 lf_printf(file
, "\n");
2144 /* the function footer */
2145 lf_printf(file
, "return nia;\n");
2146 lf_indent(file
, -2);
2147 lf_printf(file
, "}\n");
2151 lf_print_c_semantic_function(lf
*file
,
2153 insn_bits
*expanded_bits
,
2154 opcode_field
*opcodes
,
2155 int is_inline_function
)
2158 /* build the semantic routine to execute the instruction */
2159 lf_print_semantic_function_header(file
,
2160 instruction
->file_entry
->fields
[insn_name
],
2162 1/*is-function-definition*/,
2163 is_inline_function
);
2164 lf_print_c_semantic(file
,
2172 semantics_c_leaf(insn_table
*entry
,
2176 lf
*file
= (lf
*)data
;
2177 ASSERT(entry
->nr_insn
== 1
2178 && entry
->opcode
== NULL
2179 && entry
->parent
!= NULL
2180 && entry
->parent
->opcode
!= NULL
);
2181 lf_print_c_semantic_function(file
,
2183 entry
->expanded_bits
,
2184 entry
->parent
->opcode
,
2185 !idecode_cache
&& entry
->parent
->opcode_rule
->use_switch
);
2189 semantics_c_insn(insn_table
*table
,
2193 lf
*file
= (lf
*)data
;
2194 lf_print_c_semantic_function(file
, instruction
,
2196 0/*isnt_inline_function*/);
2200 semantics_c_function(insn_table
*table
,
2202 table_entry
*function
)
2204 lf
*file
= (lf
*)data
;
2205 if (function
->fields
[function_type
] == NULL
2206 || function
->fields
[function_type
][0] == '\0') {
2207 lf_print_semantic_function_header(file
,
2208 function
->fields
[function_name
],
2210 1/*is function definition*/,
2211 1/*is inline function*/);
2214 lf_printf(file
, "\n");
2215 lf_printf(file
, "INLINE_SEMANTICS %s\n%s(%s)\n",
2216 function
->fields
[function_type
],
2217 function
->fields
[function_name
],
2218 function
->fields
[function_param
]);
2220 table_entry_lf_c_line_nr(file
, function
);
2221 lf_printf(file
, "{\n");
2222 lf_indent(file
, +2);
2223 lf_print_c_code(file
, function
->annex
);
2224 lf_indent(file
, -2);
2225 lf_printf(file
, "}\n");
2226 lf_print_lf_c_line_nr(file
);
2232 gen_semantics_c(insn_table
*table
, lf
*file
)
2234 lf_print_copyleft(file
);
2235 lf_printf(file
, "\n");
2236 lf_printf(file
, "#ifndef _SEMANTICS_C_\n");
2237 lf_printf(file
, "#define _SEMANTICS_C_\n");
2238 lf_printf(file
, "\n");
2239 lf_printf(file
, "#ifndef STATIC_INLINE_SEMANTICS\n");
2240 lf_printf(file
, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2241 lf_printf(file
, "#endif\n");
2242 lf_printf(file
, "\n");
2243 lf_printf(file
, "#include \"cpu.h\"\n");
2244 lf_printf(file
, "#include \"idecode.h\"\n");
2245 lf_printf(file
, "#include \"semantics.h\"\n");
2246 lf_printf(file
, "\n");
2248 /* output a definition (c-code) for all functions */
2249 insn_table_traverse_function(table
,
2251 semantics_c_function
);
2253 /* output a definition (c-code) for all instructions */
2254 if (idecode_expand_semantics
)
2255 insn_table_traverse_tree(table
,
2261 NULL
); /* padding */
2263 insn_table_traverse_insn(table
,
2267 lf_printf(file
, "\n");
2268 lf_printf(file
, "#endif /* _SEMANTICS_C_ */\n");
2272 /****************************************************************/
2275 gen_idecode_h(insn_table
*table
, lf
*file
)
2277 lf_print_copyleft(file
);
2278 lf_printf(file
, "\n");
2279 lf_printf(file
, "#ifndef _IDECODE_H_\n");
2280 lf_printf(file
, "#define _IDECODE_H_\n");
2281 lf_printf(file
, "\n");
2282 lf_printf(file
, "#ifndef INLINE_IDECODE\n");
2283 lf_printf(file
, "#define INLINE_IDECODE\n");
2284 lf_printf(file
, "#endif\n");
2285 lf_printf(file
, "\n");
2286 lf_printf(file
, "#include \"idecode_expression.h\"\n");
2287 lf_printf(file
, "#include \"idecode_fields.h\"\n");
2288 lf_printf(file
, "#include \"idecode_branch.h\"\n");
2289 lf_printf(file
, "\n");
2290 lf_printf(file
, "#include \"icache.h\"\n");
2291 lf_printf(file
, "\n");
2292 lf_printf(file
, "typedef unsigned_word idecode_semantic\n(%s);\n",
2293 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2294 lf_printf(file
, "\n");
2296 lf_printf(file
, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2297 cache_idecode_formal
);
2299 lf_printf(file
, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2301 lf_printf(file
, "\n");
2302 lf_printf(file
, "#endif /* _IDECODE_H_ */\n");
2306 /****************************************************************/
2310 idecode_table_start(insn_table
*table
,
2314 lf
*file
= (lf
*)data
;
2316 /* start of the table */
2317 if (!table
->opcode_rule
->use_switch
) {
2318 lf_printf(file
, "\n");
2319 lf_printf(file
, "static idecode_table_entry ");
2320 lf_print_table_name(file
, table
);
2321 lf_printf(file
, "[] = {\n");
2326 idecode_table_leaf(insn_table
*entry
,
2330 lf
*file
= (lf
*)data
;
2331 ASSERT(entry
->parent
!= NULL
);
2334 /* add an entry to the table */
2335 if (!entry
->parent
->opcode_rule
->use_switch
) {
2336 if (entry
->opcode
== NULL
) {
2337 /* table leaf entry */
2338 lf_printf(file
, " /*%d*/ { 0, 0, ", entry
->opcode_nr
);
2339 lf_print_function_name(file
,
2340 entry
->insns
->file_entry
->fields
[insn_name
],
2341 entry
->expanded_bits
,
2343 ? function_name_prefix_idecode
2344 : function_name_prefix_semantics
));
2345 lf_printf(file
, " },\n");
2347 else if (entry
->opcode_rule
->use_switch
) {
2348 /* table calling switch statement */
2349 lf_printf(file
, " /*%d*/ { 0, 0, ",
2351 lf_print_table_name(file
, entry
);
2352 lf_printf(file
, " },\n");
2355 /* table `calling' another table */
2356 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
2357 if (entry
->opcode
->is_boolean
)
2358 lf_printf(file
, "MASK32(%d,%d), 0, ",
2359 i2target(hi_bit_nr
, entry
->opcode
->first
),
2360 i2target(hi_bit_nr
, entry
->opcode
->last
));
2362 lf_printf(file
, "%d, MASK32(%d,%d), ",
2363 insn_size
- entry
->opcode
->last
- 1,
2364 i2target(hi_bit_nr
, entry
->opcode
->first
),
2365 i2target(hi_bit_nr
, entry
->opcode
->last
));
2366 lf_print_table_name(file
, entry
);
2367 lf_printf(file
, " },\n");
2373 idecode_table_end(insn_table
*table
,
2377 lf
*file
= (lf
*)data
;
2380 if (!table
->opcode_rule
->use_switch
) {
2381 lf_printf(file
, "};\n");
2386 idecode_table_padding(insn_table
*table
,
2391 lf
*file
= (lf
*)data
;
2394 if (!table
->opcode_rule
->use_switch
) {
2395 lf_printf(file
, " /*%d*/ { 0, 0, %s_illegal },\n",
2396 opcode_nr
, (idecode_cache
? "idecode" : "semantic"));
2401 /****************************************************************/
2404 void lf_print_idecode_switch
2410 idecode_switch_start(insn_table
*table
,
2414 lf
*file
= (lf
*)data
;
2416 ASSERT(table
->opcode_rule
->use_switch
);
2418 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2419 i2target(hi_bit_nr
, table
->opcode
->first
),
2420 i2target(hi_bit_nr
, table
->opcode
->last
));
2425 idecode_switch_leaf(insn_table
*entry
,
2429 lf
*file
= (lf
*)data
;
2430 ASSERT(entry
->parent
!= NULL
);
2432 ASSERT(entry
->parent
->opcode_rule
->use_switch
);
2433 ASSERT(entry
->parent
->opcode
);
2435 if (!entry
->parent
->opcode
->is_boolean
2436 || entry
->opcode_nr
== 0)
2437 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
2439 lf_printf(file
, "default:\n");
2440 lf_indent(file
, +2);
2442 if (entry
->opcode
== NULL
) {
2443 /* switch calling leaf */
2444 lf_printf(file
, "return ");
2445 lf_print_function_name(file
,
2446 entry
->insns
->file_entry
->fields
[insn_name
],
2447 entry
->expanded_bits
,
2449 ? function_name_prefix_idecode
2450 : function_name_prefix_semantics
));
2452 lf_printf(file
, "(%s);\n", cache_idecode_actual
);
2454 lf_printf(file
, "(%s);\n", semantic_actual
);
2456 else if (entry
->opcode_rule
->use_switch
) {
2457 /* switch calling switch */
2458 lf_print_idecode_switch(file
, entry
);
2461 /* switch looking up a table */
2462 lf_print_idecode_table(file
, entry
);
2464 lf_printf(file
, "break;\n");
2466 lf_indent(file
, -2);
2471 lf_print_idecode_switch_illegal(lf
*file
)
2473 lf_indent(file
, +2);
2474 lf_print_idecode_illegal(file
);
2475 lf_printf(file
, "break;\n");
2476 lf_indent(file
, -2);
2480 idecode_switch_end(insn_table
*table
,
2484 lf
*file
= (lf
*)data
;
2486 ASSERT(table
->opcode_rule
->use_switch
);
2487 ASSERT(table
->opcode
);
2489 if (table
->opcode_rule
->use_switch
== 1
2490 && !table
->opcode
->is_boolean
) {
2491 lf_printf(file
, "default:\n");
2492 lf_print_idecode_switch_illegal(file
);
2494 lf_printf(file
, "}\n");
2498 idecode_switch_padding(insn_table
*table
,
2503 lf
*file
= (lf
*)data
;
2506 ASSERT(table
->opcode_rule
->use_switch
);
2508 if (table
->opcode_rule
->use_switch
> 1) {
2509 lf_printf(file
, "case %d:\n", opcode_nr
);
2510 lf_print_idecode_switch_illegal(file
);
2516 lf_print_idecode_switch(lf
*file
,
2519 insn_table_traverse_tree(table
,
2522 idecode_switch_start
,
2523 idecode_switch_leaf
,
2525 idecode_switch_padding
);
2530 lf_print_idecode_switch_function_header(lf
*file
,
2532 int is_function_definition
)
2534 lf_printf(file
, "\n");
2535 lf_printf(file
, "static ");
2537 lf_printf(file
, "idecode_semantic *");
2539 lf_printf(file
, "unsigned_word");
2540 if (is_function_definition
)
2541 lf_printf(file
, "\n");
2543 lf_printf(file
, " ");
2544 lf_print_table_name(file
, table
);
2545 lf_printf(file
, "\n(%s)",
2546 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2547 if (!is_function_definition
)
2548 lf_printf(file
, ";");
2549 lf_printf(file
, "\n");
2554 idecode_declare_if_switch(insn_table
*table
,
2558 lf
*file
= (lf
*)data
;
2560 if (table
->opcode_rule
->use_switch
2561 && table
->parent
!= NULL
/* don't declare the top one yet */
2562 && !table
->parent
->opcode_rule
->use_switch
) {
2563 lf_print_idecode_switch_function_header(file
,
2565 0/*isnt function definition*/);
2571 idecode_expand_if_switch(insn_table
*table
,
2575 lf
*file
= (lf
*)data
;
2577 if (table
->opcode_rule
->use_switch
2578 && table
->parent
!= NULL
/* don't expand the top one yet */
2579 && !table
->parent
->opcode_rule
->use_switch
) {
2580 lf_print_idecode_switch_function_header(file
,
2582 1/*is function definition*/);
2583 lf_printf(file
, "{\n");
2585 lf_indent(file
, +2);
2586 lf_print_idecode_switch(file
, table
);
2587 lf_indent(file
, -2);
2589 lf_printf(file
, "}\n");
2595 lf_print_c_cracker_function(lf
*file
,
2597 insn_bits
*expanded_bits
,
2598 opcode_field
*opcodes
,
2599 int is_inline_function
)
2601 /* if needed, generate code to enter this routine into a cache */
2602 lf_printf(file
, "\n");
2603 lf_printf(file
, "STATIC_IDECODE idecode_semantic *\n");
2604 lf_print_function_name(file
,
2605 instruction
->file_entry
->fields
[insn_name
],
2607 function_name_prefix_idecode
);
2608 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2610 lf_print_c_cracker(file
,
2617 idecode_crack_leaf(insn_table
*entry
,
2621 lf
*file
= (lf
*)data
;
2622 ASSERT(entry
->nr_insn
== 1
2623 && entry
->opcode
== NULL
2624 && entry
->parent
!= NULL
2625 && entry
->parent
->opcode
!= NULL
2626 && entry
->parent
->opcode_rule
!= NULL
);
2627 lf_print_c_cracker_function(file
,
2629 entry
->expanded_bits
,
2631 entry
->parent
->opcode_rule
->use_switch
);
2635 idecode_crack_insn(insn_table
*entry
,
2639 lf
*file
= (lf
*)data
;
2640 lf_print_c_cracker_function(file
,
2644 0/*isnt inline function*/);
2648 idecode_c_internal_function(insn_table
*table
,
2650 table_entry
*function
)
2652 lf
*file
= (lf
*)data
;
2653 ASSERT(idecode_cache
!= 0);
2654 if (it_is("internal", function
->fields
[insn_flags
])) {
2655 lf_printf(file
, "\n");
2656 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2657 lf_print_function_name(file
,
2658 function
->fields
[insn_name
],
2660 function_name_prefix_idecode
);
2661 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2662 lf_printf(file
, "{\n");
2663 lf_indent(file
, +2);
2664 lf_printf(file
, "/* semantic routine */\n");
2665 table_entry_lf_c_line_nr(file
, function
);
2666 lf_printf(file
, "return ");
2667 lf_print_function_name(file
,
2668 function
->fields
[insn_name
],
2670 function_name_prefix_semantics
);
2671 lf_printf(file
, ";\n");
2673 lf_print_lf_c_line_nr(file
);
2674 lf_indent(file
, -2);
2675 lf_printf(file
, "}\n");
2680 /****************************************************************/
2683 gen_idecode_c(insn_table
*table
, lf
*file
)
2688 lf_print_copyleft(file
);
2689 lf_printf(file
, "\n");
2690 lf_printf(file
, "\n");
2691 lf_printf(file
, "#ifndef _IDECODE_C_\n");
2692 lf_printf(file
, "#define _IDECODE_C_\n");
2693 lf_printf(file
, "\n");
2694 lf_printf(file
, "#ifndef STATIC_INLINE_IDECODE\n");
2695 lf_printf(file
, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2696 lf_printf(file
, "#endif\n");
2697 lf_printf(file
, "\n");
2698 lf_printf(file
, "#ifndef STATIC_IDECODE\n");
2699 lf_printf(file
, "#define STATIC_IDECODE\n");
2700 lf_printf(file
, "#endif\n");
2701 lf_printf(file
, "\n");
2702 lf_printf(file
, "#include \"cpu.h\"\n");
2703 lf_printf(file
, "#include \"idecode.h\"\n");
2704 lf_printf(file
, "#include \"semantics.h\"\n");
2705 lf_printf(file
, "\n");
2706 lf_printf(file
, "\n");
2707 lf_printf(file
, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2708 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2709 lf_printf(file
, "\n");
2710 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
2711 lf_printf(file
, " unsigned shift;\n");
2712 lf_printf(file
, " unsigned mask;\n");
2713 lf_printf(file
, " void *function_or_table;\n");
2714 lf_printf(file
, "} idecode_table_entry;\n");
2715 lf_printf(file
, "\n");
2716 lf_printf(file
, "\n");
2718 /* output `internal' invalid/floating-point unavailable functions
2720 if (idecode_cache
) {
2721 insn_table_traverse_function(table
,
2723 idecode_c_internal_function
);
2726 /* output cracking functions where needed */
2727 if (idecode_cache
) {
2728 if (idecode_expand_semantics
)
2729 insn_table_traverse_tree(table
,
2737 insn_table_traverse_insn(table
,
2739 idecode_crack_insn
);
2742 /* output switch function declarations where needed by tables */
2743 insn_table_traverse_tree(table
,
2746 idecode_declare_if_switch
, /* START */
2749 /* output tables where needed */
2750 for (depth
= insn_table_depth(table
);
2753 insn_table_traverse_tree(table
,
2756 idecode_table_start
,
2759 idecode_table_padding
);
2762 /* output switch functions where needed */
2763 insn_table_traverse_tree(table
,
2766 idecode_expand_if_switch
, /* START */
2769 /* output the main idecode routine */
2770 lf_printf(file
, "\n");
2772 lf_printf(file
, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2773 cache_idecode_formal
);
2775 lf_printf(file
, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2777 lf_printf(file
, "{\n");
2778 lf_indent(file
, +2);
2779 if (table
->opcode_rule
->use_switch
)
2780 lf_print_idecode_switch(file
, table
);
2782 lf_print_idecode_table(file
, table
);
2783 lf_indent(file
, -2);
2784 lf_printf(file
, "}\n");
2785 lf_printf(file
, "\n");
2786 lf_printf(file
, "#endif /* _IDECODE_C_ */\n");
2790 /****************************************************************/
2793 itable_h_insn(insn_table
*entry
,
2797 lf
*file
= (lf
*)data
;
2798 lf_printf(file
, " ");
2799 lf_print_function_name(file
,
2800 instruction
->file_entry
->fields
[insn_name
],
2802 function_name_prefix_itable
);
2803 lf_printf(file
, ",\n");
2808 gen_itable_h(insn_table
*table
, lf
*file
)
2811 lf_print_copyleft(file
);
2812 lf_printf(file
, "\n");
2813 lf_printf(file
, "#ifndef _ITABLE_H_\n");
2814 lf_printf(file
, "#define _ITABLE_H_\n");
2815 lf_printf(file
, "\n");
2816 lf_printf(file
, "#ifndef INLINE_ITABLE\n");
2817 lf_printf(file
, "#define INLINE_ITABLE\n");
2818 lf_printf(file
, "#endif\n");
2819 lf_printf(file
, "\n");
2820 lf_printf(file
, "\n");
2822 /* output an enumerated type for each instruction */
2823 lf_printf(file
, "typedef enum {\n");
2824 insn_table_traverse_insn(table
,
2827 lf_printf(file
, " nr_itable_entries,\n");
2828 lf_printf(file
, "} itable_index;\n");
2829 lf_printf(file
, "\n");
2831 /* output the table that contains the actual instruction info */
2832 lf_printf(file
, "typedef struct _itable_instruction_info {\n");
2833 lf_printf(file
, " itable_index nr;\n");
2834 lf_printf(file
, " char *format;\n");
2835 lf_printf(file
, " char *form;\n");
2836 lf_printf(file
, " char *flags;\n");
2837 lf_printf(file
, " char *mnemonic;\n");
2838 lf_printf(file
, " char *name;\n");
2839 lf_printf(file
, "} itable_info;\n");
2840 lf_printf(file
, "\n");
2841 lf_printf(file
, "extern itable_info itable[nr_itable_entries];\n");
2843 lf_printf(file
, "\n");
2844 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2848 /****************************************************************/
2851 itable_c_insn(insn_table
*entry
,
2855 lf
*file
= (lf
*)data
;
2856 char **fields
= instruction
->file_entry
->fields
;
2857 lf_printf(file
, " { ");
2858 lf_print_function_name(file
,
2859 instruction
->file_entry
->fields
[insn_name
],
2861 function_name_prefix_itable
);
2862 lf_printf(file
, ",\n");
2863 lf_printf(file
, " \"%s\",\n", fields
[insn_format
]);
2864 lf_printf(file
, " \"%s\",\n", fields
[insn_form
]);
2865 lf_printf(file
, " \"%s\",\n", fields
[insn_flags
]);
2866 lf_printf(file
, " \"%s\",\n", fields
[insn_mnemonic
]);
2867 lf_printf(file
, " \"%s\",\n", fields
[insn_name
]);
2868 lf_printf(file
, " },\n");
2873 gen_itable_c(insn_table
*table
, lf
*file
)
2876 lf_print_copyleft(file
);
2877 lf_printf(file
, "\n");
2878 lf_printf(file
, "#ifndef _ITABLE_C_\n");
2879 lf_printf(file
, "#define _ITABLE_C_\n");
2880 lf_printf(file
, "\n");
2881 lf_printf(file
, "#ifndef STATIC_INLINE_ITABLE\n");
2882 lf_printf(file
, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
2883 lf_printf(file
, "#endif\n");
2884 lf_printf(file
, "\n");
2885 lf_printf(file
, "#include \"itable.h\"\n");
2886 lf_printf(file
, "\n");
2888 /* output the table that contains the actual instruction info */
2889 lf_printf(file
, "itable_info itable[nr_itable_entries] = {\n");
2890 insn_table_traverse_insn(table
,
2893 lf_printf(file
, "};\n");
2894 lf_printf(file
, "\n");
2896 lf_printf(file
, "\n");
2897 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2900 /****************************************************************/
2903 model_c_or_h_data(insn_table
*table
,
2908 table_entry_lf_c_line_nr(file
, data
);
2909 lf_print_c_code(file
, data
->annex
);
2910 lf_print_lf_c_line_nr(file
);
2911 lf_printf(file
, "\n");
2916 model_c_or_h_function(insn_table
*entry
,
2918 table_entry
*function
,
2921 if (function
->fields
[function_type
] == NULL
2922 || function
->fields
[function_type
][0] == '\0') {
2923 error("Model function type not specified for %s", function
->fields
[function_name
]);
2926 lf_printf(file
, "\n");
2927 lf_printf(file
, "%s %s %s\n(%s);\n",
2929 function
->fields
[function_type
],
2930 function
->fields
[function_name
],
2931 function
->fields
[function_param
]);
2933 lf_printf(file
, "\n");
2937 gen_model_h(insn_table
*table
, lf
*file
)
2943 int model_create_p
= 0;
2944 int model_init_p
= 0;
2945 int model_halt_p
= 0;
2946 int model_issue_p
= 0;
2947 int model_mon_info_p
= 0;
2948 int model_mon_info_free_p
= 0;
2950 lf_print_copyleft(file
);
2951 lf_printf(file
, "\n");
2952 lf_printf(file
, "#ifndef _MODEL_H_\n");
2953 lf_printf(file
, "#define _MODEL_H_\n");
2954 lf_printf(file
, "\n");
2956 for(macro
= model_macros
; macro
; macro
= macro
->next
) {
2957 model_c_or_h_data(table
, file
, macro
->file_entry
);
2960 lf_printf(file
, "#ifndef INLINE_MODEL\n");
2961 lf_printf(file
, "#define INLINE_MODEL\n");
2962 lf_printf(file
, "#endif\n");
2963 lf_printf(file
, "#ifndef STATIC_INLINE_MODEL\n");
2964 lf_printf(file
, "#define STATIC_INLINE_MODEL STATIC_INLINE\n");
2965 lf_printf(file
, "#endif\n");
2966 lf_printf(file
, "\n");
2967 lf_printf(file
, "#ifndef STATIC_MODEL\n");
2968 lf_printf(file
, "#define STATIC_MODEL\n");
2969 lf_printf(file
, "#endif\n");
2970 lf_printf(file
, "\n");
2971 lf_printf(file
, "#ifndef EXTERN_MODEL\n");
2972 lf_printf(file
, "#define EXTERN_MODEL extern\n");
2973 lf_printf(file
, "#endif\n");
2974 lf_printf(file
, "\n");
2976 lf_printf(file
, "typedef enum _model_enum {\n");
2977 lf_printf(file
, " MODEL_NONE,\n");
2978 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
2979 lf_printf(file
, " MODEL_%s,\n", model_ptr
->name
);
2981 lf_printf(file
, " nr_models\n");
2982 lf_printf(file
, "} model_enum;\n");
2983 lf_printf(file
, "\n");
2985 lf_printf(file
, "#define DEFAULT_MODEL MODEL_%s\n", (models
) ? models
->name
: "NONE");
2986 lf_printf(file
, "\n");
2988 lf_printf(file
, "typedef struct _model_data model_data;\n");
2989 lf_printf(file
, "typedef struct _model_time model_time;\n");
2990 lf_printf(file
, "\n");
2992 lf_printf(file
, "extern model_enum current_model;\n");
2993 lf_printf(file
, "EXTERN_MODEL const char *model_name[ (int)nr_models ];\n");
2994 lf_printf(file
, "EXTERN_MODEL const char *const *const model_func_unit_name[ (int)nr_models ];\n");
2995 lf_printf(file
, "EXTERN_MODEL const model_time *const model_time_mapping[ (int)nr_models ];\n");
2996 lf_printf(file
, "\n");
2998 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
2999 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3000 name
= insn_ptr
->file_entry
->fields
[function_name
];
3001 if (strcmp (name
, "model_create") == 0)
3003 else if (strcmp (name
, "model_init") == 0)
3005 else if (strcmp (name
, "model_halt") == 0)
3007 else if (strcmp (name
, "model_issue") == 0)
3009 else if (strcmp (name
, "model_mon_info") == 0)
3010 model_mon_info_p
= 1;
3011 else if (strcmp (name
, "model_mon_info_free") == 0)
3012 model_mon_info_free_p
= 1;
3015 if (!model_create_p
) {
3016 lf_printf(file
, "INLINE_MODEL model_data *model_create\n");
3017 lf_printf(file
, "(cpu *processor);\n");
3018 lf_printf(file
, "\n");
3021 if (!model_init_p
) {
3022 lf_printf(file
, "INLINE_MODEL void model_init\n");
3023 lf_printf(file
, "(cpu *processor,\n");
3024 lf_printf(file
, " model_data *model_ptr);\n");
3025 lf_printf(file
, "\n");
3028 if (!model_halt_p
) {
3029 lf_printf(file
, "INLINE_MODEL void model_halt\n");
3030 lf_printf(file
, "(cpu *processor,\n");
3031 lf_printf(file
, " model_data *model_ptr);\n");
3032 lf_printf(file
, "\n");
3035 if (!model_issue_p
) {
3036 lf_printf(file
, "INLINE_MODEL void model_issue\n");
3037 lf_printf(file
, "(itable_index index,\n");
3038 lf_printf(file
, " model_data *model_ptr,\n");
3039 lf_printf(file
, " unsigned_word cia);\n");
3040 lf_printf(file
, "\n");
3043 if (!model_mon_info_p
) {
3044 lf_printf(file
, "INLINE_MODEL model_print *model_mon_info\n");
3045 lf_printf(file
, "(model_data *model_ptr);\n");
3046 lf_printf(file
, "\n");
3049 if (!model_mon_info_free_p
) {
3050 lf_printf(file
, "INLINE_MODEL void model_mon_info_free\n");
3051 lf_printf(file
, "(model_data *model_ptr,\n");
3052 lf_printf(file
, " model_print *info_ptr);\n");
3053 lf_printf(file
, "\n");
3056 lf_printf(file
, "INLINE_MODEL void model_set\n");
3057 lf_printf(file
, "(const char *name);\n");
3058 lf_printf(file
, "\n");
3059 lf_printf(file
, "#endif /* _MODEL_H_ */\n");
3062 /****************************************************************/
3064 typedef struct _model_c_passed_data model_c_passed_data
;
3065 struct _model_c_passed_data
{
3071 model_c_insn(insn_table
*entry
,
3075 model_c_passed_data
*data_ptr
= (model_c_passed_data
*)data
;
3076 lf
*file
= data_ptr
->file
;
3077 char *current_name
= data_ptr
->model_ptr
->printable_name
;
3078 table_model_entry
*model_ptr
= instruction
->file_entry
->model_first
;
3081 if (model_ptr
->fields
[insn_model_name
] == current_name
) {
3082 lf_printf(file
, " { %-48s },\t/* %s */\n",
3083 model_ptr
->fields
[insn_model_fields
],
3084 instruction
->file_entry
->fields
[insn_name
]);
3088 model_ptr
= model_ptr
->next
;
3091 lf_printf(file
, " { %-48s },\t/* %s */\n",
3092 data_ptr
->model_ptr
->insn_default
,
3093 instruction
->file_entry
->fields
[insn_name
]);
3097 model_c_function(insn_table
*table
,
3099 table_entry
*function
,
3102 if (function
->fields
[function_type
] == NULL
3103 || function
->fields
[function_type
][0] == '\0') {
3104 error("Model function return type not specified for %s", function
->fields
[function_name
]);
3107 lf_printf(file
, "\n");
3108 lf_printf(file
, "%s %s\n%s(%s)\n",
3110 function
->fields
[function_type
],
3111 function
->fields
[function_name
],
3112 function
->fields
[function_param
]);
3114 table_entry_lf_c_line_nr(file
, function
);
3115 lf_printf(file
, "{\n");
3116 if (function
->annex
) {
3117 lf_indent(file
, +2);
3118 lf_print_c_code(file
, function
->annex
);
3119 lf_indent(file
, -2);
3121 lf_printf(file
, "}\n");
3122 lf_print_lf_c_line_nr(file
);
3123 lf_printf(file
, "\n");
3127 gen_model_c(insn_table
*table
, lf
*file
)
3132 int model_create_p
= 0;
3133 int model_init_p
= 0;
3134 int model_halt_p
= 0;
3135 int model_issue_p
= 0;
3136 int model_mon_info_p
= 0;
3137 int model_mon_info_free_p
= 0;
3139 lf_print_copyleft(file
);
3140 lf_printf(file
, "\n");
3141 lf_printf(file
, "#ifndef _MODEL_C_\n");
3142 lf_printf(file
, "#define _MODEL_C_\n");
3143 lf_printf(file
, "\n");
3144 lf_printf(file
, "#include \"cpu.h\"\n");
3145 lf_printf(file
, "#include \"mon.h\"\n");
3146 lf_printf(file
, "\n");
3147 lf_printf(file
, "#ifdef HAVE_STDLIB_H\n");
3148 lf_printf(file
, "#include <stdlib.h>\n");
3149 lf_printf(file
, "#endif\n");
3150 lf_printf(file
, "\n");
3152 for(insn_ptr
= model_data
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3153 model_c_or_h_data(table
, file
, insn_ptr
->file_entry
);
3156 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3157 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3160 lf_printf(file
, "/* Insn functional unit info */\n");
3161 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3162 model_c_passed_data data
;
3164 lf_printf(file
, "static const model_time model_time_%s[] = {\n", model_ptr
->name
);
3166 data
.model_ptr
= model_ptr
;
3167 insn_table_traverse_insn(table
,
3171 lf_printf(file
, "};\n");
3172 lf_printf(file
, "\n");
3173 lf_printf(file
, "\f\n");
3176 lf_printf(file
, "STATIC_MODEL const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3177 lf_printf(file
, " (const model_time *const)0,\n");
3178 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3179 lf_printf(file
, " model_time_%s,\n", model_ptr
->name
);
3181 lf_printf(file
, "};\n");
3182 lf_printf(file
, "\n");
3184 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3185 model_c_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3188 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3189 model_c_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3190 name
= insn_ptr
->file_entry
->fields
[function_name
];
3191 if (strcmp (name
, "model_create") == 0)
3193 else if (strcmp (name
, "model_init") == 0)
3195 else if (strcmp (name
, "model_halt") == 0)
3197 else if (strcmp (name
, "model_issue") == 0)
3199 else if (strcmp (name
, "model_mon_info") == 0)
3200 model_mon_info_p
= 1;
3201 else if (strcmp (name
, "model_mon_info_free") == 0)
3202 model_mon_info_free_p
= 1;
3205 if (!model_create_p
) {
3206 lf_printf(file
, "INLINE_MODEL model_data *model_create(cpu *processor)\n");
3207 lf_printf(file
, "{\n");
3208 lf_printf(file
, " return (model_data *)0;\n");
3209 lf_printf(file
, "}\n");
3210 lf_printf(file
, "\n");
3213 if (!model_init_p
) {
3214 lf_printf(file
, "INLINE_MODEL void model_init(cpu *processor,\n");
3215 lf_printf(file
, " model_data *model_ptr)\n");
3216 lf_printf(file
, "{\n");
3217 lf_printf(file
, "}\n");
3218 lf_printf(file
, "\n");
3221 if (!model_halt_p
) {
3222 lf_printf(file
, "INLINE_MODEL void model_halt(cpu *processor,\n");
3223 lf_printf(file
, " model_data *model_ptr)\n");
3224 lf_printf(file
, "{\n");
3225 lf_printf(file
, "}\n");
3226 lf_printf(file
, "\n");
3229 if (!model_issue_p
) {
3230 lf_printf(file
, "INLINE_MODEL void model_issue(itable_index index,\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
, "\f\n");
3255 lf_printf(file
, "/* map model enumeration into printable string */\n");
3256 lf_printf(file
, "STATIC_MODEL const char *model_name[ (int)nr_models ] = {\n");
3257 lf_printf(file
, " \"NONE\",\n");
3258 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3259 lf_printf(file
, " \"%s\",\n", model_ptr
->printable_name
);
3261 lf_printf(file
, "};\n");
3262 lf_printf(file
, "\n");
3264 lf_printf(file
, "INLINE_MODEL void\n");
3265 lf_printf(file
, "model_set(const char *name)\n");
3266 lf_printf(file
, "{\n");
3268 lf_printf(file
, " model_enum model;\n");
3269 lf_printf(file
, " for(model = MODEL_%s; model < nr_models; model++) {\n", models
->name
);
3270 lf_printf(file
, " if(strcmp(name, model_name[model]) == 0) {\n");
3271 lf_printf(file
, " current_model = model;\n");
3272 lf_printf(file
, " return;\n");
3273 lf_printf(file
, " }\n");
3274 lf_printf(file
, " }\n");
3275 lf_printf(file
, "\n");
3276 lf_printf(file
, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3277 lf_printf(file
, " name,\n");
3278 lf_printf(file
, " \"");
3279 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3280 lf_printf(file
, "\\n\\t%s", model_ptr
->printable_name
);
3282 lf_printf(file
, "\");\n");
3284 lf_printf(file
, " error(\"No models are currently known about\");\n");
3287 lf_printf(file
, "}\n");
3288 lf_printf(file
, "\n");
3290 lf_printf(file
, "#endif /* _MODEL_C_ */\n");
3294 /****************************************************************/
3302 insn_table
*instructions
= NULL
;
3303 icache_tree
*cache_fields
= NULL
;
3304 char *real_file_name
= NULL
;
3309 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
3310 printf("Config options:\n");
3311 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
3312 printf(" -e Expand (duplicate) semantic functions\n");
3313 printf(" -r <icache-size> Generate cracking cache version\n");
3314 printf(" -l Supress line numbering in output files\n");
3315 printf(" -b <bit-size> Set the number of bits in an instruction\n");
3316 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
3317 printf("Input options (ucase version also dumps loaded table):\n");
3318 printf(" -[Oo] <opcode-rules>\n");
3319 printf(" -[Kk] <cache-rules>\n");
3320 printf(" -[Ii] <instruction-table>\n");
3321 printf("Output options:\n");
3322 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
3323 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
3324 printf(" -[Mm] <output-file> output model.h(M) model.c(M)\n");
3325 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
3326 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
3329 while ((ch
= getopt(argc
, argv
,
3330 "leb:h:r:f:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
3331 fprintf(stderr
, "\t-%c %s\n", ch
, (optarg
? optarg
: ""));
3337 idecode_expand_semantics
= 1;
3340 idecode_cache
= a2i(optarg
);
3343 insn_size
= a2i(optarg
);
3344 ASSERT(insn_size
> 0 && insn_size
<= max_insn_size
3345 && (hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0));
3348 hi_bit_nr
= a2i(optarg
);
3349 ASSERT(hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0);
3353 filter
*new_filter
= ZALLOC(filter
);
3354 new_filter
->flag
= strdup(optarg
);
3355 new_filter
->next
= filters
;
3356 filters
= new_filter
;
3361 ASSERT(opcode_table
!= NULL
);
3362 ASSERT(cache_table
!= NULL
);
3363 instructions
= insn_table_load_insns(optarg
);
3364 fprintf(stderr
, "\texpanding ...\n");
3365 insn_table_expand_insns(instructions
);
3366 fprintf(stderr
, "\tcache fields ...\n");
3367 cache_fields
= insn_table_cache_fields(instructions
);
3369 dump_traverse(instructions
);
3370 dump_insn_table(instructions
, 0, 1);
3375 opcode_table
= load_opcode_rules(optarg
);
3377 dump_opcode_rules(opcode_table
, 0);
3381 cache_table
= load_cache_rules(optarg
);
3383 dump_cache_rules(cache_table
, 0);
3386 real_file_name
= strdup(optarg
);
3398 lf
*file
= lf_open(optarg
, real_file_name
, number_lines
);
3399 ASSERT(instructions
!= NULL
);
3402 gen_semantics_h(instructions
, file
);
3405 gen_semantics_c(instructions
, file
);
3408 gen_idecode_h(instructions
, file
);
3411 gen_idecode_c(instructions
, file
);
3414 gen_model_h(instructions
, file
);
3417 gen_model_c(instructions
, file
);
3420 gen_itable_h(instructions
, file
);
3423 gen_itable_c(instructions
, file
);
3426 gen_icache_h(cache_fields
, file
);
3431 real_file_name
= NULL
;
3434 error("unknown option\n");