1 /* This file is part of the program psim.
3 Copyright (C) 1994-1998, 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.
29 #include "ld-decode.h"
33 #include "gen-semantics.h"
34 #include "gen-idecode.h"
35 #include "gen-icache.h"
40 print_icache_function_header (lf
*file
,
42 const char *format_name
,
43 opcode_bits
*expanded_bits
,
44 int is_function_definition
,
45 int nr_prefetched_words
)
47 lf_printf(file
, "\n");
48 lf_print__function_type_function (file
, print_icache_function_type
,
49 "EXTERN_ICACHE", " ");
50 print_function_name (file
,
51 basename
, format_name
, NULL
,
53 function_name_prefix_icache
);
54 lf_printf (file
, "\n(");
55 print_icache_function_formal (file
, nr_prefetched_words
);
56 lf_printf (file
, ")");
57 if (!is_function_definition
)
58 lf_printf (file
, ";");
59 lf_printf (file
, "\n");
64 print_icache_declaration (lf
*file
,
66 opcode_bits
*expanded_bits
,
67 insn_opcodes
*opcodes
,
68 int nr_prefetched_words
)
70 print_icache_function_header (file
,
74 0/* is not function definition */,
81 print_icache_extraction (lf
*file
,
82 const char *format_name
,
83 cache_entry_type cache_type
,
84 const char *entry_name
,
85 const char *entry_type
,
86 const char *entry_expression
,
87 char *single_insn_field
,
89 insn_field_entry
*cur_field
,
90 opcode_bits
*expanded_bits
,
91 icache_decl_type what_to_declare
,
92 icache_body_type what_to_do
)
94 const char *expression
;
97 ASSERT (format_name
!= NULL
);
98 ASSERT (entry_name
!= NULL
);
100 /* figure out exactly what should be going on here */
104 if ((what_to_do
& put_values_in_icache
)
105 || what_to_do
== do_not_use_icache
)
108 what_to_do
= do_not_use_icache
;
114 if ((what_to_do
& get_values_from_icache
)
115 || what_to_do
== do_not_use_icache
)
118 what_to_do
= do_not_use_icache
;
124 if ((what_to_declare
!= undef_variables
)
125 || !(what_to_do
& put_values_in_icache
))
128 what_to_declare
= ((what_to_do
& put_values_in_icache
)
136 abort (); /* Bad switch. */
139 /* For the type, default to a simple unsigned */
140 if (entry_type
== NULL
|| strlen (entry_type
) == 0)
141 entry_type
= "unsigned";
143 /* look through the set of expanded sub fields to see if this field
144 has been given a constant value */
145 for (bits
= expanded_bits
;
149 if (bits
->field
== cur_field
)
153 /* Define a storage area for the cache element */
154 switch (what_to_declare
)
156 case undef_variables
:
157 /* We've finished with the #define value - destory it */
158 lf_indent_suppress (file
);
159 lf_printf (file
, "#undef %s\n", entry_name
);
161 case define_variables
:
162 /* Using direct access for this entry, clear any prior
163 definition, then define it */
164 lf_indent_suppress (file
);
165 lf_printf (file
, "#undef %s\n", entry_name
);
166 /* Don't type cast pointer types! */
167 lf_indent_suppress (file
);
168 if (strchr (entry_type
, '*') != NULL
)
169 lf_printf (file
, "#define %s (", entry_name
);
171 lf_printf (file
, "#define %s ((%s) ", entry_name
, entry_type
);
173 case declare_variables
:
174 /* using variables to define the value */
176 lf_print__line_ref (file
, line
);
177 lf_printf (file
, "%s const %s UNUSED = ", entry_type
, entry_name
);
182 /* define a value for that storage area as determined by what is in
185 && single_insn_field
!= NULL
186 && strcmp (entry_name
, single_insn_field
) == 0
187 && strcmp (entry_name
, cur_field
->val_string
) == 0
188 && ((bits
->opcode
->is_boolean
&& bits
->value
== 0)
189 || (!bits
->opcode
->is_boolean
)))
191 /* The cache rule is specifying what to do with a simple
194 Because of instruction expansion, the field is either a
195 constant value or equal to the specified constant (boolean
196 comparison). (The latter indicated by bits->value == 0).
198 The case of a field not being equal to the specified boolean
199 value is handled later. */
200 expression
= "constant field";
201 ASSERT (bits
->field
== cur_field
);
202 if (bits
->opcode
->is_boolean
)
204 ASSERT (bits
->value
== 0);
205 lf_printf (file
, "%d", bits
->opcode
->boolean_constant
);
207 else if (bits
->opcode
->last
< bits
->field
->last
)
209 lf_printf (file
, "%d",
210 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
214 lf_printf (file
, "%d", bits
->value
);
217 else if (bits
!= NULL
218 && single_insn_field
!= NULL
219 && strncmp (entry_name
,
221 strlen (single_insn_field
)) == 0
222 && strncmp (entry_name
+ strlen (single_insn_field
),
224 strlen ("_is_")) == 0
225 && ((bits
->opcode
->is_boolean
226 && ((unsigned) atol (entry_name
+ strlen (single_insn_field
) + strlen ("_is_"))
227 == bits
->opcode
->boolean_constant
))
228 || (!bits
->opcode
->is_boolean
)))
230 /* The cache rule defines an entry for the comparison between a
231 single instruction field and a constant. The value of the
232 comparison in someway matches that of the opcode field that
233 was made constant through expansion. */
234 expression
= "constant compare";
235 if (bits
->opcode
->is_boolean
)
237 lf_printf (file
, "%d /* %s == %d */",
240 bits
->opcode
->boolean_constant
);
242 else if (bits
->opcode
->last
< bits
->field
->last
)
244 lf_printf (file
, "%d /* %s == %d */",
245 (atol (entry_name
+ strlen (single_insn_field
) + strlen ("_is_"))
246 == (bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
))),
248 (bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
)));
252 lf_printf (file
, "%d /* %s == %d */",
253 (atol (entry_name
+ strlen (single_insn_field
) + strlen ("_is_"))
261 /* put the field in the local variable, possibly also enter it
263 expression
= "extraction";
264 /* handle the cache */
265 if ((what_to_do
& get_values_from_icache
)
266 || (what_to_do
& put_values_in_icache
))
268 lf_printf (file
, "cache_entry->crack.%s.%s",
271 if (what_to_do
& put_values_in_icache
) /* also put it in the cache? */
273 lf_printf (file
, " = ");
276 if ((what_to_do
& put_values_in_icache
)
277 || what_to_do
== do_not_use_icache
)
279 if (cur_field
!= NULL
)
281 if (entry_expression
!= NULL
&& strlen (entry_expression
) > 0)
282 error (line
, "Instruction field entry with nonempty expression\n");
283 if (cur_field
->first
== 0 && cur_field
->last
== options
.insn_bit_size
- 1)
284 lf_printf (file
, "(instruction_%d)",
286 else if (cur_field
->last
== options
.insn_bit_size
- 1)
287 lf_printf (file
, "MASKED%d (instruction_%d, %d, %d)",
288 options
.insn_bit_size
,
290 i2target (options
.hi_bit_nr
, cur_field
->first
),
291 i2target (options
.hi_bit_nr
, cur_field
->last
));
293 lf_printf (file
, "EXTRACTED%d (instruction_%d, %d, %d)",
294 options
.insn_bit_size
,
296 i2target (options
.hi_bit_nr
, cur_field
->first
),
297 i2target (options
.hi_bit_nr
, cur_field
->last
));
301 lf_printf (file
, "%s", entry_expression
);
306 switch (what_to_declare
)
308 case define_variables
:
309 lf_printf (file
, ")");
311 case undef_variables
:
313 case declare_variables
:
314 lf_printf (file
, ";");
318 ASSERT (reason
!= NULL
&& expression
!= NULL
);
319 lf_printf (file
, " /* %s - %s */\n", reason
, expression
);
324 print_icache_body (lf
*file
,
325 insn_entry
*instruction
,
326 opcode_bits
*expanded_bits
,
327 cache_entry
*cache_rules
,
328 icache_decl_type what_to_declare
,
329 icache_body_type what_to_do
,
330 int nr_prefetched_words
)
332 /* extract instruction fields */
333 lf_printf (file
, "/* Extraction: %s\n", instruction
->name
);
334 lf_printf (file
, " ");
335 switch (what_to_declare
)
337 case define_variables
:
338 lf_printf (file
, "#define");
340 case declare_variables
:
341 lf_printf (file
, "declare");
343 case undef_variables
:
344 lf_printf (file
, "#undef");
347 lf_printf (file
, " ");
350 case get_values_from_icache
:
351 lf_printf (file
, "get-values-from-icache");
353 case put_values_in_icache
:
354 lf_printf (file
, "put-values-in-icache");
356 case both_values_and_icache
:
357 lf_printf (file
, "get-values-from-icache|put-values-in-icache");
359 case do_not_use_icache
:
360 lf_printf (file
, "do-not-use-icache");
363 lf_printf (file
, "\n ");
364 print_insn_words (file
, instruction
);
365 lf_printf(file
, " */\n");
367 /* pass zero - fetch from memory any missing instructions.
369 Some of the instructions will have already been fetched (in the
370 instruction array), others will still need fetching. */
373 case get_values_from_icache
:
375 case put_values_in_icache
:
376 case both_values_and_icache
:
377 case do_not_use_icache
:
380 switch (what_to_declare
)
382 case undef_variables
:
384 case define_variables
:
385 case declare_variables
:
386 for (word_nr
= nr_prefetched_words
;
387 word_nr
< instruction
->nr_words
;
390 /* FIXME - should be using print_icache_extraction? */
391 lf_printf (file
, "%sinstruction_word instruction_%d UNUSED = ",
392 options
.module
.global
.prefix
.l
,
394 lf_printf (file
, "IMEM%d_IMMED (cia, %d)",
395 options
.insn_bit_size
, word_nr
);
396 lf_printf (file
, ";\n");
402 /* if putting the instruction words in the cache, define references
404 if (options
.gen
.insn_in_icache
) {
405 /* FIXME: is the instruction_word type correct? */
406 print_icache_extraction (file
,
407 instruction
->format_name
,
410 "instruction_word", /* type */
411 "instruction", /* expression */
418 lf_printf(file
, "\n");
420 /* pass one - process instruction fields.
422 If there is no cache rule, the default is to enter the field into
425 insn_word_entry
*word
;
426 for (word
= instruction
->words
;
430 insn_field_entry
*cur_field
;
431 for (cur_field
= word
->first
;
432 cur_field
->first
< options
.insn_bit_size
;
433 cur_field
= cur_field
->next
)
435 if (cur_field
->type
== insn_field_string
)
437 cache_entry
*cache_rule
;
438 cache_entry_type value_type
= cache_value
;
439 line_ref
*value_line
= instruction
->line
;
440 /* check the cache table to see if it contains a rule
441 overriding the default cache action for an
443 for (cache_rule
= cache_rules
;
445 cache_rule
= cache_rule
->next
)
447 if (filter_is_subset (instruction
->field_names
,
448 cache_rule
->original_fields
)
449 && strcmp (cache_rule
->name
, cur_field
->val_string
) == 0)
451 value_type
= cache_rule
->entry_type
;
452 value_line
= cache_rule
->line
;
453 if (value_type
== compute_value
)
455 options
.warning (cache_rule
->line
,
456 "instruction field of type `compute' changed to `cache'\n");
457 cache_rule
->entry_type
= cache_value
;
462 /* Define an entry for the field within the
464 print_icache_extraction (file
,
465 instruction
->format_name
,
467 cur_field
->val_string
, /* name */
469 NULL
, /* expression */
470 cur_field
->val_string
, /* insn field */
481 /* pass two - any cache fields not processed above */
483 cache_entry
*cache_rule
;
484 for (cache_rule
= cache_rules
;
486 cache_rule
= cache_rule
->next
)
488 if (filter_is_subset (instruction
->field_names
,
489 cache_rule
->original_fields
)
490 && !filter_is_member (instruction
->field_names
,
493 char *single_field
= filter_next (cache_rule
->original_fields
, "");
494 if (filter_next (cache_rule
->original_fields
, single_field
) != NULL
)
496 print_icache_extraction (file
,
497 instruction
->format_name
,
498 cache_rule
->entry_type
,
501 cache_rule
->expression
,
504 NULL
, /* cur_field */
512 lf_print__internal_ref (file
);
517 typedef struct _form_fields form_fields
;
518 struct _form_fields
{
525 insn_table_cache_fields (insn_table
*isa
)
527 form_fields
*forms
= NULL
;
529 for (insn
= isa
->insns
;
532 form_fields
**form
= &forms
;
537 /* new format name, add it */
538 form_fields
*new_form
= ZALLOC (form_fields
);
539 new_form
->name
= insn
->format_name
;
540 filter_add (&new_form
->fields
, insn
->field_names
);
544 else if (strcmp ((*form
)->name
, insn
->format_name
) == 0)
546 /* already present, add field names to the existing list */
547 filter_add (&(*form
)->fields
, insn
->field_names
);
550 form
= &(*form
)->next
;
559 print_icache_struct (lf
*file
,
561 cache_entry
*cache_rules
)
563 /* Create a list of all the different instruction formats with their
564 corresponding field names. */
565 form_fields
*formats
= insn_table_cache_fields (isa
);
567 lf_printf (file
, "\n");
568 lf_printf (file
, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
569 options
.module
.global
.prefix
.u
,
570 (options
.gen
.icache
? options
.gen
.icache_size
: 0));
571 lf_printf (file
, "\n");
573 /* create an instruction cache if being used */
574 if (options
.gen
.icache
) {
575 lf_printf (file
, "typedef struct _%sidecode_cache {\n",
576 options
.module
.global
.prefix
.l
);
577 lf_indent (file
, +2);
580 lf_printf (file
, "unsigned_word address;\n");
581 lf_printf (file
, "void *semantic;\n");
582 lf_printf (file
, "union {\n");
583 lf_indent (file
, +2);
584 for (format
= formats
;
586 format
= format
->next
)
588 lf_printf (file
, "struct {\n");
589 lf_indent (file
, +2);
591 cache_entry
*cache_rule
;
593 /* space for any instruction words */
594 if (options
.gen
.insn_in_icache
)
595 lf_printf (file
, "instruction_word insn[%d];\n", isa
->max_nr_words
);
596 /* define an entry for any applicable cache rules */
597 for (cache_rule
= cache_rules
;
599 cache_rule
= cache_rule
->next
)
601 /* nb - sort of correct - should really check against
602 individual instructions */
603 if (filter_is_subset (format
->fields
, cache_rule
->original_fields
))
606 lf_printf (file
, "%s %s;",
607 (cache_rule
->type
== NULL
611 lf_printf (file
, " /*");
612 for (memb
= filter_next (cache_rule
->original_fields
, "");
614 memb
= filter_next (cache_rule
->original_fields
, memb
))
616 lf_printf (file
, " %s", memb
);
618 lf_printf (file
, " */\n");
621 /* define an entry for any fields not covered by a cache rule */
622 for (field
= filter_next (format
->fields
, "");
624 field
= filter_next (format
->fields
, field
))
626 cache_entry
*cache_rule
;
628 for (cache_rule
= cache_rules
;
630 cache_rule
= cache_rule
->next
)
632 if (strcmp (cache_rule
->name
, field
) == 0)
639 lf_printf (file
, "unsigned %s; /* default */\n", field
);
642 lf_indent (file
, -2);
643 lf_printf (file
, "} %s;\n", format
->name
);
645 lf_indent (file
, -2);
646 lf_printf (file
, "} crack;\n");
648 lf_indent (file
, -2);
649 lf_printf (file
, "} %sidecode_cache;\n", options
.module
.global
.prefix
.l
);
653 /* alernativly, since no cache, emit a dummy definition for
654 idecode_cache so that code refering to the type can still compile */
655 lf_printf(file
, "typedef void %sidecode_cache;\n",
656 options
.module
.global
.prefix
.l
);
658 lf_printf (file
, "\n");
664 print_icache_function (lf
*file
,
665 insn_entry
*instruction
,
666 opcode_bits
*expanded_bits
,
667 insn_opcodes
*opcodes
,
668 cache_entry
*cache_rules
,
669 int nr_prefetched_words
)
673 /* generate code to enter decoded instruction into the icache */
674 lf_printf(file
, "\n");
675 lf_print__function_type_function (file
, print_icache_function_type
,
676 "EXTERN_ICACHE", "\n");
677 indent
= print_function_name (file
,
679 instruction
->format_name
,
682 function_name_prefix_icache
);
683 indent
+= lf_printf (file
, " ");
684 lf_indent (file
, +indent
);
685 lf_printf (file
, "(");
686 print_icache_function_formal (file
, nr_prefetched_words
);
687 lf_printf (file
, ")\n");
688 lf_indent (file
, -indent
);
690 /* function header */
691 lf_printf (file
, "{\n");
692 lf_indent (file
, +2);
694 print_my_defines (file
,
696 instruction
->format_name
,
698 print_itrace (file
, instruction
, 1/*putting-value-in-cache*/);
700 print_idecode_validate (file
, instruction
, opcodes
);
702 lf_printf (file
, "\n");
703 lf_printf (file
, "{\n");
704 lf_indent (file
, +2);
705 if (options
.gen
.semantic_icache
)
706 lf_printf (file
, "unsigned_word nia;\n");
707 print_icache_body (file
,
711 (options
.gen
.direct_access
713 : declare_variables
),
714 (options
.gen
.semantic_icache
715 ? both_values_and_icache
716 : put_values_in_icache
),
717 nr_prefetched_words
);
719 lf_printf (file
, "\n");
720 lf_printf (file
, "cache_entry->address = cia;\n");
721 lf_printf (file
, "cache_entry->semantic = ");
722 print_function_name (file
,
724 instruction
->format_name
,
727 function_name_prefix_semantics
);
728 lf_printf (file
, ";\n");
729 lf_printf (file
, "\n");
731 if (options
.gen
.semantic_icache
) {
732 lf_printf (file
, "/* semantic routine */\n");
733 print_semantic_body (file
,
737 lf_printf (file
, "return nia;\n");
740 if (!options
.gen
.semantic_icache
)
742 lf_printf (file
, "/* return the function proper */\n");
743 lf_printf (file
, "return ");
744 print_function_name (file
,
746 instruction
->format_name
,
749 function_name_prefix_semantics
);
750 lf_printf (file
, ";\n");
753 if (options
.gen
.direct_access
)
755 print_icache_body (file
,
760 (options
.gen
.semantic_icache
761 ? both_values_and_icache
762 : put_values_in_icache
),
763 nr_prefetched_words
);
766 lf_indent (file
, -2);
767 lf_printf (file
, "}\n");
768 lf_indent (file
, -2);
769 lf_printf (file
, "}\n");
774 print_icache_definition (lf
*file
,
776 opcode_bits
*expanded_bits
,
777 insn_opcodes
*opcodes
,
778 cache_entry
*cache_rules
,
779 int nr_prefetched_words
)
781 print_icache_function (file
,
786 nr_prefetched_words
);
792 print_icache_internal_function_declaration (lf
*file
,
793 function_entry
*function
,
796 ASSERT (options
.gen
.icache
);
797 if (function
->is_internal
)
799 lf_printf (file
, "\n");
800 lf_print__function_type_function (file
, print_icache_function_type
,
801 "INLINE_ICACHE", "\n");
802 print_function_name (file
,
807 function_name_prefix_icache
);
808 lf_printf (file
, "\n(");
809 print_icache_function_formal (file
, 0);
810 lf_printf (file
, ");\n");
816 print_icache_internal_function_definition (lf
*file
,
817 function_entry
*function
,
820 ASSERT (options
.gen
.icache
);
821 if (function
->is_internal
)
823 lf_printf (file
, "\n");
824 lf_print__function_type_function (file
, print_icache_function_type
,
825 "INLINE_ICACHE", "\n");
826 print_function_name (file
,
831 function_name_prefix_icache
);
832 lf_printf (file
, "\n(");
833 print_icache_function_formal (file
, 0);
834 lf_printf (file
, ")\n");
835 lf_printf (file
, "{\n");
836 lf_indent (file
, +2);
837 lf_printf (file
, "/* semantic routine */\n");
838 if (options
.gen
.semantic_icache
)
840 lf_print__line_ref (file
, function
->code
->line
);
841 table_print_code (file
, function
->code
);
842 lf_printf (file
, "error (\"Internal function must longjump\\n\");\n");
843 lf_printf (file
, "return 0;\n");
847 lf_printf (file
, "return ");
848 print_function_name (file
,
853 function_name_prefix_semantics
);
854 lf_printf (file
, ";\n");
857 lf_print__internal_ref (file
);
858 lf_indent (file
, -2);
859 lf_printf (file
, "}\n");