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(lf
*file
,
2273 insn_bits
*expanded_bits
,
2274 opcode_field
*opcodes
,
2275 int is_inline_function
)
2278 /* build the semantic routine to execute the instruction */
2279 lf_print_semantic_function_header(file
,
2280 instruction
->file_entry
->fields
[insn_name
],
2282 1/*is-function-definition*/,
2283 is_inline_function
);
2284 lf_print_c_semantic(file
,
2292 semantics_c_leaf(insn_table
*entry
,
2296 lf
*file
= (lf
*)data
;
2297 ASSERT(entry
->nr_insn
== 1
2298 && entry
->opcode
== NULL
2299 && entry
->parent
!= NULL
2300 && entry
->parent
->opcode
!= NULL
);
2301 lf_print_c_semantic_function(file
,
2303 entry
->expanded_bits
,
2304 entry
->parent
->opcode
,
2305 !idecode_cache
&& entry
->parent
->opcode_rule
->use_switch
);
2309 semantics_c_insn(insn_table
*table
,
2313 lf
*file
= (lf
*)data
;
2314 lf_print_c_semantic_function(file
, instruction
,
2316 0/*isnt_inline_function*/);
2320 semantics_c_function(insn_table
*table
,
2322 table_entry
*function
)
2324 lf
*file
= (lf
*)data
;
2325 if (function
->fields
[function_type
] == NULL
2326 || function
->fields
[function_type
][0] == '\0') {
2327 lf_print_semantic_function_header(file
,
2328 function
->fields
[function_name
],
2330 1/*is function definition*/,
2331 1/*is inline function*/);
2334 lf_printf(file
, "\n");
2335 lf_printf(file
, "INLINE_SEMANTICS %s\n%s(%s)\n",
2336 function
->fields
[function_type
],
2337 function
->fields
[function_name
],
2338 function
->fields
[function_param
]);
2340 table_entry_lf_c_line_nr(file
, function
);
2341 lf_printf(file
, "{\n");
2342 lf_indent(file
, +2);
2343 lf_print_c_code(file
, function
->annex
);
2344 lf_indent(file
, -2);
2345 lf_printf(file
, "}\n");
2346 lf_print_lf_c_line_nr(file
);
2352 gen_semantics_c(insn_table
*table
, lf
*file
)
2354 lf_print_copyleft(file
);
2355 lf_printf(file
, "\n");
2356 lf_printf(file
, "#ifndef _SEMANTICS_C_\n");
2357 lf_printf(file
, "#define _SEMANTICS_C_\n");
2358 lf_printf(file
, "\n");
2359 lf_printf(file
, "#ifndef STATIC_INLINE_SEMANTICS\n");
2360 lf_printf(file
, "#define STATIC_INLINE_SEMANTICS STATIC_INLINE\n");
2361 lf_printf(file
, "#endif\n");
2362 lf_printf(file
, "\n");
2363 lf_printf(file
, "#include \"cpu.h\"\n");
2364 lf_printf(file
, "#include \"idecode.h\"\n");
2365 lf_printf(file
, "#include \"semantics.h\"\n");
2366 lf_printf(file
, "\n");
2368 /* output a definition (c-code) for all functions */
2369 insn_table_traverse_function(table
,
2371 semantics_c_function
);
2373 /* output a definition (c-code) for all instructions */
2374 if (idecode_expand_semantics
)
2375 insn_table_traverse_tree(table
,
2381 NULL
); /* padding */
2383 insn_table_traverse_insn(table
,
2387 lf_printf(file
, "\n");
2388 lf_printf(file
, "#endif /* _SEMANTICS_C_ */\n");
2392 /****************************************************************/
2395 gen_idecode_h(insn_table
*table
, lf
*file
)
2397 lf_print_copyleft(file
);
2398 lf_printf(file
, "\n");
2399 lf_printf(file
, "#ifndef _IDECODE_H_\n");
2400 lf_printf(file
, "#define _IDECODE_H_\n");
2401 lf_printf(file
, "\n");
2402 lf_printf(file
, "#ifndef INLINE_IDECODE\n");
2403 lf_printf(file
, "#define INLINE_IDECODE\n");
2404 lf_printf(file
, "#endif\n");
2405 lf_printf(file
, "\n");
2406 lf_printf(file
, "#include \"idecode_expression.h\"\n");
2407 lf_printf(file
, "#include \"idecode_fields.h\"\n");
2408 lf_printf(file
, "#include \"idecode_branch.h\"\n");
2409 lf_printf(file
, "\n");
2410 lf_printf(file
, "#include \"icache.h\"\n");
2411 lf_printf(file
, "\n");
2412 lf_printf(file
, "typedef unsigned_word idecode_semantic\n(%s);\n",
2413 (idecode_cache
? cache_semantic_formal
: semantic_formal
));
2414 lf_printf(file
, "\n");
2416 lf_printf(file
, "INLINE_IDECODE idecode_semantic *idecode\n(%s);\n",
2417 cache_idecode_formal
);
2419 lf_printf(file
, "INLINE_IDECODE unsigned_word idecode_issue\n(%s);\n",
2421 lf_printf(file
, "\n");
2422 lf_printf(file
, "#endif /* _IDECODE_H_ */\n");
2426 /****************************************************************/
2430 idecode_table_start(insn_table
*table
,
2434 lf
*file
= (lf
*)data
;
2436 /* start of the table */
2437 if (!table
->opcode_rule
->use_switch
) {
2438 lf_printf(file
, "\n");
2439 lf_printf(file
, "static idecode_table_entry ");
2440 lf_print_table_name(file
, table
);
2441 lf_printf(file
, "[] = {\n");
2446 idecode_table_leaf(insn_table
*entry
,
2450 lf
*file
= (lf
*)data
;
2451 ASSERT(entry
->parent
!= NULL
);
2454 /* add an entry to the table */
2455 if (!entry
->parent
->opcode_rule
->use_switch
) {
2456 if (entry
->opcode
== NULL
) {
2457 /* table leaf entry */
2458 lf_printf(file
, " /*%d*/ { 0, 0, ", entry
->opcode_nr
);
2459 lf_print_function_name(file
,
2460 entry
->insns
->file_entry
->fields
[insn_name
],
2461 entry
->expanded_bits
,
2463 ? function_name_prefix_idecode
2464 : function_name_prefix_semantics
));
2465 lf_printf(file
, " },\n");
2467 else if (entry
->opcode_rule
->use_switch
) {
2468 /* table calling switch statement */
2469 lf_printf(file
, " /*%d*/ { 0, 0, ",
2471 lf_print_table_name(file
, entry
);
2472 lf_printf(file
, " },\n");
2475 /* table `calling' another table */
2476 lf_printf(file
, " /*%d*/ { ", entry
->opcode_nr
);
2477 if (entry
->opcode
->is_boolean
)
2478 lf_printf(file
, "MASK32(%d,%d), 0, ",
2479 i2target(hi_bit_nr
, entry
->opcode
->first
),
2480 i2target(hi_bit_nr
, entry
->opcode
->last
));
2482 lf_printf(file
, "%d, MASK32(%d,%d), ",
2483 insn_size
- entry
->opcode
->last
- 1,
2484 i2target(hi_bit_nr
, entry
->opcode
->first
),
2485 i2target(hi_bit_nr
, entry
->opcode
->last
));
2486 lf_print_table_name(file
, entry
);
2487 lf_printf(file
, " },\n");
2493 idecode_table_end(insn_table
*table
,
2497 lf
*file
= (lf
*)data
;
2500 if (!table
->opcode_rule
->use_switch
) {
2501 lf_printf(file
, "};\n");
2506 idecode_table_padding(insn_table
*table
,
2511 lf
*file
= (lf
*)data
;
2514 if (!table
->opcode_rule
->use_switch
) {
2515 lf_printf(file
, " /*%d*/ { 0, 0, %s_illegal },\n",
2516 opcode_nr
, (idecode_cache
? "idecode" : "semantic"));
2521 /****************************************************************/
2524 void lf_print_idecode_switch
2530 idecode_switch_start(insn_table
*table
,
2534 lf
*file
= (lf
*)data
;
2536 ASSERT(table
->opcode_rule
->use_switch
);
2538 lf_printf(file
, "switch (EXTRACTED32(instruction, %d, %d)) {\n",
2539 i2target(hi_bit_nr
, table
->opcode
->first
),
2540 i2target(hi_bit_nr
, table
->opcode
->last
));
2545 idecode_switch_leaf(insn_table
*entry
,
2549 lf
*file
= (lf
*)data
;
2550 ASSERT(entry
->parent
!= NULL
);
2552 ASSERT(entry
->parent
->opcode_rule
->use_switch
);
2553 ASSERT(entry
->parent
->opcode
);
2555 if (!entry
->parent
->opcode
->is_boolean
2556 || entry
->opcode_nr
== 0)
2557 lf_printf(file
, "case %d:\n", entry
->opcode_nr
);
2559 lf_printf(file
, "default:\n");
2560 lf_indent(file
, +2);
2562 if (entry
->opcode
== NULL
) {
2563 /* switch calling leaf */
2564 lf_printf(file
, "return ");
2565 lf_print_function_name(file
,
2566 entry
->insns
->file_entry
->fields
[insn_name
],
2567 entry
->expanded_bits
,
2569 ? function_name_prefix_idecode
2570 : function_name_prefix_semantics
));
2572 lf_printf(file
, "(%s);\n", cache_idecode_actual
);
2574 lf_printf(file
, "(%s);\n", semantic_actual
);
2576 else if (entry
->opcode_rule
->use_switch
) {
2577 /* switch calling switch */
2578 lf_print_idecode_switch(file
, entry
);
2581 /* switch looking up a table */
2582 lf_print_idecode_table(file
, entry
);
2584 lf_printf(file
, "break;\n");
2586 lf_indent(file
, -2);
2591 lf_print_idecode_switch_illegal(lf
*file
)
2593 lf_indent(file
, +2);
2594 lf_print_idecode_illegal(file
);
2595 lf_printf(file
, "break;\n");
2596 lf_indent(file
, -2);
2600 idecode_switch_end(insn_table
*table
,
2604 lf
*file
= (lf
*)data
;
2606 ASSERT(table
->opcode_rule
->use_switch
);
2607 ASSERT(table
->opcode
);
2609 if (table
->opcode_rule
->use_switch
== 1
2610 && !table
->opcode
->is_boolean
) {
2611 lf_printf(file
, "default:\n");
2612 lf_print_idecode_switch_illegal(file
);
2614 lf_printf(file
, "}\n");
2618 idecode_switch_padding(insn_table
*table
,
2623 lf
*file
= (lf
*)data
;
2626 ASSERT(table
->opcode_rule
->use_switch
);
2628 if (table
->opcode_rule
->use_switch
> 1) {
2629 lf_printf(file
, "case %d:\n", opcode_nr
);
2630 lf_print_idecode_switch_illegal(file
);
2636 lf_print_idecode_switch(lf
*file
,
2639 insn_table_traverse_tree(table
,
2642 idecode_switch_start
,
2643 idecode_switch_leaf
,
2645 idecode_switch_padding
);
2650 lf_print_idecode_switch_function_header(lf
*file
,
2652 int is_function_definition
)
2654 lf_printf(file
, "\n");
2655 lf_printf(file
, "static ");
2657 lf_printf(file
, "idecode_semantic *");
2659 lf_printf(file
, "unsigned_word");
2660 if (is_function_definition
)
2661 lf_printf(file
, "\n");
2663 lf_printf(file
, " ");
2664 lf_print_table_name(file
, table
);
2665 lf_printf(file
, "\n(%s)",
2666 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2667 if (!is_function_definition
)
2668 lf_printf(file
, ";");
2669 lf_printf(file
, "\n");
2674 idecode_declare_if_switch(insn_table
*table
,
2678 lf
*file
= (lf
*)data
;
2680 if (table
->opcode_rule
->use_switch
2681 && table
->parent
!= NULL
/* don't declare the top one yet */
2682 && !table
->parent
->opcode_rule
->use_switch
) {
2683 lf_print_idecode_switch_function_header(file
,
2685 0/*isnt function definition*/);
2691 idecode_expand_if_switch(insn_table
*table
,
2695 lf
*file
= (lf
*)data
;
2697 if (table
->opcode_rule
->use_switch
2698 && table
->parent
!= NULL
/* don't expand the top one yet */
2699 && !table
->parent
->opcode_rule
->use_switch
) {
2700 lf_print_idecode_switch_function_header(file
,
2702 1/*is function definition*/);
2703 lf_printf(file
, "{\n");
2705 lf_indent(file
, +2);
2706 lf_print_idecode_switch(file
, table
);
2707 lf_indent(file
, -2);
2709 lf_printf(file
, "}\n");
2715 lf_print_c_cracker_function(lf
*file
,
2717 insn_bits
*expanded_bits
,
2718 opcode_field
*opcodes
,
2719 int is_inline_function
)
2721 /* if needed, generate code to enter this routine into a cache */
2722 lf_printf(file
, "\n");
2723 lf_printf(file
, "STATIC_IDECODE idecode_semantic *\n");
2724 lf_print_function_name(file
,
2725 instruction
->file_entry
->fields
[insn_name
],
2727 function_name_prefix_idecode
);
2728 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2730 lf_print_c_cracker(file
,
2737 idecode_crack_leaf(insn_table
*entry
,
2741 lf
*file
= (lf
*)data
;
2742 ASSERT(entry
->nr_insn
== 1
2743 && entry
->opcode
== NULL
2744 && entry
->parent
!= NULL
2745 && entry
->parent
->opcode
!= NULL
2746 && entry
->parent
->opcode_rule
!= NULL
);
2747 lf_print_c_cracker_function(file
,
2749 entry
->expanded_bits
,
2751 entry
->parent
->opcode_rule
->use_switch
);
2755 idecode_crack_insn(insn_table
*entry
,
2759 lf
*file
= (lf
*)data
;
2760 lf_print_c_cracker_function(file
,
2764 0/*isnt inline function*/);
2768 idecode_c_internal_function(insn_table
*table
,
2770 table_entry
*function
)
2772 lf
*file
= (lf
*)data
;
2773 ASSERT(idecode_cache
!= 0);
2774 if (it_is("internal", function
->fields
[insn_flags
])) {
2775 lf_printf(file
, "\n");
2776 lf_printf(file
, "STATIC_INLINE_IDECODE idecode_semantic *\n");
2777 lf_print_function_name(file
,
2778 function
->fields
[insn_name
],
2780 function_name_prefix_idecode
);
2781 lf_printf(file
, "\n(%s)\n", cache_idecode_formal
);
2782 lf_printf(file
, "{\n");
2783 lf_indent(file
, +2);
2784 lf_printf(file
, "/* semantic routine */\n");
2785 table_entry_lf_c_line_nr(file
, function
);
2786 lf_printf(file
, "return ");
2787 lf_print_function_name(file
,
2788 function
->fields
[insn_name
],
2790 function_name_prefix_semantics
);
2791 lf_printf(file
, ";\n");
2793 lf_print_lf_c_line_nr(file
);
2794 lf_indent(file
, -2);
2795 lf_printf(file
, "}\n");
2800 /****************************************************************/
2803 gen_idecode_c(insn_table
*table
, lf
*file
)
2808 lf_print_copyleft(file
);
2809 lf_printf(file
, "\n");
2810 lf_printf(file
, "\n");
2811 lf_printf(file
, "#ifndef _IDECODE_C_\n");
2812 lf_printf(file
, "#define _IDECODE_C_\n");
2813 lf_printf(file
, "\n");
2814 lf_printf(file
, "#ifndef STATIC_INLINE_IDECODE\n");
2815 lf_printf(file
, "#define STATIC_INLINE_IDECODE STATIC_INLINE\n");
2816 lf_printf(file
, "#endif\n");
2817 lf_printf(file
, "\n");
2818 lf_printf(file
, "#ifndef STATIC_IDECODE\n");
2819 lf_printf(file
, "#define STATIC_IDECODE\n");
2820 lf_printf(file
, "#endif\n");
2821 lf_printf(file
, "\n");
2822 lf_printf(file
, "#include \"cpu.h\"\n");
2823 lf_printf(file
, "#include \"idecode.h\"\n");
2824 lf_printf(file
, "#include \"semantics.h\"\n");
2825 lf_printf(file
, "\n");
2826 lf_printf(file
, "\n");
2827 lf_printf(file
, "typedef idecode_semantic *idecode_crack\n(%s);\n",
2828 (idecode_cache
? cache_idecode_formal
: semantic_formal
));
2829 lf_printf(file
, "\n");
2830 lf_printf(file
, "typedef struct _idecode_table_entry {\n");
2831 lf_printf(file
, " unsigned shift;\n");
2832 lf_printf(file
, " unsigned mask;\n");
2833 lf_printf(file
, " void *function_or_table;\n");
2834 lf_printf(file
, "} idecode_table_entry;\n");
2835 lf_printf(file
, "\n");
2836 lf_printf(file
, "\n");
2838 /* output `internal' invalid/floating-point unavailable functions
2840 if (idecode_cache
) {
2841 insn_table_traverse_function(table
,
2843 idecode_c_internal_function
);
2846 /* output cracking functions where needed */
2847 if (idecode_cache
) {
2848 if (idecode_expand_semantics
)
2849 insn_table_traverse_tree(table
,
2857 insn_table_traverse_insn(table
,
2859 idecode_crack_insn
);
2862 /* output switch function declarations where needed by tables */
2863 insn_table_traverse_tree(table
,
2866 idecode_declare_if_switch
, /* START */
2869 /* output tables where needed */
2870 for (depth
= insn_table_depth(table
);
2873 insn_table_traverse_tree(table
,
2876 idecode_table_start
,
2879 idecode_table_padding
);
2882 /* output switch functions where needed */
2883 insn_table_traverse_tree(table
,
2886 idecode_expand_if_switch
, /* START */
2889 /* output the main idecode routine */
2890 lf_printf(file
, "\n");
2892 lf_printf(file
, "INLINE_IDECODE idecode_semantic *\nidecode\n(%s)\n",
2893 cache_idecode_formal
);
2895 lf_printf(file
, "INLINE_IDECODE unsigned_word\nidecode_issue\n(%s)\n",
2897 lf_printf(file
, "{\n");
2898 lf_indent(file
, +2);
2899 if (table
->opcode_rule
->use_switch
)
2900 lf_print_idecode_switch(file
, table
);
2902 lf_print_idecode_table(file
, table
);
2903 lf_indent(file
, -2);
2904 lf_printf(file
, "}\n");
2905 lf_printf(file
, "\n");
2906 lf_printf(file
, "#endif /* _IDECODE_C_ */\n");
2910 /****************************************************************/
2913 itable_h_insn(insn_table
*entry
,
2917 lf
*file
= (lf
*)data
;
2918 lf_printf(file
, " ");
2919 lf_print_function_name(file
,
2920 instruction
->file_entry
->fields
[insn_name
],
2922 function_name_prefix_itable
);
2923 lf_printf(file
, ",\n");
2928 gen_itable_h(insn_table
*table
, lf
*file
)
2931 lf_print_copyleft(file
);
2932 lf_printf(file
, "\n");
2933 lf_printf(file
, "#ifndef _ITABLE_H_\n");
2934 lf_printf(file
, "#define _ITABLE_H_\n");
2935 lf_printf(file
, "\n");
2936 lf_printf(file
, "#ifndef INLINE_ITABLE\n");
2937 lf_printf(file
, "#define INLINE_ITABLE\n");
2938 lf_printf(file
, "#endif\n");
2939 lf_printf(file
, "\n");
2940 lf_printf(file
, "\n");
2942 /* output an enumerated type for each instruction */
2943 lf_printf(file
, "typedef enum {\n");
2944 insn_table_traverse_insn(table
,
2947 lf_printf(file
, " nr_itable_entries,\n");
2948 lf_printf(file
, "} itable_index;\n");
2949 lf_printf(file
, "\n");
2951 /* output the table that contains the actual instruction info */
2952 lf_printf(file
, "typedef struct _itable_instruction_info {\n");
2953 lf_printf(file
, " itable_index nr;\n");
2954 lf_printf(file
, " char *format;\n");
2955 lf_printf(file
, " char *form;\n");
2956 lf_printf(file
, " char *flags;\n");
2957 lf_printf(file
, " char *mnemonic;\n");
2958 lf_printf(file
, " char *name;\n");
2959 lf_printf(file
, "} itable_info;\n");
2960 lf_printf(file
, "\n");
2961 lf_printf(file
, "extern itable_info itable[nr_itable_entries];\n");
2963 lf_printf(file
, "\n");
2964 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
2968 /****************************************************************/
2971 itable_c_insn(insn_table
*entry
,
2975 lf
*file
= (lf
*)data
;
2976 char **fields
= instruction
->file_entry
->fields
;
2977 lf_printf(file
, " { ");
2978 lf_print_function_name(file
,
2979 instruction
->file_entry
->fields
[insn_name
],
2981 function_name_prefix_itable
);
2982 lf_printf(file
, ",\n");
2983 lf_printf(file
, " \"%s\",\n", fields
[insn_format
]);
2984 lf_printf(file
, " \"%s\",\n", fields
[insn_form
]);
2985 lf_printf(file
, " \"%s\",\n", fields
[insn_flags
]);
2986 lf_printf(file
, " \"%s\",\n", fields
[insn_mnemonic
]);
2987 lf_printf(file
, " \"%s\",\n", fields
[insn_name
]);
2988 lf_printf(file
, " },\n");
2993 gen_itable_c(insn_table
*table
, lf
*file
)
2996 lf_print_copyleft(file
);
2997 lf_printf(file
, "\n");
2998 lf_printf(file
, "#ifndef _ITABLE_C_\n");
2999 lf_printf(file
, "#define _ITABLE_C_\n");
3000 lf_printf(file
, "\n");
3001 lf_printf(file
, "#ifndef STATIC_INLINE_ITABLE\n");
3002 lf_printf(file
, "#define STATIC_INLINE_ITABLE STATIC_INLINE\n");
3003 lf_printf(file
, "#endif\n");
3004 lf_printf(file
, "\n");
3005 lf_printf(file
, "#include \"itable.h\"\n");
3006 lf_printf(file
, "\n");
3008 /* output the table that contains the actual instruction info */
3009 lf_printf(file
, "itable_info itable[nr_itable_entries] = {\n");
3010 insn_table_traverse_insn(table
,
3013 lf_printf(file
, "};\n");
3014 lf_printf(file
, "\n");
3016 lf_printf(file
, "\n");
3017 lf_printf(file
, "#endif /* _ITABLE_C_ */\n");
3020 /****************************************************************/
3023 model_c_or_h_data(insn_table
*table
,
3028 table_entry_lf_c_line_nr(file
, data
);
3029 lf_print_c_code(file
, data
->annex
);
3030 lf_print_lf_c_line_nr(file
);
3031 lf_printf(file
, "\n");
3036 model_c_or_h_function(insn_table
*entry
,
3038 table_entry
*function
,
3041 if (function
->fields
[function_type
] == NULL
3042 || function
->fields
[function_type
][0] == '\0') {
3043 error("Model function type not specified for %s", function
->fields
[function_name
]);
3046 lf_printf(file
, "\n");
3047 lf_printf(file
, "%s %s %s\n(%s);\n",
3049 function
->fields
[function_type
],
3050 function
->fields
[function_name
],
3051 function
->fields
[function_param
]);
3053 lf_printf(file
, "\n");
3057 gen_model_h(insn_table
*table
, lf
*file
)
3061 model_func_unit
*func_unit_ptr
;
3065 lf_print_copyleft(file
);
3066 lf_printf(file
, "\n");
3067 lf_printf(file
, "#ifndef _MODEL_H_\n");
3068 lf_printf(file
, "#define _MODEL_H_\n");
3069 lf_printf(file
, "\n");
3071 for(macro
= model_macros
; macro
; macro
= macro
->next
) {
3072 model_c_or_h_data(table
, file
, macro
->file_entry
);
3075 lf_printf(file
, "#ifndef INLINE_MODEL\n");
3076 lf_printf(file
, "#define INLINE_MODEL\n");
3077 lf_printf(file
, "#endif\n");
3078 lf_printf(file
, "#ifndef STATIC_INLINE_MODEL\n");
3079 lf_printf(file
, "#define STATIC_INLINE_MODEL STATIC_INLINE\n");
3080 lf_printf(file
, "#endif\n");
3081 lf_printf(file
, "\n");
3082 lf_printf(file
, "#ifndef STATIC_MODEL\n");
3083 lf_printf(file
, "#define STATIC_MODEL\n");
3084 lf_printf(file
, "#endif\n");
3085 lf_printf(file
, "\n");
3086 lf_printf(file
, "#ifndef EXTERN_MODEL\n");
3087 lf_printf(file
, "#define EXTERN_MODEL extern\n");
3088 lf_printf(file
, "#endif\n");
3089 lf_printf(file
, "\n");
3091 if (table
->max_func_unit_mask
> 0xffff) {
3093 lf_printf(file
, "#ifndef MODEL_UNITS\n");
3094 lf_printf(file
, "#define MODEL_UNITS unsigned32\n");
3095 lf_printf(file
, "#endif\n");
3096 lf_printf(file
, "\n");
3098 lf_printf(file
, "#ifndef MODEL_CYCLES\n");
3099 lf_printf(file
, "#define MODEL_CYCLES unsigned16\n");
3100 lf_printf(file
, "#endif\n");
3101 lf_printf(file
, "\n");
3104 lf_printf(file
, "#ifndef MODEL_UNITS\n");
3105 lf_printf(file
, "#define MODEL_UNITS unsigned16\n");
3106 lf_printf(file
, "#endif\n");
3107 lf_printf(file
, "\n");
3109 lf_printf(file
, "#ifndef MODEL_CYCLES\n");
3110 lf_printf(file
, "#define MODEL_CYCLES unsigned8\n");
3111 lf_printf(file
, "#endif\n");
3112 lf_printf(file
, "\n");
3115 lf_printf(file
, "#ifndef MODEL_FLAGS\n");
3116 lf_printf(file
, "#define MODEL_FLAGS unsigned32\n");
3117 lf_printf(file
, "#endif\n");
3118 lf_printf(file
, "\n");
3120 lf_printf(file
, "typedef struct _model_time {\t/* Instruction cycle time */\n");
3121 lf_printf(file
, " MODEL_UNITS units;\n");
3122 lf_printf(file
, " MODEL_CYCLES initial;\n");
3123 lf_printf(file
, " MODEL_CYCLES finish;\n");
3124 lf_printf(file
, " MODEL_FLAGS flags;\n");
3125 lf_printf(file
, "} model_time;\n");
3126 lf_printf(file
, "\n");
3128 lf_printf(file
, "typedef enum _model_enum {\n");
3129 lf_printf(file
, " MODEL_NONE,\n");
3130 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3131 lf_printf(file
, " MODEL_%s,\n", model_ptr
->name
);
3133 lf_printf(file
, " nr_models\n");
3134 lf_printf(file
, "} model_enum;\n");
3135 lf_printf(file
, "\n");
3137 lf_printf(file
, "#define DEFAULT_MODEL MODEL_%s\n", (models
) ? models
->name
: "NONE");
3138 lf_printf(file
, "\n");
3140 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3141 for (func_unit_ptr
= model_ptr
->func_unit_start
; func_unit_ptr
; func_unit_ptr
= func_unit_ptr
->next
) {
3142 if (func_unit_ptr
->comment
) {
3143 lf_printf(file
, "#define %-*s 0x%.*x /* %s functional unit */\n",
3144 table
->max_func_unit_name_len
, func_unit_ptr
->name
,
3145 hex_size
, func_unit_ptr
->mask
,
3146 func_unit_ptr
->comment
);
3148 lf_printf(file
, "#define %-*s 0x%.*x\n",
3149 table
->max_func_unit_name_len
, func_unit_ptr
->name
,
3150 hex_size
, func_unit_ptr
->mask
);
3153 lf_printf(file
, "\n");
3156 lf_printf(file
, "EXTERN_MODEL model_enum current_model;\n");
3157 lf_printf(file
, "EXTERN_MODEL const char *model_name[ (int)nr_models ];\n");
3158 lf_printf(file
, "EXTERN_MODEL const char *const *const model_func_unit_name[ (int)nr_models ];\n");
3159 lf_printf(file
, "EXTERN_MODEL const model_time *const model_time_mapping[ (int)nr_models ];\n");
3160 lf_printf(file
, "\n");
3161 lf_printf(file
, "INLINE_MODEL void model_set\n");
3162 lf_printf(file
, "(const char *name);\n");
3164 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3165 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3166 lf_printf(file
, "\n");
3169 lf_printf(file
, "\n");
3170 lf_printf(file
, "#endif /* _MODEL_H_ */\n");
3173 /****************************************************************/
3175 typedef struct _model_c_passed_data model_c_passed_data
;
3176 struct _model_c_passed_data
{
3182 model_c_insn(insn_table
*entry
,
3186 model_c_passed_data
*data_ptr
= (model_c_passed_data
*)data
;
3187 lf
*file
= data_ptr
->file
;
3188 char *current_name
= data_ptr
->model_ptr
->name
;
3189 table_model_entry
*model_ptr
= instruction
->file_entry
->model_first
;
3193 if (model_ptr
->fields
[insn_model_name
] == current_name
) {
3194 lf_printf(file
, " {");
3195 for(i
= insn_model_unit
; i
< nr_insn_model_table_fields
; i
++) {
3196 lf_printf(file
, " %s,", model_ptr
->fields
[i
]);
3198 lf_printf(file
, " }, /* %s */\n", instruction
->file_entry
->fields
[insn_name
]);
3202 model_ptr
= model_ptr
->next
;
3205 lf_printf(file
, " { %s_SENTINEL },\n", current_name
);
3209 model_c_function(insn_table
*table
,
3211 table_entry
*function
,
3214 if (function
->fields
[function_type
] == NULL
3215 || function
->fields
[function_type
][0] == '\0') {
3216 error("Model function return type not specified for %s", function
->fields
[function_name
]);
3219 lf_printf(file
, "\n");
3220 lf_printf(file
, "%s %s\n%s(%s)\n",
3222 function
->fields
[function_type
],
3223 function
->fields
[function_name
],
3224 function
->fields
[function_param
]);
3226 table_entry_lf_c_line_nr(file
, function
);
3227 lf_printf(file
, "{\n");
3228 if (function
->annex
) {
3229 lf_indent(file
, +2);
3230 lf_print_c_code(file
, function
->annex
);
3231 lf_indent(file
, -2);
3233 lf_printf(file
, "}\n");
3234 lf_print_lf_c_line_nr(file
);
3235 lf_printf(file
, "\n");
3239 gen_model_c(insn_table
*table
, lf
*file
)
3243 model_func_unit
*func_unit_ptr
;
3246 lf_print_copyleft(file
);
3247 lf_printf(file
, "\n");
3248 lf_printf(file
, "#ifndef _MODEL_C_\n");
3249 lf_printf(file
, "#define _MODEL_C_\n");
3250 lf_printf(file
, "\n");
3251 lf_printf(file
, "#include \"cpu.h\"\n");
3252 lf_printf(file
, "\n");
3254 for(insn_ptr
= model_data
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3255 model_c_or_h_data(table
, file
, insn_ptr
->file_entry
);
3258 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3259 model_c_or_h_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3262 lf_printf(file
, "/* map model enumeration into printable string */\n");
3263 lf_printf(file
, "STATIC_MODEL const char *model_name[ (int)nr_models ] = {\n");
3264 lf_printf(file
, " \"NONE\",\n");
3265 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3266 lf_printf(file
, " \"%s\",\n", model_ptr
->printable_name
);
3268 lf_printf(file
, "};\n");
3269 lf_printf(file
, "\n");
3271 lf_printf(file
, "/* Emit each model's individual function unit names */\n");
3272 lf_printf(file
, "static const char *const model_func_unit_name_NONE[] = {\n");
3273 lf_printf(file
, " \"none\",\n");
3274 lf_printf(file
, " (const char *)0\n");
3275 lf_printf(file
, "};\n");
3276 lf_printf(file
, "\n");
3278 for (model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3279 lf_printf(file
, "static const char *const model_func_unit_name_%s[] = {\n", model_ptr
->name
);
3280 lf_printf(file
, " \"none\",\n");
3281 for (func_unit_ptr
= model_ptr
->func_unit_start
; func_unit_ptr
; func_unit_ptr
= func_unit_ptr
->next
) {
3283 if (func_unit_ptr
->comment
)
3284 lf_printf(file
, " \"%s %s functional unit\",\n", func_unit_ptr
->name
, func_unit_ptr
->comment
);
3286 lf_printf(file
, " \"%s\",\n", func_unit_ptr
->name
);
3288 for(i
= 2; i
< func_unit_ptr
->number
; i
++) {
3289 if (func_unit_ptr
->comment
)
3290 lf_printf(file
, " \"%s %s functional unit #%d\",\n", func_unit_ptr
->name
,
3291 func_unit_ptr
->comment
, i
);
3293 lf_printf(file
, " \"%s #%d\",\n", func_unit_ptr
->name
, i
);
3297 lf_printf(file
, " (const char *)0\n");
3298 lf_printf(file
, "};\n");
3299 lf_printf(file
, "\n");
3302 lf_printf(file
, "/* Array to map model,function unit number to printable string. */\n");
3303 lf_printf(file
, "STATIC_MODEL const char *const *const model_func_unit_name[] = {\n");
3304 lf_printf(file
, " model_func_unit_name_NONE,\n");
3305 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3306 lf_printf(file
, " model_func_unit_name_%s,\n", model_ptr
->name
);
3308 lf_printf(file
, "};\n");
3309 lf_printf(file
, "\n");
3310 lf_printf(file
, "\f\n");
3312 lf_printf(file
, "/* Insn functional unit info */\n");
3313 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3314 model_c_passed_data data
;
3316 lf_printf(file
, "static const model_time model_time_%s[] = {\n", model_ptr
->name
);
3318 data
.model_ptr
= model_ptr
;
3319 insn_table_traverse_insn(table
,
3323 lf_printf(file
, "};\n");
3324 lf_printf(file
, "\n");
3325 lf_printf(file
, "\f\n");
3328 lf_printf(file
, "STATIC_MODEL const model_time *const model_time_mapping[ (int)nr_models ] = {\n");
3329 lf_printf(file
, " (const model_time *const)0,\n");
3330 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3331 lf_printf(file
, " model_time_%s,\n", model_ptr
->name
);
3333 lf_printf(file
, "};\n");
3334 lf_printf(file
, "\n");
3336 for(insn_ptr
= model_internal
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3337 model_c_function(table
, file
, insn_ptr
->file_entry
, "STATIC_INLINE_MODEL");
3340 for(insn_ptr
= model_functions
; insn_ptr
; insn_ptr
= insn_ptr
->next
) {
3341 model_c_function(table
, file
, insn_ptr
->file_entry
, "INLINE_MODEL");
3344 lf_printf(file
, "INLINE_MODEL void\n");
3345 lf_printf(file
, "model_set(const char *name)\n");
3346 lf_printf(file
, "{\n");
3348 lf_printf(file
, " model_enum model;\n");
3349 lf_printf(file
, " for(model = MODEL_%s; model < nr_models; model++) {\n", models
->name
);
3350 lf_printf(file
, " if(strcmp(name, model_name[model]) == 0) {\n");
3351 lf_printf(file
, " current_model = model;\n");
3352 lf_printf(file
, " return;\n");
3353 lf_printf(file
, " }\n");
3354 lf_printf(file
, " }\n");
3355 lf_printf(file
, "\n");
3356 lf_printf(file
, " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n");
3357 lf_printf(file
, " name,\n");
3358 lf_printf(file
, " \"");
3359 for(model_ptr
= models
; model_ptr
; model_ptr
= model_ptr
->next
) {
3360 lf_printf(file
, "\\n\\t%s", model_ptr
->printable_name
);
3362 lf_printf(file
, "\");\n");
3364 lf_printf(file
, " error(\"No models are currently known about\");\n");
3367 lf_printf(file
, "}\n");
3368 lf_printf(file
, "\n");
3370 lf_printf(file
, "#endif /* _MODEL_C_ */\n");
3374 /****************************************************************/
3382 insn_table
*instructions
= NULL
;
3383 icache_tree
*cache_fields
= NULL
;
3384 char *real_file_name
= NULL
;
3389 printf(" igen <config-opts> ... <input-opts>... <output-opts>...\n");
3390 printf("Config options:\n");
3391 printf(" -f <filter-out-flag> eg -f 64 to skip 64bit instructions\n");
3392 printf(" -e Expand (duplicate) semantic functions\n");
3393 printf(" -r <icache-size> Generate cracking cache version\n");
3394 printf(" -l Supress line numbering in output files\n");
3395 printf(" -b <bit-size> Set the number of bits in an instruction\n");
3396 printf(" -h <high-bit> Set the nr of the high (msb bit)\n");
3397 printf("Input options (ucase version also dumps loaded table):\n");
3398 printf(" -[Oo] <opcode-rules>\n");
3399 printf(" -[Kk] <cache-rules>\n");
3400 printf(" -[Ii] <instruction-table>\n");
3401 printf("Output options:\n");
3402 printf(" -[Cc] <output-file> output icache.h(C) invalid(c)\n");
3403 printf(" -[Dd] <output-file> output idecode.h(D) idecode.c(d)\n");
3404 printf(" -[Mm] <output-file> output model.h(M) model.c(M)\n");
3405 printf(" -[Ss] <output-file> output schematic.h(S) schematic.c(s)\n");
3406 printf(" -[Tt] <table> output itable.h(T) itable.c(t)\n");
3409 while ((ch
= getopt(argc
, argv
,
3410 "leb:h:r:f:I:i:O:o:K:k:M:m:n:S:s:D:d:T:t:C:")) != -1) {
3411 fprintf(stderr
, "\t-%c %s\n", ch
, (optarg
? optarg
: ""));
3417 idecode_expand_semantics
= 1;
3420 idecode_cache
= a2i(optarg
);
3423 insn_size
= a2i(optarg
);
3424 ASSERT(insn_size
> 0 && insn_size
<= max_insn_size
3425 && (hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0));
3428 hi_bit_nr
= a2i(optarg
);
3429 ASSERT(hi_bit_nr
== insn_size
-1 || hi_bit_nr
== 0);
3433 filter
*new_filter
= ZALLOC(filter
);
3434 new_filter
->flag
= strdup(optarg
);
3435 new_filter
->next
= filters
;
3436 filters
= new_filter
;
3441 ASSERT(opcode_table
!= NULL
);
3442 ASSERT(cache_table
!= NULL
);
3443 instructions
= insn_table_load_insns(optarg
);
3444 fprintf(stderr
, "\texpanding ...\n");
3445 insn_table_expand_insns(instructions
);
3446 fprintf(stderr
, "\tcache fields ...\n");
3447 cache_fields
= insn_table_cache_fields(instructions
);
3449 dump_traverse(instructions
);
3450 dump_insn_table(instructions
, 0, 1);
3455 opcode_table
= load_opcode_rules(optarg
);
3457 dump_opcode_rules(opcode_table
, 0);
3461 cache_table
= load_cache_rules(optarg
);
3463 dump_cache_rules(cache_table
, 0);
3466 real_file_name
= strdup(optarg
);
3478 lf
*file
= lf_open(optarg
, real_file_name
, number_lines
);
3479 ASSERT(instructions
!= NULL
);
3482 gen_semantics_h(instructions
, file
);
3485 gen_semantics_c(instructions
, file
);
3488 gen_idecode_h(instructions
, file
);
3491 gen_idecode_c(instructions
, file
);
3494 gen_model_h(instructions
, file
);
3497 gen_model_c(instructions
, file
);
3500 gen_itable_h(instructions
, file
);
3503 gen_itable_c(instructions
, file
);
3506 gen_icache_h(cache_fields
, file
);
3511 real_file_name
= NULL
;
3514 error("unknown option\n");