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_default
= insn_form
,
582 model_name
= insn_mnemonic
,
583 model_identifer
= insn_name
,
584 model_func
= insn_comment
,
585 } model_table_fields
;
587 typedef struct _insn insn
;
589 table_entry
*file_entry
;
594 typedef struct _model_func_unit model_func_unit
;
595 struct _model_func_unit
{
596 model_func_unit
*next
;
603 typedef struct _model model
;
607 char *printable_name
;
608 model_func_unit
*func_unit_start
;
609 model_func_unit
*func_unit_end
;
612 typedef struct _insn_table insn_table
;
615 insn_bits
*expanded_bits
;
620 int max_func_unit_name_len
;
621 unsigned max_func_unit_mask
;
622 opcode_rules
*opcode_rule
;
623 opcode_field
*opcode
;
636 nr_insn_model_table_fields
637 } insn_model_table_fields
;
639 static model
*models
;
640 static model
*last_model
;
642 static insn
*model_macros
;
643 static insn
*last_model_macro
;
645 static insn
*model_functions
;
646 static insn
*last_model_function
;
648 static insn
*model_internal
;
649 static insn
*last_model_internal
;
651 static insn
*model_data
;
652 static insn
*last_model_data
;
655 insn_table_insert_function(insn_table
*table
,
656 table_entry
*file_entry
)
658 /* create a new function */
659 insn
*new_function
= ZALLOC(insn
);
660 new_function
->file_entry
= file_entry
;
662 /* append it to the end of the function list */
663 if (table
->last_function
)
664 table
->last_function
->next
= new_function
;
666 table
->functions
= new_function
;
667 table
->last_function
= new_function
;
671 insn_table_insert_insn(insn_table
*table
,
672 table_entry
*file_entry
,
675 insn
**ptr_to_cur_insn
= &table
->insns
;
676 insn
*cur_insn
= *ptr_to_cur_insn
;
677 table_model_entry
*insn_model_ptr
;
680 /* create a new instruction */
681 insn
*new_insn
= ZALLOC(insn
);
682 new_insn
->file_entry
= file_entry
;
683 new_insn
->fields
= fields
;
685 /* Check out any model information returned to make sure the model
687 for(insn_model_ptr
= file_entry
->model_first
; insn_model_ptr
; insn_model_ptr
= insn_model_ptr
->next
) {
688 char *name
= insn_model_ptr
->fields
[insn_model_name
];
690 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
691 if (strcmp(name
, model_ptr
->name
) == 0) {
693 /* Replace the name field with that of the global model, so that when we
694 want to print it out, we can just compare pointers. */
695 insn_model_ptr
->fields
[insn_model_name
] = model_ptr
->name
;
701 error("%s:%d: machine model `%s' was not known about\n",
702 file_entry
->file_name
, file_entry
->line_nr
, name
);
705 /* insert it according to the order of the fields */
706 while (cur_insn
!= NULL
707 && new_insn
->fields
->value
>= cur_insn
->fields
->value
) {
708 ptr_to_cur_insn
= &cur_insn
->next
;
709 cur_insn
= *ptr_to_cur_insn
;
712 new_insn
->next
= cur_insn
;
713 *ptr_to_cur_insn
= new_insn
;
719 static opcode_field
*
720 insn_table_find_opcode_field(insn
*insns
,
724 opcode_field
*curr_opcode
= ZALLOC(opcode_field
);
728 curr_opcode
->first
= insn_size
;
729 curr_opcode
->last
= -1;
730 for (entry
= insns
; entry
!= NULL
; entry
= entry
->next
) {
731 insn_fields
*fields
= entry
->fields
;
732 opcode_field new_opcode
;
734 /* find a start point for the opcode field */
735 new_opcode
.first
= rule
->first
;
736 while (new_opcode
.first
<= rule
->last
738 || insn_field_is_constant(fields
->bits
[new_opcode
.first
],
739 rule
) != field_constant_string
)
741 || !insn_field_is_constant(fields
->bits
[new_opcode
.first
],
743 new_opcode
.first
= fields
->bits
[new_opcode
.first
]->last
+ 1;
744 ASSERT(new_opcode
.first
> rule
->last
746 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
747 rule
) == field_constant_string
)
749 && insn_field_is_constant(fields
->bits
[new_opcode
.first
],
752 /* find the end point for the opcode field */
753 new_opcode
.last
= rule
->last
;
754 while (new_opcode
.last
>= rule
->first
756 || insn_field_is_constant(fields
->bits
[new_opcode
.last
],
757 rule
) != field_constant_string
)
759 || !insn_field_is_constant(fields
->bits
[new_opcode
.last
],
761 new_opcode
.last
= fields
->bits
[new_opcode
.last
]->first
- 1;
762 ASSERT(new_opcode
.last
< rule
->first
764 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
765 rule
) == field_constant_string
)
767 && insn_field_is_constant(fields
->bits
[new_opcode
.last
],
770 /* now see if our current opcode needs expanding */
771 if (new_opcode
.first
<= rule
->last
772 && curr_opcode
->first
> new_opcode
.first
)
773 curr_opcode
->first
= new_opcode
.first
;
774 if (new_opcode
.last
>= rule
->first
775 && curr_opcode
->last
< new_opcode
.last
)
776 curr_opcode
->last
= new_opcode
.last
;
780 /* was any thing interesting found? */
781 if (curr_opcode
->first
> rule
->last
) {
782 ASSERT(curr_opcode
->last
< rule
->first
);
785 ASSERT(curr_opcode
->last
>= rule
->first
);
786 ASSERT(curr_opcode
->first
<= rule
->last
);
788 /* if something was found, check it includes the forced field range */
790 && curr_opcode
->first
> rule
->force_first
) {
791 curr_opcode
->first
= rule
->force_first
;
794 && curr_opcode
->last
< rule
->force_last
) {
795 curr_opcode
->last
= rule
->force_last
;
797 /* handle special case elminating any need to do shift after mask */
799 && rule
->force_last
== insn_size
-1) {
800 curr_opcode
->last
= insn_size
-1;
803 /* handle any special cases */
804 switch (rule
->special_rule
) {
805 case 0: /* let the above apply */
807 case 1: /* expand a limited nr of bits, ignoring the rest */
808 curr_opcode
->first
= rule
->force_first
;
809 curr_opcode
->last
= rule
->force_last
;
811 case 2: /* boolean field */
812 curr_opcode
->is_boolean
= 1;
821 insn_table_insert_expanded(insn_table
*table
,
826 insn_table
**ptr_to_cur_entry
= &table
->entries
;
827 insn_table
*cur_entry
= *ptr_to_cur_entry
;
829 /* find the new table for this entry */
830 while (cur_entry
!= NULL
831 && cur_entry
->opcode_nr
< new_opcode_nr
) {
832 ptr_to_cur_entry
= &cur_entry
->sibling
;
833 cur_entry
= *ptr_to_cur_entry
;
836 if (cur_entry
== NULL
|| cur_entry
->opcode_nr
!= new_opcode_nr
) {
837 insn_table
*new_entry
= ZALLOC(insn_table
);
838 new_entry
->opcode_nr
= new_opcode_nr
;
839 new_entry
->expanded_bits
= new_bits
;
840 new_entry
->opcode_rule
= table
->opcode_rule
->next
;
841 new_entry
->sibling
= cur_entry
;
842 new_entry
->parent
= table
;
843 *ptr_to_cur_entry
= new_entry
;
844 cur_entry
= new_entry
;
847 /* ASSERT new_bits == cur_entry bits */
848 ASSERT(cur_entry
!= NULL
&& cur_entry
->opcode_nr
== new_opcode_nr
);
849 insn_table_insert_insn(cur_entry
,
850 old_insn
->file_entry
,
855 insn_table_expand_opcode(insn_table
*table
,
862 if (field_nr
> table
->opcode
->last
) {
863 insn_table_insert_expanded(table
, instruction
, opcode_nr
, bits
);
866 insn_field
*field
= instruction
->fields
->bits
[field_nr
];
867 if (field
->is_int
|| field
->is_slash
) {
868 ASSERT(field
->first
>= table
->opcode
->first
869 && field
->last
<= table
->opcode
->last
);
870 insn_table_expand_opcode(table
, instruction
, field
->last
+1,
871 ((opcode_nr
<< field
->width
) + field
->val_int
),
876 int last_pos
= ((field
->last
< table
->opcode
->last
)
877 ? field
->last
: table
->opcode
->last
);
878 int first_pos
= ((field
->first
> table
->opcode
->first
)
879 ? field
->first
: table
->opcode
->first
);
880 int width
= last_pos
- first_pos
+ 1;
881 int last_val
= (table
->opcode
->is_boolean
883 for (val
= 0; val
< last_val
; val
++) {
884 insn_bits
*new_bits
= ZALLOC(insn_bits
);
885 new_bits
->field
= field
;
886 new_bits
->value
= val
;
887 new_bits
->last
= bits
;
888 new_bits
->opcode
= table
->opcode
;
889 insn_table_expand_opcode(table
, instruction
, last_pos
+1,
890 ((opcode_nr
<< width
) | val
),
898 insn_table_insert_expanding(insn_table
*table
,
901 insn_table_expand_opcode(table
,
903 table
->opcode
->first
,
905 table
->expanded_bits
);
910 insn_table_expand_insns(insn_table
*table
)
913 ASSERT(table
->nr_insn
>= 1);
915 /* determine a valid opcode */
916 while (table
->opcode_rule
) {
917 /* specials only for single instructions */
918 if ((table
->nr_insn
> 1
919 && table
->opcode_rule
->special_mask
== 0
920 && table
->opcode_rule
->special_rule
== 0)
921 || (table
->nr_insn
== 1
922 && table
->opcode_rule
->special_mask
!= 0
923 && ((table
->insns
->fields
->value
924 & table
->opcode_rule
->special_mask
)
925 == table
->opcode_rule
->special_value
))
926 || (idecode_expand_semantics
927 && table
->opcode_rule
->special_mask
== 0
928 && table
->opcode_rule
->special_rule
== 0))
930 insn_table_find_opcode_field(table
->insns
,
932 table
->nr_insn
== 1/*string*/
934 if (table
->opcode
!= NULL
)
936 table
->opcode_rule
= table
->opcode_rule
->next
;
939 /* did we find anything */
940 if (table
->opcode
== NULL
) {
943 ASSERT(table
->opcode
!= NULL
);
945 /* back link what we found to its parent */
946 if (table
->parent
!= NULL
) {
947 ASSERT(table
->parent
->opcode
!= NULL
);
948 table
->opcode
->parent
= table
->parent
->opcode
;
951 /* expand the raw instructions according to the opcode */
954 for (entry
= table
->insns
; entry
!= NULL
; entry
= entry
->next
) {
955 insn_table_insert_expanding(table
, entry
);
959 /* and do the same for the sub entries */
962 for (entry
= table
->entries
; entry
!= NULL
; entry
= entry
->sibling
) {
963 insn_table_expand_insns(entry
);
970 model_table_insert(insn_table
*table
,
971 table_entry
*file_entry
)
973 /* create a new model */
974 model
*new_model
= ZALLOC(model
);
975 model_func_unit
*func_unit
;
976 char *ptr
, *end
, *end_name
, *comment
, *name
;
983 new_model
->name
= file_entry
->fields
[model_identifer
];
984 new_model
->printable_name
= file_entry
->fields
[model_name
];
985 name_len
= strlen(new_model
->name
);
987 /* append it to the end of the model list */
989 last_model
->next
= new_model
;
992 last_model
= new_model
;
994 /* Parse the function units separated by commas */
996 for (ptr
= file_entry
->fields
[model_func
];
997 ((ch
= *ptr
) != '\0') && (ch
!= '\n');
998 ptr
= (*end
== ',') ? end
+1 : end
) {
1000 while (ch
== ' ' || ch
== '\t')
1003 if (!ch
|| ch
== '\n')
1006 /* Search for comma or newline ending field */
1008 end_name
= (char *)0;
1013 while (ch
!= '\0' && ch
!= ',' && ch
!= '\n') {
1014 if (end_name
== (char *)0 && (ch
== '=' || isspace(ch
)))
1022 func_unit
= ZALLOC(model_func_unit
);
1023 if (new_model
->func_unit_end
)
1024 new_model
->func_unit_end
->next
= func_unit
;
1026 new_model
->func_unit_start
= func_unit
;
1028 new_model
->func_unit_end
= func_unit
;
1030 /* Record function unit name as model name _ unit name */
1031 func_name_len
= name_len
+ end_name
- ptr
+ 2;
1032 if (table
->max_func_unit_name_len
< func_name_len
)
1033 table
->max_func_unit_name_len
= func_name_len
;
1035 func_unit
->name
= name
= (char *)zalloc(func_name_len
);
1036 memcpy(name
, new_model
->name
, name_len
);
1037 name
[name_len
] = '_';
1038 memcpy(name
+ name_len
+ 1, ptr
, end_name
- ptr
);
1040 /* See if there are multiple functional units */
1041 if (*end_name
== '=') {
1043 for(end_name
++; end_name
< end
&& isdigit(*end_name
); end_name
++)
1044 number
= number
* 10 + (*end_name
- '0');
1049 /* Now figure out the mask for these unit(s) */
1050 func_unit
->number
= number
;
1057 func_unit
->mask
= mask
;
1058 table
->max_func_unit_mask
|= mask
;
1060 /* Now figure out comments */
1061 for (comment
= end_name
; comment
< end
&& ((ch
= *comment
) == ' ' || ch
== '\t'); comment
++)
1064 if (comment
< end
) {
1065 func_unit
->comment
= (char *)zalloc(end
- comment
+ 1);
1066 memcpy(func_unit
->comment
, comment
, end
- comment
);
1070 /* Add an 'sentinel' function unit at the end to simpify the loop */
1071 func_unit
= ZALLOC(model_func_unit
);
1072 if (new_model
->func_unit_end
)
1073 new_model
->func_unit_end
->next
= func_unit
;
1075 new_model
->func_unit_start
= func_unit
;
1077 new_model
->func_unit_end
= func_unit
;
1079 /* Record function unit name as model name _ unit name */
1080 func_name_len
= name_len
+ sizeof("_SENTINEL");
1081 if (table
->max_func_unit_name_len
< func_name_len
)
1082 table
->max_func_unit_name_len
= func_name_len
;
1084 func_unit
->name
= name
= (char *)zalloc(func_name_len
);
1085 func_unit
->number
= 0;
1086 func_unit
->mask
= unit
;
1087 func_unit
->comment
= "dummy";
1088 table
->max_func_unit_mask
|= unit
;
1090 memcpy(name
, new_model
->name
, name_len
);
1091 strcpy(name
+ name_len
, "_SENTINEL");
1095 model_table_insert_specific(insn_table
*table
,
1096 table_entry
*file_entry
,
1100 insn
*ptr
= ZALLOC(insn
);
1101 ptr
->file_entry
= file_entry
;
1103 (*end_ptr
)->next
= ptr
;
1112 insn_table_load_insns(char *file_name
)
1114 table
*file
= table_open(file_name
, nr_insn_table_fields
, nr_insn_model_table_fields
);
1115 insn_table
*table
= ZALLOC(insn_table
);
1116 table_entry
*file_entry
;
1117 table
->opcode_rule
= opcode_table
;
1119 while ((file_entry
= table_entry_read(file
)) != NULL
) {
1120 if (it_is("function", file_entry
->fields
[insn_flags
])
1121 || it_is("internal", file_entry
->fields
[insn_flags
])) {
1122 insn_table_insert_function(table
, file_entry
);
1124 else if (it_is("model", file_entry
->fields
[insn_flags
])) {
1125 model_table_insert(table
, file_entry
);
1127 else if (it_is("model-macro", file_entry
->fields
[insn_flags
])) {
1128 model_table_insert_specific(table
, file_entry
, &model_macros
, &last_model_macro
);
1130 else if (it_is("model-function", file_entry
->fields
[insn_flags
])) {
1131 model_table_insert_specific(table
, file_entry
, &model_functions
, &last_model_function
);
1133 else if (it_is("model-internal", file_entry
->fields
[insn_flags
])) {
1134 model_table_insert_specific(table
, file_entry
, &model_internal
, &last_model_internal
);
1136 else if (it_is("model-data", file_entry
->fields
[insn_flags
])) {
1137 model_table_insert_specific(table
, file_entry
, &model_data
, &last_model_data
);
1140 insn_fields
*fields
;
1141 /* skip instructions that aren't relevant to the mode */
1142 filter
*filt
= filters
;
1143 while (filt
!= NULL
) {
1144 if (it_is(filt
->flag
, file_entry
->fields
[insn_flags
]))
1149 /* create/insert the new instruction */
1150 fields
= parse_insn_format(file_entry
,
1151 file_entry
->fields
[insn_format
]);
1152 insn_table_insert_insn(table
, file_entry
, fields
);
1161 dump_insn(insn
*entry
, int indent
, int levels
)
1163 printf("(insn*)%p\n", entry
);
1165 if (levels
&& entry
!= NULL
) {
1167 dumpf(indent
, "(file_entry ");
1168 dump_table_entry(entry
->file_entry
, indent
+1);
1169 dumpf(indent
, " )\n");
1171 dumpf(indent
, "(fields ");
1172 dump_insn_fields(entry
->fields
, indent
+1);
1173 dumpf(indent
, " )\n");
1175 dumpf(indent
, "(next ");
1176 dump_insn(entry
->next
, indent
+1, levels
-1);
1177 dumpf(indent
, " )\n");
1185 dump_insn_table(insn_table
*table
,
1186 int indent
, int levels
)
1189 printf("(insn_table*)%p\n", table
);
1191 if (levels
&& table
!= NULL
) {
1193 dumpf(indent
, "(opcode_nr %d)\n", table
->opcode_nr
);
1195 dumpf(indent
, "(expanded_bits ");
1196 dump_insn_bits(table
->expanded_bits
, indent
+1, -1);
1197 dumpf(indent
, " )\n");
1199 dumpf(indent
, "(int nr_insn %d)\n", table
->nr_insn
);
1201 dumpf(indent
, "(insns ");
1202 dump_insn(table
->insns
, indent
+1, table
->nr_insn
);
1203 dumpf(indent
, " )\n");
1205 dumpf(indent
, "(opcode_rule ");
1206 dump_opcode_rule(table
->opcode_rule
, indent
+1);
1207 dumpf(indent
, " )\n");
1209 dumpf(indent
, "(opcode ");
1210 dump_opcode_field(table
->opcode
, indent
+1, 1);
1211 dumpf(indent
, " )\n");
1213 dumpf(indent
, "(nr_entries %d)\n", table
->entries
);
1214 dumpf(indent
, "(entries ");
1215 dump_insn_table(table
->entries
, indent
+1, table
->nr_entries
);
1216 dumpf(indent
, " )\n");
1218 dumpf(indent
, "(sibling ", table
->sibling
);
1219 dump_insn_table(table
->sibling
, indent
+1, levels
-1);
1220 dumpf(indent
, " )\n");
1222 dumpf(indent
, "(parent ", table
->parent
);
1223 dump_insn_table(table
->parent
, indent
+1, 0);
1224 dumpf(indent
, " )\n");
1230 /****************************************************************/
1234 lf_print_insn_bits(lf
*file
, insn_bits
*bits
)
1238 lf_print_insn_bits(file
, bits
->last
);
1239 lf_putchr(file
, '_');
1240 lf_putstr(file
, bits
->field
->val_string
);
1241 if (!bits
->opcode
->is_boolean
|| bits
->value
== 0) {
1242 if (bits
->opcode
->last
< bits
->field
->last
)
1243 lf_putint(file
, bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1245 lf_putint(file
, bits
->value
);
1250 lf_print_opcodes(lf
*file
,
1253 if (table
!= NULL
) {
1255 lf_printf(file
, "_%d_%d",
1256 table
->opcode
->first
,
1257 table
->opcode
->last
);
1258 if (table
->parent
== NULL
) break;
1259 lf_printf(file
, "__%d", table
->opcode_nr
);
1260 table
= table
->parent
;
1266 lf_print_table_name(lf
*file
,
1269 lf_printf(file
, "idecode_table");
1270 lf_print_opcodes(file
, table
);
1276 function_name_prefix_semantics
,
1277 function_name_prefix_idecode
,
1278 function_name_prefix_itable
,
1279 function_name_prefix_none
1280 } lf_function_name_prefixes
;
1283 lf_print_function_name(lf
*file
,
1285 insn_bits
*expanded_bits
,
1286 lf_function_name_prefixes prefix
)
1291 case function_name_prefix_semantics
:
1292 lf_putstr(file
, "semantic_");
1294 case function_name_prefix_idecode
:
1295 lf_printf(file
, "idecode_");
1297 case function_name_prefix_itable
:
1298 lf_putstr(file
, "itable_");
1304 /* the function name */
1307 for (pos
= basename
;
1315 lf_putchr(file
, '_');
1318 lf_putchr(file
, *pos
);
1325 if (idecode_expand_semantics
)
1326 lf_print_insn_bits(file
, expanded_bits
);
1331 lf_print_idecode_table(lf
*file
,
1334 int can_assume_leaf
;
1335 opcode_rules
*opcode_rule
;
1337 /* have a look at the rule table, if all table rules follow all
1338 switch rules, I can assume that all end points are leaves */
1339 opcode_rule
= opcode_table
;
1340 while (opcode_rule
!= NULL
1341 && opcode_rule
->use_switch
)
1342 opcode_rule
= opcode_rule
->next
;
1343 while (opcode_rule
!= NULL
1344 && opcode_rule
->use_switch
1345 && opcode_rule
->special_rule
)
1346 opcode_rule
= opcode_rule
->next
;
1347 can_assume_leaf
= opcode_rule
== NULL
;
1349 lf_printf(file
, "{\n");
1350 lf_indent(file
, +2);
1352 lf_printf(file
, "idecode_table_entry *table = ");
1353 lf_print_table_name(file
, entry
);
1354 lf_printf(file
, ";\n");
1355 lf_printf(file
, "int opcode = EXTRACTED32(instruction, %d, %d);\n",
1356 i2target(hi_bit_nr
, entry
->opcode
->first
),
1357 i2target(hi_bit_nr
, entry
->opcode
->last
));
1358 lf_printf(file
, "idecode_table_entry *table_entry = table + opcode;\n");
1359 lf_printf(file
, "while (1) {\n");
1360 lf_indent(file
, +2);
1362 lf_printf(file
, "/* nonzero mask -> another table */\n");
1363 lf_printf(file
, "while (table_entry->mask != 0) {\n");
1364 lf_indent(file
, +2);
1366 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1367 lf_printf(file
, " table_entry->function_or_table);\n");
1368 lf_printf(file
, "opcode = ((instruction & table_entry->mask)\n");
1369 lf_printf(file
, " >> table_entry->shift);\n");
1370 lf_printf(file
, "table_entry = table + opcode;\n");
1372 lf_indent(file
, -2);
1373 lf_printf(file
, "}\n");
1374 lf_printf(file
, "ASSERT(table_entry->mask == 0);\n");
1375 if (can_assume_leaf
)
1376 lf_printf(file
, "ASSERT(table_entry->shift == 0);\n");
1378 lf_printf(file
, "if (table_entry->shift == 0)\n");
1379 lf_indent(file
, +2);
1381 if (idecode_cache
) {
1382 lf_printf(file
, "return (((idecode_crack*)\n");
1383 lf_printf(file
, " table_entry->function_or_table)\n");
1384 lf_printf(file
, " (%s));\n", cache_idecode_actual
);
1387 lf_printf(file
, "return (((idecode_semantic*)\n");
1388 lf_printf(file
, " table_entry->function_or_table)\n");
1389 lf_printf(file
, " (%s));\n", semantic_actual
);
1391 if (!can_assume_leaf
) {
1392 lf_indent(file
, -2);
1393 lf_printf(file
, "/* must be a boolean */\n");
1394 lf_printf(file
, "opcode = (instruction & table_entry->shift) != 0;\n");
1395 lf_printf(file
, "table = ((idecode_table_entry*)\n");
1396 lf_printf(file
, " table_entry->function_or_table);\n");
1397 lf_printf(file
, "table_entry = table + opcode;\n");
1400 lf_indent(file
, -2);
1401 lf_printf(file
, "}\n");
1403 lf_indent(file
, -2);
1404 lf_printf(file
, "}\n");
1409 lf_print_my_prefix(lf
*file
,
1410 table_entry
*file_entry
,
1413 lf_printf(file
, "const char *const my_prefix = \n");
1414 lf_printf(file
, " \"%s:%s:%s:%d\";\n",
1415 filter_filename (file_entry
->file_name
),
1416 (idecode
? "idecode" : "semantics"),
1417 file_entry
->fields
[insn_name
],
1418 file_entry
->line_nr
);
1423 lf_print_ptrace(lf
*file
,
1426 lf_printf(file
, "\n");
1427 lf_printf(file
, "ITRACE(trace_%s, (\"\\n\"));\n",
1428 (idecode
? "idecode" : "semantics"));
1432 /****************************************************************/
1434 typedef void leaf_handler
1438 typedef void padding_handler
1446 insn_table_traverse_tree(insn_table
*table
,
1449 leaf_handler
*start
,
1452 padding_handler
*padding
)
1457 ASSERT(table
!= NULL
1458 && table
->opcode
!= NULL
1459 && table
->nr_entries
> 0
1460 && table
->entries
!= 0);
1462 if (start
!= NULL
&& depth
>= 0)
1463 start(table
, data
, depth
);
1465 for (entry_nr
= 0, entry
= table
->entries
;
1466 entry_nr
< (table
->opcode
->is_boolean
1468 : (1 << (table
->opcode
->last
- table
->opcode
->first
+ 1)));
1471 || (!table
->opcode
->is_boolean
1472 && entry_nr
< entry
->opcode_nr
)) {
1473 if (padding
!= NULL
&& depth
>= 0)
1474 padding(table
, data
, depth
, entry_nr
);
1477 ASSERT(entry
!= NULL
&& (entry
->opcode_nr
== entry_nr
1478 || table
->opcode
->is_boolean
));
1479 if (entry
->opcode
!= NULL
&& depth
!= 0) {
1480 insn_table_traverse_tree(entry
, data
, depth
+1,
1481 start
, leaf
, end
, padding
);
1483 else if (depth
>= 0) {
1485 leaf(entry
, data
, depth
);
1487 entry
= entry
->sibling
;
1490 if (end
!= NULL
&& depth
>= 0)
1491 end(table
, data
, depth
);
1495 typedef void function_handler
1498 table_entry
*function
);
1501 insn_table_traverse_function(insn_table
*table
,
1503 function_handler
*leaf
)
1506 for (function
= table
->functions
;
1508 function
= function
->next
) {
1509 leaf(table
, data
, function
->file_entry
);
1514 typedef void insn_handler
1520 insn_table_traverse_insn(insn_table
*table
,
1525 for (instruction
= table
->insns
;
1526 instruction
!= NULL
;
1527 instruction
= instruction
->next
) {
1528 leaf(table
, data
, instruction
);
1534 update_depth(insn_table
*entry
,
1538 int *max_depth
= (int*)data
;
1539 if (*max_depth
< depth
)
1545 insn_table_depth(insn_table
*table
)
1548 insn_table_traverse_tree(table
,
1559 /****************************************************************/
1562 dump_traverse_start(insn_table
*table
,
1566 dumpf(depth
*2, "(%d\n", table
->opcode_nr
);
1570 dump_traverse_leaf(insn_table
*entry
,
1574 ASSERT(entry
->nr_entries
== 0
1575 && entry
->nr_insn
== 1
1576 && entry
->opcode
== NULL
);
1577 dumpf(depth
*2, ".%d %s\n", entry
->opcode_nr
,
1578 entry
->insns
->file_entry
->fields
[insn_format
]);
1582 dump_traverse_end(insn_table
*table
,
1586 dumpf(depth
*2, ")\n");
1590 dump_traverse_padding(insn_table
*table
,
1595 dumpf(depth
*2, ".<%d>\n", opcode_nr
);
1600 dump_traverse(insn_table
*table
)
1602 insn_table_traverse_tree(table
, NULL
, 1,
1603 dump_traverse_start
,
1606 dump_traverse_padding
);
1610 /****************************************************************/
1614 lf_print_semantic_function_header(lf
*file
,
1616 insn_bits
*expanded_bits
,
1617 int is_function_definition
,
1618 int is_inline_function
)
1620 lf_printf(file
, "\n");
1621 lf_printf(file
, "STATIC_SEMANTICS unsigned_word ");
1622 lf_print_function_name(file
,
1625 function_name_prefix_semantics
);
1626 lf_printf(file
, "\n(%s)",
1627 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
1628 if (!is_function_definition
)
1629 lf_printf(file
, ";");
1630 lf_printf(file
, "\n");
1635 semantics_h_leaf(insn_table
*entry
,
1639 lf
*file
= (lf
*)data
;
1640 ASSERT(entry
->nr_insn
== 1);
1641 lf_print_semantic_function_header(file
,
1642 entry
->insns
->file_entry
->fields
[insn_name
],
1643 entry
->expanded_bits
,
1644 0/* isnt function definition*/,
1645 !idecode_cache
&& entry
->parent
->opcode_rule
->use_switch
);
1649 semantics_h_insn(insn_table
*entry
,
1653 lf
*file
= (lf
*)data
;
1654 lf_print_semantic_function_header(file
,
1655 instruction
->file_entry
->fields
[insn_name
],
1657 0/*isnt function definition*/,
1658 0/*isnt inline function*/);
1662 semantics_h_function(insn_table
*entry
,
1664 table_entry
*function
)
1666 lf
*file
= (lf
*)data
;
1667 if (function
->fields
[function_type
] == NULL
1668 || function
->fields
[function_type
][0] == '\0') {
1669 lf_print_semantic_function_header(file
,
1670 function
->fields
[function_name
],
1672 0/*isnt function definition*/,
1673 1/*is inline function*/);
1676 lf_printf(file
, "\n");
1677 lf_printf(file
, "INLINE_SEMANTICS %s %s\n(%s);\n",
1678 function
->fields
[function_type
],
1679 function
->fields
[function_name
],
1680 function
->fields
[function_param
]);
1686 gen_semantics_h(insn_table
*table
, lf
*file
)
1689 lf_print_copyleft(file
);
1690 lf_printf(file
, "\n");
1691 lf_printf(file
, "#ifndef _SEMANTICS_H_\n");
1692 lf_printf(file
, "#define _SEMANTICS_H_\n");
1693 lf_printf(file
, "\n");
1694 lf_printf(file
, "#ifndef INLINE_SEMANTICS\n");
1695 lf_printf(file
, "#define INLINE_SEMANTICS\n");
1696 lf_printf(file
, "#endif\n");
1697 lf_printf(file
, "\n");
1698 lf_printf(file
, "#ifndef STATIC_SEMANTICS\n");
1699 lf_printf(file
, "#define STATIC_SEMANTICS\n");
1700 lf_printf(file
, "#endif\n");
1701 lf_printf(file
, "\n");
1702 lf_printf(file
, "\n");
1704 /* output a declaration for all functions */
1705 insn_table_traverse_function(table
,
1707 semantics_h_function
);
1709 /* output a declaration for all instructions */
1710 if (idecode_expand_semantics
)
1711 insn_table_traverse_tree(table
,
1715 semantics_h_leaf
, /* leaf */
1717 NULL
); /* padding */
1719 insn_table_traverse_insn(table
,
1723 lf_printf(file
, "\n");
1724 lf_printf(file
, "#endif /* _SEMANTICS_H_ */\n");
1728 /****************************************************************/
1730 typedef struct _icache_tree icache_tree
;
1731 struct _icache_tree
{
1734 icache_tree
*children
;
1737 static icache_tree
*
1738 icache_tree_insert(icache_tree
*tree
,
1741 icache_tree
*new_tree
;
1743 icache_tree
**ptr_to_cur_tree
= &tree
->children
;
1744 icache_tree
*cur_tree
= *ptr_to_cur_tree
;
1745 while (cur_tree
!= NULL
1746 && strcmp(cur_tree
->name
, name
) < 0) {
1747 ptr_to_cur_tree
= &cur_tree
->next
;
1748 cur_tree
= *ptr_to_cur_tree
;
1750 ASSERT(cur_tree
== NULL
1751 || strcmp(cur_tree
->name
, name
) >= 0);
1752 /* already in the tree */
1753 if (cur_tree
!= NULL
1754 && strcmp(cur_tree
->name
, name
) == 0)
1756 /* missing, insert it */
1757 ASSERT(cur_tree
== NULL
1758 || strcmp(cur_tree
->name
, name
) > 0);
1759 new_tree
= ZALLOC(icache_tree
);
1760 new_tree
->name
= name
;
1761 new_tree
->next
= cur_tree
;
1762 *ptr_to_cur_tree
= new_tree
;
1767 static icache_tree
*
1768 insn_table_cache_fields(insn_table
*table
)
1770 icache_tree
*tree
= ZALLOC(icache_tree
);
1772 for (instruction
= table
->insns
;
1773 instruction
!= NULL
;
1774 instruction
= instruction
->next
) {
1777 icache_tree_insert(tree
,
1778 instruction
->file_entry
->fields
[insn_form
]);
1779 for (field
= instruction
->fields
->first
;
1781 field
= field
->next
) {
1782 if (field
->is_string
)
1783 icache_tree_insert(form
, field
->val_string
);
1792 gen_icache_h(icache_tree
*tree
,
1795 lf_print_copyleft(file
);
1796 lf_printf(file
, "\n");
1797 lf_printf(file
, "#ifndef _ICACHE_H_\n");
1798 lf_printf(file
, "#define _ICACHE_H_\n");
1799 lf_printf(file
, "\n");
1800 lf_printf(file
, "#ifndef INLINE_ICACHE\n");
1801 lf_printf(file
, "#define INLINE_ICACHE\n");
1802 lf_printf(file
, "#endif\n");
1803 lf_printf(file
, "\n");
1805 lf_printf(file
, "#define WITH_IDECODE_CACHE_SIZE %d\n",
1807 lf_printf(file
, "\n");
1809 /* create an instruction cache if being used */
1810 if (idecode_cache
) {
1812 lf_printf(file
, "typedef struct _idecode_cache {\n");
1813 lf_printf(file
, " unsigned_word address;\n");
1814 lf_printf(file
, " void *semantic;\n");
1815 lf_printf(file
, " union {\n");
1816 for (form
= tree
->children
;
1818 form
= form
->next
) {
1820 lf_printf(file
, " struct {\n");
1821 for (field
= form
->children
;
1823 field
= field
->next
) {
1824 cache_rules
*cache_rule
;
1826 for (cache_rule
= cache_table
;
1828 cache_rule
= cache_rule
->next
) {
1829 if (strcmp(field
->name
, cache_rule
->old_name
) == 0) {
1831 if (cache_rule
->new_name
!= NULL
)
1832 lf_printf(file
, " %s %s; /* %s */\n",
1833 (cache_rule
->type
== NULL
1835 : cache_rule
->type
),
1836 cache_rule
->new_name
,
1837 cache_rule
->old_name
);
1841 lf_printf(file
, " unsigned %s;\n", field
->name
);
1843 lf_printf(file
, " } %s;\n", form
->name
);
1845 lf_printf(file
, " } crack;\n");
1846 lf_printf(file
, "} idecode_cache;\n");
1849 /* alernativly, since no cache, #define the fields to be
1850 extractions from the instruction variable */
1851 cache_rules
*cache_rule
;
1852 lf_printf(file
, "\n");
1853 for (cache_rule
= cache_table
;
1855 cache_rule
= cache_rule
->next
) {
1856 if (cache_rule
->expression
!= NULL
1857 && strlen(cache_rule
->expression
) > 0)
1858 lf_printf(file
, "#define %s %s\n",
1859 cache_rule
->new_name
, cache_rule
->expression
);
1863 lf_printf(file
, "\n");
1864 lf_printf(file
, "#endif /* _ICACHE_H_ */\n");
1870 /****************************************************************/
1874 lf_print_c_extraction(lf
*file
,
1878 char *field_expression
,
1879 insn_field
*cur_field
,
1881 int get_value_from_cache
,
1882 int put_value_in_cache
)
1884 ASSERT(field_name
!= NULL
);
1886 && (!bits
->opcode
->is_boolean
|| bits
->value
== 0)
1887 && strcmp(field_name
, cur_field
->val_string
) == 0) {
1888 ASSERT(bits
->field
== cur_field
);
1889 ASSERT(field_type
== NULL
);
1890 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1891 lf_printf(file
, "const unsigned %s = ",
1893 if (bits
->opcode
->last
< bits
->field
->last
)
1894 lf_printf(file
, "%d;\n",
1895 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
1897 lf_printf(file
, "%d;\n", bits
->value
);
1900 /* put the field in the local variable */
1901 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
1902 lf_printf(file
, "%s const %s = ",
1903 field_type
== NULL
? "unsigned" : field_type
,
1905 /* getting it from the cache */
1906 if (get_value_from_cache
|| put_value_in_cache
) {
1907 lf_printf(file
, "cache_entry->crack.%s.%s",
1908 instruction
->file_entry
->fields
[insn_form
],
1910 if (put_value_in_cache
) /* also put it in the cache? */
1911 lf_printf(file
, " = ");
1913 if (!get_value_from_cache
) {
1914 if (strcmp(field_name
, cur_field
->val_string
) == 0)
1915 lf_printf(file
, "EXTRACTED32(instruction, %d, %d)",
1916 i2target(hi_bit_nr
, cur_field
->first
),
1917 i2target(hi_bit_nr
, cur_field
->last
));
1918 else if (field_expression
!= NULL
)
1919 lf_printf(file
, "%s", field_expression
);
1921 lf_printf(file
, "eval_%s", field_name
);
1923 lf_printf(file
, ";\n");
1929 lf_print_c_extractions(lf
*file
,
1931 insn_bits
*expanded_bits
,
1932 int get_value_from_cache
,
1933 int put_value_in_cache
)
1935 insn_field
*cur_field
;
1937 /* extract instruction fields */
1938 lf_printf(file
, "/* extraction: %s */\n",
1939 instruction
->file_entry
->fields
[insn_format
]);
1941 for (cur_field
= instruction
->fields
->first
;
1942 cur_field
->first
< insn_size
;
1943 cur_field
= cur_field
->next
) {
1944 if (cur_field
->is_string
) {
1947 /* find any corresponding value */
1948 for (bits
= expanded_bits
;
1950 bits
= bits
->last
) {
1951 if (bits
->field
== cur_field
)
1954 /* try the cache rule table for what to do */
1955 if (get_value_from_cache
|| put_value_in_cache
) {
1956 cache_rules
*cache_rule
;
1957 for (cache_rule
= cache_table
;
1959 cache_rule
= cache_rule
->next
) {
1960 if (strcmp(cur_field
->val_string
, cache_rule
->old_name
) == 0) {
1962 if (cache_rule
->valid
> 1 && put_value_in_cache
)
1963 lf_print_c_extraction(file
,
1965 cache_rule
->new_name
,
1967 cache_rule
->expression
,
1972 else if (cache_rule
->valid
== 1)
1973 lf_print_c_extraction(file
,
1975 cache_rule
->new_name
,
1977 cache_rule
->expression
,
1980 get_value_from_cache
,
1981 put_value_in_cache
);
1985 if (found_rule
== 0)
1986 lf_print_c_extraction(file
,
1988 cur_field
->val_string
,
1993 get_value_from_cache
,
1994 put_value_in_cache
);
1995 /* if any (XXX == 0), output a corresponding test */
1996 if (instruction
->file_entry
->annex
!= NULL
) {
1997 char *field_name
= cur_field
->val_string
;
1998 char *is_0_ptr
= instruction
->file_entry
->annex
;
1999 int field_len
= strlen(field_name
);
2000 if (strlen(is_0_ptr
) >= (strlen("_is_0") + field_len
)) {
2001 is_0_ptr
+= field_len
;
2002 while ((is_0_ptr
= strstr(is_0_ptr
, "_is_0")) != NULL
) {
2003 if (strncmp(is_0_ptr
- field_len
, field_name
, field_len
) == 0
2004 && !isalpha(is_0_ptr
[ - field_len
- 1])) {
2005 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2006 lf_printf(file
, "const unsigned %s_is_0 = (", field_name
);
2008 lf_printf(file
, "%d", bits
->value
);
2010 lf_printf(file
, "%s", field_name
);
2011 lf_printf(file
, " == 0);\n");
2014 is_0_ptr
+= strlen("_is_0");
2018 /* any thing else ... */
2021 lf_print_lf_c_line_nr(file
);
2026 lf_print_idecode_illegal(lf
*file
)
2029 lf_printf(file
, "return idecode_illegal(%s);\n", cache_idecode_actual
);
2031 lf_printf(file
, "return semantic_illegal(%s);\n", semantic_actual
);
2036 lf_print_idecode_floating_point_unavailable(lf
*file
)
2039 lf_printf(file
, "return idecode_floating_point_unavailable(%s);\n",
2040 cache_idecode_actual
);
2042 lf_printf(file
, "return semantic_floating_point_unavailable(%s);\n",
2047 /* Output code to do any final checks on the decoded instruction.
2048 This includes things like verifying any on decoded fields have the
2049 correct value and checking that (for floating point) floating point
2050 hardware isn't disabled */
2053 lf_print_c_validate(lf
*file
,
2055 opcode_field
*opcodes
)
2057 /* Validate: unchecked instruction fields
2059 If any constant fields in the instruction were not checked by the
2060 idecode tables, output code to check that they have the correct
2063 unsigned check_mask
= 0;
2064 unsigned check_val
= 0;
2066 opcode_field
*opcode
;
2068 /* form check_mask/check_val containing what needs to be checked
2069 in the instruction */
2070 for (field
= instruction
->fields
->first
;
2071 field
->first
< insn_size
;
2072 field
= field
->next
) {
2074 check_mask
<<= field
->width
;
2075 check_val
<<= field
->width
;
2077 /* is it a constant that could need validating? */
2078 if (!field
->is_int
&& !field
->is_slash
)
2081 /* has it been checked by a table? */
2082 for (opcode
= opcodes
; opcode
!= NULL
; opcode
= opcode
->parent
) {
2083 if (field
->first
>= opcode
->first
2084 && field
->last
<= opcode
->last
)
2090 check_mask
|= (1 << field
->width
)-1;
2091 check_val
|= field
->val_int
;
2094 /* if any bits not checked by opcode tables, output code to check them */
2096 lf_printf(file
, "\n");
2097 lf_printf(file
, "/* validate: %s */\n",
2098 instruction
->file_entry
->fields
[insn_format
]);
2099 lf_printf(file
, "if (WITH_RESERVED_BITS && (instruction & 0x%x) != 0x%x)\n",
2100 check_mask
, check_val
);
2101 lf_indent(file
, +2);
2102 lf_print_idecode_illegal(file
);
2103 lf_indent(file
, -2);
2107 /* Validate floating point hardware
2109 If the simulator is being built with out floating point hardware
2110 (different to it being disabled in the MSR) then floating point
2111 instructions are invalid */
2113 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2114 lf_printf(file
, "\n");
2115 lf_printf(file
, "/* Validate: FP hardware exists */\n");
2116 lf_printf(file
, "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT)\n");
2117 lf_indent(file
, +2);
2118 lf_print_idecode_illegal(file
);
2119 lf_indent(file
, -2);
2123 /* Validate: Floating Point available
2125 If floating point is not available, we enter a floating point
2126 unavailable interrupt into the cache instead of the instruction
2129 The PowerPC spec requires a CSI after MSR[FP] is changed and when
2130 ever a CSI occures we flush the instruction cache. */
2133 if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2134 lf_printf(file
, "\n");
2135 lf_printf(file
, "/* Validate: FP available according to MSR[FP] */\n");
2136 lf_printf(file
, "if (!IS_FP_AVAILABLE(processor))\n");
2137 lf_indent(file
, +2);
2138 lf_print_idecode_floating_point_unavailable(file
);
2139 lf_indent(file
, -2);
2146 lf_print_c_cracker(lf
*file
,
2148 insn_bits
*expanded_bits
,
2149 opcode_field
*opcodes
)
2152 /* function header */
2153 lf_printf(file
, "{\n");
2154 lf_indent(file
, +2);
2156 lf_print_my_prefix(file
,
2157 instruction
->file_entry
,
2158 1/*putting-value-in-cache*/);
2160 lf_print_ptrace(file
,
2161 1/*putting-value-in-cache*/);
2163 lf_print_c_validate(file
, instruction
, opcodes
);
2165 lf_printf(file
, "\n");
2166 lf_printf(file
, "{\n");
2167 lf_indent(file
, +2);
2168 lf_print_c_extractions(file
,
2171 0/*get_value_from_cache*/,
2172 1/*put_value_in_cache*/);
2173 lf_indent(file
, -2);
2174 lf_printf(file
, "}\n");
2176 /* return the function propper (main sorts this one out) */
2177 lf_printf(file
, "\n");
2178 lf_printf(file
, "/* semantic routine */\n");
2179 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2180 lf_printf(file
, "return ");
2181 lf_print_function_name(file
,
2182 instruction
->file_entry
->fields
[insn_name
],
2184 function_name_prefix_semantics
);
2185 lf_printf(file
, ";\n");
2187 lf_print_lf_c_line_nr(file
);
2188 lf_indent(file
, -2);
2189 lf_printf(file
, "}\n");
2194 lf_print_c_semantic(lf
*file
,
2196 insn_bits
*expanded_bits
,
2197 opcode_field
*opcodes
)
2200 lf_printf(file
, "{\n");
2201 lf_indent(file
, +2);
2203 lf_print_my_prefix(file
,
2204 instruction
->file_entry
,
2205 0/*not putting value in cache*/);
2206 lf_printf(file
, "unsigned_word nia = cia + %d;\n", insn_size
/ 8);
2208 lf_printf(file
, "\n");
2209 lf_print_c_extractions(file
,
2212 idecode_cache
/*get_value_from_cache*/,
2213 0/*put_value_in_cache*/);
2215 lf_print_ptrace(file
,
2216 0/*put_value_in_cache*/);
2218 /* validate the instruction, if a cache this has already been done */
2220 lf_print_c_validate(file
, instruction
, opcodes
);
2222 /* generate the profileing call - this is delayed until after the
2223 instruction has been verified */
2224 lf_printf(file
, "\n");
2225 lf_printf(file
, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
2226 lf_printf(file
, " mon_issue(");
2227 lf_print_function_name(file
,
2228 instruction
->file_entry
->fields
[insn_name
],
2230 function_name_prefix_itable
);
2231 lf_printf(file
, ", processor, cia);\n");
2233 /* generate the code (or at least something */
2234 if (instruction
->file_entry
->annex
!= NULL
) {
2236 lf_printf(file
, "\n");
2237 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2238 lf_printf(file
, "{\n");
2239 lf_indent(file
, +2);
2240 lf_print_c_code(file
, instruction
->file_entry
->annex
);
2241 lf_indent(file
, -2);
2242 lf_printf(file
, "}\n");
2243 lf_print_lf_c_line_nr(file
);
2245 else if (it_is("nop", instruction
->file_entry
->fields
[insn_flags
])) {
2246 lf_print_lf_c_line_nr(file
);
2248 else if (it_is("f", instruction
->file_entry
->fields
[insn_flags
])) {
2249 /* unimplemented floating point instruction - call for assistance */
2250 lf_printf(file
, "\n");
2251 lf_printf(file
, "/* unimplemented floating point instruction - call for assistance */\n");
2252 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2253 lf_putstr(file
, "floating_point_assist_interrupt(processor, cia);\n");
2254 lf_print_lf_c_line_nr(file
);
2257 /* abort so it is implemented now */
2258 table_entry_lf_c_line_nr(file
, instruction
->file_entry
);
2259 lf_putstr(file
, "error(\"%s: unimplemented, cia=0x%x\\n\", my_prefix, cia);\n");
2260 lf_print_lf_c_line_nr(file
);
2261 lf_printf(file
, "\n");
2264 /* the function footer */
2265 lf_printf(file
, "return nia;\n");
2266 lf_indent(file
, -2);
2267 lf_printf(file
, "}\n");
2271 lf_print_c_semantic_function_header(lf
*file
,
2273 insn_bits
*expanded_bits
)
2275 lf_printf(file
, "\n");
2276 lf_printf(file
, "STATIC_SEMANTICS unsigned_word\n");
2277 lf_print_function_name(file
,
2280 function_name_prefix_semantics
);
2281 lf_printf(file
, "\n(%s)\n",
2282 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2286 lf_print_c_semantic_function(lf
*file
,
2288 insn_bits
*expanded_bits
,
2289 opcode_field
*opcodes
,
2290 int is_inline_function
)
2293 /* build the semantic routine to execute the instruction */
2294 lf_print_semantic_function_header(file
,
2295 instruction
->file_entry
->fields
[insn_name
],
2297 1/*is-function-definition*/,
2298 is_inline_function
);
2299 lf_print_c_semantic(file
,
2307 semantics_c_leaf(insn_table
*entry
,
2311 lf
*file
= (lf
*)data
;
2312 ASSERT(entry
->nr_insn
== 1
2313 && entry
->opcode
== NULL
2314 && entry
->parent
!= NULL
2315 && entry
->parent
->opcode
!= NULL
);
2316 lf_print_c_semantic_function(file
,
2318 entry
->expanded_bits
,
2319 entry
->parent
->opcode
,
2320 !idecode_cache
&& entry
->parent
->opcode_rule
->use_switch
);
2324 semantics_c_insn(insn_table
*table
,
2328 lf
*file
= (lf
*)data
;
2329 lf_print_c_semantic_function(file
, instruction
,
2331 0/*isnt_inline_function*/);
2335 semantics_c_function(insn_table
*table
,
2337 table_entry
*function
)
2339 lf
*file
= (lf
*)data
;
2340 if (function
->fields
[function_type
] == NULL
2341 || function
->fields
[function_type
][0] == '\0') {
2342 lf_print_semantic_function_header(file
,
2343 function
->fields
[function_name
],
2345 1/*is function definition*/,
2346 1/*is inline function*/);
2349 lf_printf(file
, "\n");
2350 lf_printf(file
, "INLINE_SEMANTICS %s\n%s(%s)\n",
2351 function
->fields
[function_type
],
2352 function
->fields
[function_name
],
2353 function
->fields
[function_param
]);
2355 table_entry_lf_c_line_nr(file
, function
);
2356 lf_printf(file
, "{\n");
2357 lf_indent(file
, +2);
2358 lf_print_c_code(file
, function
->annex
);
2359 lf_indent(file
, -2);
2360 lf_printf(file
, "}\n");
2361 lf_print_lf_c_line_nr(file
);
2367 gen_semantics_c(insn_table
*table
, lf
*file
)
2369 lf_print_copyleft(file
);
2370 lf_printf(file
, "\n");
2371 lf_printf(file
, "#ifndef _SEMANTICS_C_\n");
2372 lf_printf(file
, "#define _SEMANTICS_C_\n");
2373 lf_printf(file
, "\n");
2374 lf_printf(file
, "#ifndef STATIC_INLINE_SEMANTICS\n");
2375 lf_printf(file
, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2376 lf_printf(file
, "#endif\n");
2377 lf_printf(file
, "\n");
2378 lf_printf(file
, "#include \"cpu.h\"\n");
2379 lf_printf(file
, "#include \"idecode.h\"\n");
2380 lf_printf(file
, "#include \"semantics.h\"\n");
2381 lf_printf(file
, "\n");
2383 /* output a definition (c-code) for all functions */
2384 insn_table_traverse_function(table
,
2386 semantics_c_function
);
2388 /* output a definition (c-code) for all instructions */
2389 if (idecode_expand_semantics
)
2390 insn_table_traverse_tree(table
,
2396 NULL
); /* padding */
2398 insn_table_traverse_insn(table
,
2402 lf_printf(file
, "\n");
2403 lf_printf(file
, "#endif /* _SEMANTICS_C_ */\n");
2407 /****************************************************************/
2410 gen_idecode_h(insn_table
*table
, lf
*file
)
2412 lf_print_copyleft(file
);
2413 lf_printf(file
, "\n");
2414 lf_printf(file
, "#ifndef _IDECODE_H_\n");
2415 lf_printf(file
, "#define _IDECODE_H_\n");
2416 lf_printf(file
, "\n");
2417 lf_printf(file
, "#ifndef INLINE_IDECODE\n");
2418 lf_printf(file
, "#define INLINE_IDECODE\n");
2419 lf_printf(file
, "#endif\n");
2420 lf_printf(file
, "\n");
2421 lf_printf(file
, "#include \"idecode_expression.h\"\n");
2422 lf_printf(file
, "#include \"idecode_fields.h\"\n");
2423 lf_printf(file
, "#include \"idecode_branch.h\"\n");
2424 lf_printf(file
, "\n");
2425 lf_printf(file
, "#include \"icache.h\"\n");
2426 lf_printf(file
, "\n");
2427 lf_printf(file
, "typedef unsigned_word idecode_semantic\n(%s);\n",
2428 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2429 lf_printf(file
, "\n");
2431 lf_printf(file
, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2432 cache_idecode_formal
);
2434 lf_printf(file
, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2436 lf_printf(file
, "\n");
2437 lf_printf(file
, "#endif /* _IDECODE_H_ */\n");
2441 /****************************************************************/
2445 idecode_table_start(insn_table
*table
,
2449 lf
*file
= (lf
*)data
;
2451 /* start of the table */
2452 if (!table
->opcode_rule
->use_switch
) {
2453 lf_printf(file
, "\n");
2454 lf_printf(file
, "static idecode_table_entry ");
2455 lf_print_table_name(file
, table
);
2456 lf_printf(file
, "[] = {\n");
2461 idecode_table_leaf(insn_table
*entry
,
2465 lf
*file
= (lf
*)data
;
2466 ASSERT(entry
->parent
!= NULL
);
2469 /* add an entry to the table */
2470 if (!entry
->parent
->opcode_rule
->use_switch
) {
2471 if (entry
->opcode
== NULL
) {
2472 /* table leaf entry */
2473 lf_printf(file
, " /*%d*/ { 0, 0, ", entry
->opcode_nr
);
2474 lf_print_function_name(file
,
2475 entry
->insns
->file_entry
->fields
[insn_name
],
2476 entry
->expanded_bits
,
2478 ? function_name_prefix_idecode
2479 : function_name_prefix_semantics
));
2480 lf_printf(file
, " },\n");
2482 else if (entry
->opcode_rule
->use_switch
) {
2483 /* table calling switch statement */
2484 lf_printf(file
, " /*%d*/ { 0, 0, ",
2486 lf_print_table_name(file
, entry
);
2487 lf_printf(file
, " },\n");
2490 /* table `calling' another table */
2491 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
2492 if (entry
->opcode
->is_boolean
)
2493 lf_printf(file
, "MASK32(%d,%d), 0, ",
2494 i2target(hi_bit_nr
, entry
->opcode
->first
),
2495 i2target(hi_bit_nr
, entry
->opcode
->last
));
2497 lf_printf(file
, "%d, MASK32(%d,%d), ",
2498 insn_size
- entry
->opcode
->last
- 1,
2499 i2target(hi_bit_nr
, entry
->opcode
->first
),
2500 i2target(hi_bit_nr
, entry
->opcode
->last
));
2501 lf_print_table_name(file
, entry
);
2502 lf_printf(file
, " },\n");
2508 idecode_table_end(insn_table
*table
,
2512 lf
*file
= (lf
*)data
;
2515 if (!table
->opcode_rule
->use_switch
) {
2516 lf_printf(file
, "};\n");
2521 idecode_table_padding(insn_table
*table
,
2526 lf
*file
= (lf
*)data
;
2529 if (!table
->opcode_rule
->use_switch
) {
2530 lf_printf(file
, " /*%d*/ { 0, 0, %s_illegal },\n",
2531 opcode_nr
, (idecode_cache
? "idecode" : "semantic"));
2536 /****************************************************************/
2539 void lf_print_idecode_switch
2545 idecode_switch_start(insn_table
*table
,
2549 lf
*file
= (lf
*)data
;
2551 ASSERT(table
->opcode_rule
->use_switch
);
2553 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2554 i2target(hi_bit_nr
, table
->opcode
->first
),
2555 i2target(hi_bit_nr
, table
->opcode
->last
));
2560 idecode_switch_leaf(insn_table
*entry
,
2564 lf
*file
= (lf
*)data
;
2565 ASSERT(entry
->parent
!= NULL
);
2567 ASSERT(entry
->parent
->opcode_rule
->use_switch
);
2568 ASSERT(entry
->parent
->opcode
);
2570 if (!entry
->parent
->opcode
->is_boolean
2571 || entry
->opcode_nr
== 0)
2572 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
2574 lf_printf(file
, "default:\n");
2575 lf_indent(file
, +2);
2577 if (entry
->opcode
== NULL
) {
2578 /* switch calling leaf */
2579 lf_printf(file
, "return ");
2580 lf_print_function_name(file
,
2581 entry
->insns
->file_entry
->fields
[insn_name
],
2582 entry
->expanded_bits
,
2584 ? function_name_prefix_idecode
2585 : function_name_prefix_semantics
));
2587 lf_printf(file
, "(%s);\n", cache_idecode_actual
);
2589 lf_printf(file
, "(%s);\n", semantic_actual
);
2591 else if (entry
->opcode_rule
->use_switch
) {
2592 /* switch calling switch */
2593 lf_print_idecode_switch(file
, entry
);
2596 /* switch looking up a table */
2597 lf_print_idecode_table(file
, entry
);
2599 lf_printf(file
, "break;\n");
2601 lf_indent(file
, -2);
2606 lf_print_idecode_switch_illegal(lf
*file
)
2608 lf_indent(file
, +2);
2609 lf_print_idecode_illegal(file
);
2610 lf_printf(file
, "break;\n");
2611 lf_indent(file
, -2);
2615 idecode_switch_end(insn_table
*table
,
2619 lf
*file
= (lf
*)data
;
2621 ASSERT(table
->opcode_rule
->use_switch
);
2622 ASSERT(table
->opcode
);
2624 if (table
->opcode_rule
->use_switch
== 1
2625 && !table
->opcode
->is_boolean
) {
2626 lf_printf(file
, "default:\n");
2627 lf_print_idecode_switch_illegal(file
);
2629 lf_printf(file
, "}\n");
2633 idecode_switch_padding(insn_table
*table
,
2638 lf
*file
= (lf
*)data
;
2641 ASSERT(table
->opcode_rule
->use_switch
);
2643 if (table
->opcode_rule
->use_switch
> 1) {
2644 lf_printf(file
, "case %d:\n", opcode_nr
);
2645 lf_print_idecode_switch_illegal(file
);
2651 lf_print_idecode_switch(lf
*file
,
2654 insn_table_traverse_tree(table
,
2657 idecode_switch_start
,
2658 idecode_switch_leaf
,
2660 idecode_switch_padding
);
2665 lf_print_idecode_switch_function_header(lf
*file
,
2667 int is_function_definition
)
2669 lf_printf(file
, "\n");
2670 lf_printf(file
, "static ");
2672 lf_printf(file
, "idecode_semantic *");
2674 lf_printf(file
, "unsigned_word");
2675 if (is_function_definition
)
2676 lf_printf(file
, "\n");
2678 lf_printf(file
, " ");
2679 lf_print_table_name(file
, table
);
2680 lf_printf(file
, "\n(%s)",
2681 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2682 if (!is_function_definition
)
2683 lf_printf(file
, ";");
2684 lf_printf(file
, "\n");
2689 idecode_declare_if_switch(insn_table
*table
,
2693 lf
*file
= (lf
*)data
;
2695 if (table
->opcode_rule
->use_switch
2696 && table
->parent
!= NULL
/* don't declare the top one yet */
2697 && !table
->parent
->opcode_rule
->use_switch
) {
2698 lf_print_idecode_switch_function_header(file
,
2700 0/*isnt function definition*/);
2706 idecode_expand_if_switch(insn_table
*table
,
2710 lf
*file
= (lf
*)data
;
2712 if (table
->opcode_rule
->use_switch
2713 && table
->parent
!= NULL
/* don't expand the top one yet */
2714 && !table
->parent
->opcode_rule
->use_switch
) {
2715 lf_print_idecode_switch_function_header(file
,
2717 1/*is function definition*/);
2718 lf_printf(file
, "{\n");
2720 lf_indent(file
, +2);
2721 lf_print_idecode_switch(file
, table
);
2722 lf_indent(file
, -2);
2724 lf_printf(file
, "}\n");
2730 lf_print_c_cracker_function(lf
*file
,
2732 insn_bits
*expanded_bits
,
2733 opcode_field
*opcodes
,
2734 int is_inline_function
)
2736 /* if needed, generate code to enter this routine into a cache */
2737 lf_printf(file
, "\n");
2738 lf_printf(file
, "STATIC_IDECODE idecode_semantic *\n");
2739 lf_print_function_name(file
,
2740 instruction
->file_entry
->fields
[insn_name
],
2742 function_name_prefix_idecode
);
2743 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2745 lf_print_c_cracker(file
,
2752 idecode_crack_leaf(insn_table
*entry
,
2756 lf
*file
= (lf
*)data
;
2757 ASSERT(entry
->nr_insn
== 1
2758 && entry
->opcode
== NULL
2759 && entry
->parent
!= NULL
2760 && entry
->parent
->opcode
!= NULL
2761 && entry
->parent
->opcode_rule
!= NULL
);
2762 lf_print_c_cracker_function(file
,
2764 entry
->expanded_bits
,
2766 entry
->parent
->opcode_rule
->use_switch
);
2770 idecode_crack_insn(insn_table
*entry
,
2774 lf
*file
= (lf
*)data
;
2775 lf_print_c_cracker_function(file
,
2779 0/*isnt inline function*/);
2783 idecode_c_internal_function(insn_table
*table
,
2785 table_entry
*function
)
2787 lf
*file
= (lf
*)data
;
2788 ASSERT(idecode_cache
!= 0);
2789 if (it_is("internal", function
->fields
[insn_flags
])) {
2790 lf_printf(file
, "\n");
2791 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2792 lf_print_function_name(file
,
2793 function
->fields
[insn_name
],
2795 function_name_prefix_idecode
);
2796 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2797 lf_printf(file
, "{\n");
2798 lf_indent(file
, +2);
2799 lf_printf(file
, "/* semantic routine */\n");
2800 table_entry_lf_c_line_nr(file
, function
);
2801 lf_printf(file
, "return ");
2802 lf_print_function_name(file
,
2803 function
->fields
[insn_name
],
2805 function_name_prefix_semantics
);
2806 lf_printf(file
, ";\n");
2808 lf_print_lf_c_line_nr(file
);
2809 lf_indent(file
, -2);
2810 lf_printf(file
, "}\n");
2815 /****************************************************************/
2818 gen_idecode_c(insn_table
*table
, lf
*file
)
2823 lf_print_copyleft(file
);
2824 lf_printf(file
, "\n");
2825 lf_printf(file
, "\n");
2826 lf_printf(file
, "#ifndef _IDECODE_C_\n");
2827 lf_printf(file
, "#define _IDECODE_C_\n");
2828 lf_printf(file
, "\n");
2829 lf_printf(file
, "#ifndef STATIC_INLINE_IDECODE\n");
2830 lf_printf(file
, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2831 lf_printf(file
, "#endif\n");
2832 lf_printf(file
, "\n");
2833 lf_printf(file
, "#ifndef STATIC_IDECODE\n");
2834 lf_printf(file
, "#define STATIC_IDECODE\n");
2835 lf_printf(file
, "#endif\n");
2836 lf_printf(file
, "\n");
2837 lf_printf(file
, "#include \"cpu.h\"\n");
2838 lf_printf(file
, "#include \"idecode.h\"\n");
2839 lf_printf(file
, "#include \"semantics.h\"\n");
2840 lf_printf(file
, "\n");
2841 lf_printf(file
, "\n");
2842 lf_printf(file
, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2843 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2844 lf_printf(file
, "\n");
2845 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
2846 lf_printf(file
, " unsigned shift;\n");
2847 lf_printf(file
, " unsigned mask;\n");
2848 lf_printf(file
, " void *function_or_table;\n");
2849 lf_printf(file
, "} idecode_table_entry;\n");
2850 lf_printf(file
, "\n");
2851 lf_printf(file
, "\n");
2853 /* output `internal' invalid/floating-point unavailable functions
2855 if (idecode_cache
) {
2856 insn_table_traverse_function(table
,
2858 idecode_c_internal_function
);
2861 /* output cracking functions where needed */
2862 if (idecode_cache
) {
2863 if (idecode_expand_semantics
)
2864 insn_table_traverse_tree(table
,
2872 insn_table_traverse_insn(table
,
2874 idecode_crack_insn
);
2877 /* output switch function declarations where needed by tables */
2878 insn_table_traverse_tree(table
,
2881 idecode_declare_if_switch
, /* START */
2884 /* output tables where needed */
2885 for (depth
= insn_table_depth(table
);
2888 insn_table_traverse_tree(table
,
2891 idecode_table_start
,
2894 idecode_table_padding
);
2897 /* output switch functions where needed */
2898 insn_table_traverse_tree(table
,
2901 idecode_expand_if_switch
, /* START */
2904 /* output the main idecode routine */
2905 lf_printf(file
, "\n");
2907 lf_printf(file
, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2908 cache_idecode_formal
);
2910 lf_printf(file
, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2912 lf_printf(file
, "{\n");
2913 lf_indent(file
, +2);
2914 if (table
->opcode_rule
->use_switch
)
2915 lf_print_idecode_switch(file
, table
);
2917 lf_print_idecode_table(file
, table
);
2918 lf_indent(file
, -2);
2919 lf_printf(file
, "}\n");
2920 lf_printf(file
, "\n");
2921 lf_printf(file
, "#endif /* _IDECODE_C_ */\n");
2925 /****************************************************************/
2928 itable_h_insn(insn_table
*entry
,
2932 lf
*file
= (lf
*)data
;
2933 lf_printf(file
, " ");
2934 lf_print_function_name(file
,
2935 instruction
->file_entry
->fields
[insn_name
],
2937 function_name_prefix_itable
);
2938 lf_printf(file
, ",\n");
2943 gen_itable_h(insn_table
*table
, lf
*file
)
2946 lf_print_copyleft(file
);
2947 lf_printf(file
, "\n");
2948 lf_printf(file
, "#ifndef _ITABLE_H_\n");
2949 lf_printf(file
, "#define _ITABLE_H_\n");
2950 lf_printf(file
, "\n");
2951 lf_printf(file
, "#ifndef INLINE_ITABLE\n");
2952 lf_printf(file
, "#define INLINE_ITABLE\n");
2953 lf_printf(file
, "#endif\n");
2954 lf_printf(file
, "\n");
2955 lf_printf(file
, "\n");
2957 /* output an enumerated type for each instruction */
2958 lf_printf(file
, "typedef enum {\n");
2959 insn_table_traverse_insn(table
,
2962 lf_printf(file
, " nr_itable_entries,\n");
2963 lf_printf(file
, "} itable_index;\n");
2964 lf_printf(file
, "\n");
2966 /* output the table that contains the actual instruction info */
2967 lf_printf(file
, "typedef struct _itable_instruction_info {\n");
2968 lf_printf(file
, " itable_index nr;\n");
2969 lf_printf(file
, " char *format;\n");
2970 lf_printf(file
, " char *form;\n");
2971 lf_printf(file
, " char *flags;\n");
2972 lf_printf(file
, " char *mnemonic;\n");
2973 lf_printf(file
, " char *name;\n");
2974 lf_printf(file
, "} itable_info;\n");
2975 lf_printf(file
, "\n");
2976 lf_printf(file
, "extern itable_info itable[nr_itable_entries];\n");
2978 lf_printf(file
, "\n");
2979 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2983 /****************************************************************/
2986 itable_c_insn(insn_table
*entry
,
2990 lf
*file
= (lf
*)data
;
2991 char **fields
= instruction
->file_entry
->fields
;
2992 lf_printf(file
, " { ");
2993 lf_print_function_name(file
,
2994 instruction
->file_entry
->fields
[insn_name
],
2996 function_name_prefix_itable
);
2997 lf_printf(file
, ",\n");
2998 lf_printf(file
, " \"%s\",\n", fields
[insn_format
]);
2999 lf_printf(file
, " \"%s\",\n", fields
[insn_form
]);
3000 lf_printf(file
, " \"%s\",\n", fields
[insn_flags
]);
3001 lf_printf(file
, " \"%s\",\n", fields
[insn_mnemonic
]);
3002 lf_printf(file
, " \"%s\",\n", fields
[insn_name
]);
3003 lf_printf(file
, " },\n");
3008 gen_itable_c(insn_table
*table
, lf
*file
)
3011 lf_print_copyleft(file
);
3012 lf_printf(file
, "\n");
3013 lf_printf(file
, "#ifndef _ITABLE_C_\n");
3014 lf_printf(file
, "#define _ITABLE_C_\n");
3015 lf_printf(file
, "\n");
3016 lf_printf(file
, "#ifndef STATIC_INLINE_ITABLE\n");
3017 lf_printf(file
, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
3018 lf_printf(file
, "#endif\n");
3019 lf_printf(file
, "\n");
3020 lf_printf(file
, "#include \"itable.h\"\n");
3021 lf_printf(file
, "\n");
3023 /* output the table that contains the actual instruction info */
3024 lf_printf(file
, "itable_info itable[nr_itable_entries] = {\n");
3025 insn_table_traverse_insn(table
,
3028 lf_printf(file
, "};\n");
3029 lf_printf(file
, "\n");
3031 lf_printf(file
, "\n");
3032 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
3035 /****************************************************************/
3038 model_c_or_h_data(insn_table
*table
,
3043 table_entry_lf_c_line_nr(file
, data
);
3044 lf_print_c_code(file
, data
->annex
);
3045 lf_print_lf_c_line_nr(file
);
3046 lf_printf(file
, "\n");
3051 model_c_or_h_function(insn_table
*entry
,
3053 table_entry
*function
,
3056 if (function
->fields
[function_type
] == NULL
3057 || function
->fields
[function_type
][0] == '\0') {
3058 error("Model function type not specified for %s", function
->fields
[function_name
]);
3061 lf_printf(file
, "\n");
3062 lf_printf(file
, "%s %s %s\n(%s);\n",
3064 function
->fields
[function_type
],
3065 function
->fields
[function_name
],
3066 function
->fields
[function_param
]);
3068 lf_printf(file
, "\n");
3072 gen_model_h(insn_table
*table
, lf
*file
)
3076 model_func_unit
*func_unit_ptr
;
3080 lf_print_copyleft(file
);
3081 lf_printf(file
, "\n");
3082 lf_printf(file
, "#ifndef _MODEL_H_\n");
3083 lf_printf(file
, "#define _MODEL_H_\n");
3084 lf_printf(file
, "\n");
3086 for(macro
= model_macros
; macro
; macro
= macro
->next
) {
3087 model_c_or_h_data(table
, file
, insn_ptr
->file_entry
);
3090 lf_printf(file
, "#ifndef INLINE_MODEL\n");
3091 lf_printf(file
, "#define INLINE_MODEL\n");
3092 lf_printf(file
, "#endif\n");
3093 lf_printf(file
, "#ifndef STATIC_INLINE_MODEL\n");
3094 lf_printf(file
, "#define STATIC_INLINE_MODEL STATIC_INLINE\n");
3095 lf_printf(file
, "#endif\n");
3096 lf_printf(file
, "\n");
3097 lf_printf(file
, "\n");
3099 if (table
->max_func_unit_mask
> 0xffff) {
3101 lf_printf(file
, "#ifndef MODEL_UNITS\n");
3102 lf_printf(file
, "#define MODEL_UNITS unsigned32\n");
3103 lf_printf(file
, "#endif\n");
3104 lf_printf(file
, "\n");
3106 lf_printf(file
, "#ifndef MODEL_CYCLES\n");
3107 lf_printf(file
, "#define MODEL_CYCLES unsigned16\n");
3108 lf_printf(file
, "#endif\n");
3109 lf_printf(file
, "\n");
3112 lf_printf(file
, "#ifndef MODEL_UNITS\n");
3113 lf_printf(file
, "#define MODEL_UNITS unsigned16\n");
3114 lf_printf(file
, "#endif\n");
3115 lf_printf(file
, "\n");
3117 lf_printf(file
, "#ifndef MODEL_CYCLES\n");
3118 lf_printf(file
, "#define MODEL_CYCLES unsigned8\n");
3119 lf_printf(file
, "#endif\n");
3120 lf_printf(file
, "\n");
3123 lf_printf(file
, "#ifndef MODEL_FLAGS\n");
3124 lf_printf(file
, "#define MODEL_FLAGS unsigned32\n");
3125 lf_printf(file
, "#endif\n");
3126 lf_printf(file
, "\n");
3128 lf_printf(file
, "typedef struct _model_time {\t/* Instruction cycle time */\n");
3129 lf_printf(file
, " MODEL_UNITS units;\n");
3130 lf_printf(file
, " MODEL_CYCLES initial;\n");
3131 lf_printf(file
, " MODEL_CYCLES finish;\n");
3132 lf_printf(file
, " MODEL_FLAGS flags;\n");
3133 lf_printf(file
, "} model_time;\n");
3134 lf_printf(file
, "\n");
3136 lf_printf(file
, "typedef enum _model_enum {\n");
3137 lf_printf(file
, " MODEL_NONE,\n");
3138 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3139 lf_printf(file
, " MODEL_%s,\n", model_ptr
->name
);
3141 lf_printf(file
, " nr_models\n");
3142 lf_printf(file
, "} model_enum;\n");
3143 lf_printf(file
, "\n");
3145 lf_printf(file
, "#define DEFAULT_MODEL MODEL_%s\n", (models
) ? models
->name
: "NONE");
3146 lf_printf(file
, "\n");
3148 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3149 for (func_unit_ptr
= model_ptr
->func_unit_start
; func_unit_ptr
; func_unit_ptr
= func_unit_ptr
->next
) {
3150 if (func_unit_ptr
->comment
) {
3151 lf_printf(file
, "#define %-*s 0x%.*x /* %s functional unit */\n",
3152 table
->max_func_unit_name_len
, func_unit_ptr
->name
,
3153 hex_size
, func_unit_ptr
->mask
,
3154 func_unit_ptr
->comment
);
3156 lf_printf(file
, "#define %-*s 0x%.*x\n",
3157 table
->max_func_unit_name_len
, func_unit_ptr
->name
,
3158 hex_size
, func_unit_ptr
->mask
);
3161 lf_printf(file
, "\n");
3164 lf_printf(file
, "extern model_enum current_model;\n");
3165 lf_printf(file
, "extern const char *model_name[ (int)nr_models ];\n");
3166 lf_printf(file
, "extern const char *const *const model_func_unit_name[ (int)nr_models ];\n");
3167 lf_printf(file
, "extern const model_time *const model_time_mapping[ (int)nr_models ];\n");
3168 lf_printf(file
, "\n");
3169 lf_printf(file
, "INLINE_MODEL void model_set\n");
3170 lf_printf(file
, "(const char *name);\n");
3172 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3173 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3174 lf_printf(file
, "\n");
3177 lf_printf(file
, "\n");
3178 lf_printf(file
, "#endif /* _MODEL_H_ */\n");
3181 /****************************************************************/
3183 typedef struct _model_c_passed_data model_c_passed_data
;
3184 struct _model_c_passed_data
{
3190 model_c_insn(insn_table
*entry
,
3194 model_c_passed_data
*data_ptr
= (model_c_passed_data
*)data
;
3195 lf
*file
= data_ptr
->file
;
3196 char *current_name
= data_ptr
->model_ptr
->name
;
3197 table_model_entry
*model_ptr
= instruction
->file_entry
->model_first
;
3201 if (model_ptr
->fields
[insn_model_name
] == current_name
) {
3202 lf_printf(file
, " {");
3203 for(i
= insn_model_unit
; i
< nr_insn_model_table_fields
; i
++) {
3204 lf_printf(file
, " %s,", model_ptr
->fields
[i
]);
3206 lf_printf(file
, " }, /* %s */\n", instruction
->file_entry
->fields
[insn_name
]);
3210 model_ptr
= model_ptr
->next
;
3213 lf_printf(file
, " { %s_SENTINEL },\n", current_name
);
3217 model_c_function(insn_table
*table
,
3219 table_entry
*function
,
3222 if (function
->fields
[function_type
] == NULL
3223 || function
->fields
[function_type
][0] == '\0') {
3224 error("Model function return type not specified for %s", function
->fields
[function_name
]);
3227 lf_printf(file
, "\n");
3228 lf_printf(file
, "%s %s\n%s(%s)\n",
3230 function
->fields
[function_type
],
3231 function
->fields
[function_name
],
3232 function
->fields
[function_param
]);
3234 table_entry_lf_c_line_nr(file
, function
);
3235 lf_printf(file
, "{\n");
3236 if (function
->annex
) {
3237 lf_indent(file
, +2);
3238 lf_print_c_code(file
, function
->annex
);
3239 lf_indent(file
, -2);
3241 lf_printf(file
, "}\n");
3242 lf_print_lf_c_line_nr(file
);
3243 lf_printf(file
, "\n");
3247 gen_model_c(insn_table
*table
, lf
*file
)
3251 model_func_unit
*func_unit_ptr
;
3254 lf_print_copyleft(file
);
3255 lf_printf(file
, "\n");
3256 lf_printf(file
, "#ifndef _MODEL_C_\n");
3257 lf_printf(file
, "#define _MODEL_C_\n");
3258 lf_printf(file
, "\n");
3259 lf_printf(file
, "#include \"cpu.h\"\n");
3260 lf_printf(file
, "\n");
3262 for(insn_ptr
= model_data
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3263 model_c_or_h_data(table
, file
, insn_ptr
->file_entry
);
3266 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3267 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3270 lf_printf(file
, "/* map model enumeration into printable string */\n");
3271 lf_printf(file
, "const char *model_name[ (int)nr_models ] = {\n");
3272 lf_printf(file
, " \"NONE\",\n");
3273 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3274 lf_printf(file
, " \"%s\",\n", model_ptr
->printable_name
);
3276 lf_printf(file
, "};\n");
3277 lf_printf(file
, "\n");
3279 lf_printf(file
, "/* Emit each model's individual function unit names */\n");
3280 lf_printf(file
, "static const char *const model_func_unit_name_NONE[] = {\n");
3281 lf_printf(file
, " \"none\",\n");
3282 lf_printf(file
, " (const char *)0\n");
3283 lf_printf(file
, "};\n");
3284 lf_printf(file
, "\n");
3286 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3287 lf_printf(file
, "static const char *const model_func_unit_name_%s[] = {\n", model_ptr
->name
);
3288 lf_printf(file
, " \"none\",\n");
3289 for (func_unit_ptr
= model_ptr
->func_unit_start
; func_unit_ptr
; func_unit_ptr
= func_unit_ptr
->next
) {
3291 if (func_unit_ptr
->comment
)
3292 lf_printf(file
, " \"%s %s functional unit\",\n", func_unit_ptr
->name
, func_unit_ptr
->comment
);
3294 lf_printf(file
, " \"%s\",\n", func_unit_ptr
->name
);
3296 for(i
= 2; i
< func_unit_ptr
->number
; i
++) {
3297 if (func_unit_ptr
->comment
)
3298 lf_printf(file
, " \"%s %s functional unit #%d\",\n", func_unit_ptr
->name
,
3299 func_unit_ptr
->comment
, i
);
3301 lf_printf(file
, " \"%s #%d\",\n", func_unit_ptr
->name
, i
);
3305 lf_printf(file
, " (const char *)0\n");
3306 lf_printf(file
, "};\n");
3307 lf_printf(file
, "\n");
3310 lf_printf(file
, "/* Array to map model,function unit number to printable string. */\n");
3311 lf_printf(file
, "const char *const *const model_func_unit_name[] = {\n");
3312 lf_printf(file
, " model_func_unit_name_NONE,\n");
3313 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3314 lf_printf(file
, " model_func_unit_name_%s,\n", model_ptr
->name
);
3316 lf_printf(file
, "};\n");
3317 lf_printf(file
, "\n");
3318 lf_printf(file
, "\f\n");
3320 lf_printf(file
, "/* Insn functional unit info */\n");
3321 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3322 model_c_passed_data data
;
3324 lf_printf(file
, "static const model_time model_time_%s[] = {\n", model_ptr
->name
);
3326 data
.model_ptr
= model_ptr
;
3327 insn_table_traverse_insn(table
,
3331 lf_printf(file
, "};\n");
3332 lf_printf(file
, "\n");
3333 lf_printf(file
, "\f\n");
3336 lf_printf(file
, "const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3337 lf_printf(file
, " (const model_time *const)0,\n");
3338 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3339 lf_printf(file
, " model_time_%s,\n", model_ptr
->name
);
3341 lf_printf(file
, "};\n");
3342 lf_printf(file
, "\n");
3344 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3345 model_c_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3348 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3349 model_c_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3352 lf_printf(file
, "INLINE_MODEL void\n");
3353 lf_printf(file
, "model_set(const char *name)\n");
3354 lf_printf(file
, "{\n");
3356 lf_printf(file
, " model_enum model;\n");
3357 lf_printf(file
, " for(model = MODEL_%s; model < nr_models; model++) {\n", models
->name
);
3358 lf_printf(file
, " if(strcasecmp(name, model_name[model]) == 0) {\n");
3359 lf_printf(file
, " current_model = model;\n");
3360 lf_printf(file
, " return;\n");
3361 lf_printf(file
, " }\n");
3362 lf_printf(file
, " }\n");
3363 lf_printf(file
, "\n");
3364 lf_printf(file
, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3365 lf_printf(file
, " name,\n");
3366 lf_printf(file
, " \"");
3367 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3368 lf_printf(file
, "\\n\\t%s", model_ptr
->printable_name
);
3370 lf_printf(file
, "\");\n");
3372 lf_printf(file
, " error(\"No models are currently known about\");\n");
3375 lf_printf(file
, "}\n");
3376 lf_printf(file
, "\n");
3378 lf_printf(file
, "#endif /* _MODEL_C_ */\n");
3382 /****************************************************************/
3390 insn_table
*instructions
= NULL
;
3391 icache_tree
*cache_fields
= NULL
;
3392 char *real_file_name
= NULL
;
3397 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
3398 printf("Config options:\n");
3399 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
3400 printf(" -e Expand (duplicate) semantic functions\n");
3401 printf(" -r <icache-size> Generate cracking cache version\n");
3402 printf(" -l Supress line numbering in output files\n");
3403 printf(" -b <bit-size> Set the number of bits in an instruction\n");
3404 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
3405 printf("Input options (ucase version also dumps loaded table):\n");
3406 printf(" -[Oo] <opcode-rules>\n");
3407 printf(" -[Kk] <cache-rules>\n");
3408 printf(" -[Ii] <instruction-table>\n");
3409 printf("Output options:\n");
3410 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
3411 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
3412 printf(" -[Mm] <output-file> output model.h(M) model.c(M)\n");
3413 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
3414 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
3417 while ((ch
= getopt(argc
, argv
,
3418 "leb:h:r:f:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
3419 fprintf(stderr
, "\t-%c %s\n", ch
, (optarg
? optarg
: ""));
3425 idecode_expand_semantics
= 1;
3428 idecode_cache
= a2i(optarg
);
3431 insn_size
= a2i(optarg
);
3432 ASSERT(insn_size
> 0 && insn_size
<= max_insn_size
3433 && (hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0));
3436 hi_bit_nr
= a2i(optarg
);
3437 ASSERT(hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0);
3441 filter
*new_filter
= ZALLOC(filter
);
3442 new_filter
->flag
= strdup(optarg
);
3443 new_filter
->next
= filters
;
3444 filters
= new_filter
;
3449 ASSERT(opcode_table
!= NULL
);
3450 ASSERT(cache_table
!= NULL
);
3451 instructions
= insn_table_load_insns(optarg
);
3452 fprintf(stderr
, "\texpanding ...\n");
3453 insn_table_expand_insns(instructions
);
3454 fprintf(stderr
, "\tcache fields ...\n");
3455 cache_fields
= insn_table_cache_fields(instructions
);
3457 dump_traverse(instructions
);
3458 dump_insn_table(instructions
, 0, 1);
3463 opcode_table
= load_opcode_rules(optarg
);
3465 dump_opcode_rules(opcode_table
, 0);
3469 cache_table
= load_cache_rules(optarg
);
3471 dump_cache_rules(cache_table
, 0);
3474 real_file_name
= strdup(optarg
);
3486 lf
*file
= lf_open(optarg
, real_file_name
, number_lines
);
3487 ASSERT(instructions
!= NULL
);
3490 gen_semantics_h(instructions
, file
);
3493 gen_semantics_c(instructions
, file
);
3496 gen_idecode_h(instructions
, file
);
3499 gen_idecode_c(instructions
, file
);
3502 gen_model_h(instructions
, file
);
3505 gen_model_c(instructions
, file
);
3508 gen_itable_h(instructions
, file
);
3511 gen_itable_c(instructions
, file
);
3514 gen_icache_h(cache_fields
, file
);
3519 real_file_name
= NULL
;
3522 error("unknown option\n");