1 /* The IGEN simulator generator for GDB, the GNU Debugger.
3 Copyright 2002-2024 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
31 #include "ld-decode.h"
35 #include "gen-semantics.h"
36 #include "gen-idecode.h"
37 #include "gen-icache.h"
42 print_icache_function_header (lf
*file
,
44 const char *format_name
,
45 const opcode_bits
*expanded_bits
,
46 int is_function_definition
,
47 int nr_prefetched_words
)
49 lf_printf (file
, "\n");
50 lf_print__function_type_function (file
, print_icache_function_type
,
51 "EXTERN_ICACHE", " ");
52 print_function_name (file
,
53 basename
, format_name
, NULL
,
54 expanded_bits
, function_name_prefix_icache
);
55 lf_printf (file
, "\n(");
56 print_icache_function_formal (file
, nr_prefetched_words
);
57 lf_printf (file
, ")");
58 if (!is_function_definition
)
59 lf_printf (file
, ";");
60 lf_printf (file
, "\n");
65 print_icache_declaration (lf
*file
,
66 const insn_entry
*insn
,
67 const opcode_bits
*expanded_bits
,
68 const insn_opcodes
*opcodes
,
69 int nr_prefetched_words
)
71 print_icache_function_header (file
,
75 0 /* is not function definition */ ,
82 print_icache_extraction (lf
*file
,
83 const char *format_name
,
84 cache_entry_type cache_type
,
85 const char *entry_name
,
86 const char *entry_type
,
87 const char *entry_expression
,
88 const char *single_insn_field
,
90 insn_field_entry
*cur_field
,
91 const opcode_bits
*expanded_bits
,
92 icache_decl_type what_to_declare
,
93 icache_body_type what_to_do
)
95 const char *expression
;
96 const opcode_bits
*bits
;
98 ASSERT (format_name
!= NULL
);
99 ASSERT (entry_name
!= NULL
);
101 /* figure out exactly what should be going on here */
105 if ((what_to_do
& put_values_in_icache
)
106 || what_to_do
== do_not_use_icache
)
109 what_to_do
= do_not_use_icache
;
115 if ((what_to_do
& get_values_from_icache
)
116 || what_to_do
== do_not_use_icache
)
119 what_to_do
= do_not_use_icache
;
125 if ((what_to_declare
!= undef_variables
)
126 || !(what_to_do
& put_values_in_icache
))
129 what_to_declare
= ((what_to_do
& put_values_in_icache
)
130 ? declare_variables
: what_to_declare
);
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
; bits
!= NULL
; bits
= bits
->next
)
147 if (bits
->field
== cur_field
)
151 /* Define a storage area for the cache element */
152 switch (what_to_declare
)
154 case undef_variables
:
155 /* We've finished with the #define value - destroy it */
156 lf_indent_suppress (file
);
157 lf_printf (file
, "#undef %s\n", entry_name
);
159 case define_variables
:
160 /* Using direct access for this entry, clear any prior
161 definition, then define it */
162 lf_indent_suppress (file
);
163 lf_printf (file
, "#undef %s\n", entry_name
);
164 /* Don't type cast pointer types! */
165 lf_indent_suppress (file
);
166 if (strchr (entry_type
, '*') != NULL
)
167 lf_printf (file
, "#define %s (", entry_name
);
169 lf_printf (file
, "#define %s ((%s) ", entry_name
, entry_type
);
171 case declare_variables
:
172 /* using variables to define the value */
174 lf_print__line_ref (file
, line
);
175 lf_printf (file
, "%s const %s UNUSED = ", entry_type
, entry_name
);
180 /* define a value for that storage area as determined by what is in
183 && single_insn_field
!= NULL
184 && strcmp (entry_name
, single_insn_field
) == 0
185 && strcmp (entry_name
, cur_field
->val_string
) == 0
186 && ((bits
->opcode
->is_boolean
&& bits
->value
== 0)
187 || (!bits
->opcode
->is_boolean
)))
189 /* The cache rule is specifying what to do with a simple
192 Because of instruction expansion, the field is either a
193 constant value or equal to the specified constant (boolean
194 comparison). (The latter indicated by bits->value == 0).
196 The case of a field not being equal to the specified boolean
197 value is handled later. */
198 expression
= "constant field";
199 ASSERT (bits
->field
== cur_field
);
200 if (bits
->opcode
->is_boolean
)
202 ASSERT (bits
->value
== 0);
203 lf_printf (file
, "%d", bits
->opcode
->boolean_constant
);
205 else if (bits
->opcode
->last
< bits
->field
->last
)
207 lf_printf (file
, "%d",
208 bits
->value
<< (bits
->field
->last
- bits
->opcode
->last
));
212 lf_printf (file
, "%d", bits
->value
);
215 else if (bits
!= NULL
216 && single_insn_field
!= NULL
217 && strncmp (entry_name
,
219 strlen (single_insn_field
)) == 0
220 && strncmp (entry_name
+ strlen (single_insn_field
),
222 strlen ("_is_")) == 0
223 && ((bits
->opcode
->is_boolean
225 atol (entry_name
+ strlen (single_insn_field
) +
226 strlen ("_is_")) == bits
->opcode
->boolean_constant
))
227 || (!bits
->opcode
->is_boolean
)))
229 /* The cache rule defines an entry for the comparison between a
230 single instruction field and a constant. The value of the
231 comparison in someway matches that of the opcode field that
232 was made constant through expansion. */
233 expression
= "constant compare";
234 if (bits
->opcode
->is_boolean
)
236 lf_printf (file
, "%d /* %s == %d */",
238 single_insn_field
, bits
->opcode
->boolean_constant
);
240 else if (bits
->opcode
->last
< bits
->field
->last
)
242 lf_printf (file
, "%d /* %s == %d */",
244 (entry_name
+ strlen (single_insn_field
) +
247 value
<< (bits
->field
->last
- bits
->opcode
->last
))),
250 value
<< (bits
->field
->last
- bits
->opcode
->last
)));
254 lf_printf (file
, "%d /* %s == %d */",
256 (entry_name
+ strlen (single_insn_field
) +
257 strlen ("_is_")) == bits
->value
), single_insn_field
,
263 /* put the field in the local variable, possibly also enter it
265 expression
= "extraction";
266 /* handle the cache */
267 if ((what_to_do
& get_values_from_icache
)
268 || (what_to_do
& put_values_in_icache
))
270 lf_printf (file
, "cache_entry->crack.%s.%s",
271 format_name
, entry_name
);
272 if (what_to_do
& put_values_in_icache
) /* also put it in the cache? */
274 lf_printf (file
, " = ");
277 if ((what_to_do
& put_values_in_icache
)
278 || what_to_do
== do_not_use_icache
)
280 if (cur_field
!= NULL
)
282 if (entry_expression
!= NULL
&& strlen (entry_expression
) > 0)
284 "Instruction field entry with nonempty expression\n");
285 if (cur_field
->first
== 0
286 && cur_field
->last
== options
.insn_bit_size
- 1)
287 lf_printf (file
, "(instruction_%d)", cur_field
->word_nr
);
288 else if (cur_field
->last
== options
.insn_bit_size
- 1)
289 lf_printf (file
, "MASKED%d (instruction_%d, %d, %d)",
290 options
.insn_bit_size
,
292 i2target (options
.hi_bit_nr
, cur_field
->first
),
293 i2target (options
.hi_bit_nr
, cur_field
->last
));
295 lf_printf (file
, "EXTRACTED%d (instruction_%d, %d, %d)",
296 options
.insn_bit_size
,
298 i2target (options
.hi_bit_nr
, cur_field
->first
),
299 i2target (options
.hi_bit_nr
, cur_field
->last
));
303 lf_printf (file
, "%s", entry_expression
);
308 switch (what_to_declare
)
310 case define_variables
:
311 lf_printf (file
, ")");
313 case undef_variables
:
315 case declare_variables
:
316 lf_printf (file
, ";");
320 ASSERT (reason
!= NULL
&& expression
!= NULL
);
321 lf_printf (file
, " /* %s - %s */\n", reason
, expression
);
326 print_icache_body (lf
*file
,
327 const insn_entry
*instruction
,
328 const opcode_bits
*expanded_bits
,
329 cache_entry
*cache_rules
,
330 icache_decl_type what_to_declare
,
331 icache_body_type what_to_do
, int nr_prefetched_words
)
333 /* extract instruction fields */
334 lf_printf (file
, "/* Extraction: %s\n", instruction
->name
);
335 lf_printf (file
, " ");
336 switch (what_to_declare
)
338 case define_variables
:
339 lf_printf (file
, "#define");
341 case declare_variables
:
342 lf_printf (file
, "declare");
344 case undef_variables
:
345 lf_printf (file
, "#undef");
348 lf_printf (file
, " ");
351 case get_values_from_icache
:
352 lf_printf (file
, "get-values-from-icache");
354 case put_values_in_icache
:
355 lf_printf (file
, "put-values-in-icache");
357 case both_values_and_icache
:
358 lf_printf (file
, "get-values-from-icache|put-values-in-icache");
360 case do_not_use_icache
:
361 lf_printf (file
, "do-not-use-icache");
364 lf_printf (file
, "\n ");
365 print_insn_words (file
, instruction
);
366 lf_printf (file
, " */\n");
368 /* pass zero - fetch from memory any missing instructions.
370 Some of the instructions will have already been fetched (in the
371 instruction array), others will still need fetching. */
374 case get_values_from_icache
:
376 case put_values_in_icache
:
377 case both_values_and_icache
:
378 case do_not_use_icache
:
381 switch (what_to_declare
)
383 case undef_variables
:
385 case define_variables
:
386 case declare_variables
:
387 for (word_nr
= nr_prefetched_words
;
388 word_nr
< instruction
->nr_words
; word_nr
++)
390 /* FIXME - should be using print_icache_extraction? */
392 "%sinstruction_word instruction_%d UNUSED = ",
393 options
.module
.global
.prefix
.l
, word_nr
);
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
)
406 /* FIXME: is the instruction_word type correct? */
407 print_icache_extraction (file
, instruction
->format_name
, cache_value
, "insn", /* name */
408 "instruction_word", /* type */
409 "instruction", /* expression */
412 NULL
, NULL
, what_to_declare
, what_to_do
);
414 lf_printf (file
, "\n");
416 /* pass one - process instruction fields.
418 If there is no cache rule, the default is to enter the field into
421 insn_word_entry
*word
;
422 for (word
= instruction
->words
; word
!= NULL
; word
= word
->next
)
424 insn_field_entry
*cur_field
;
425 for (cur_field
= word
->first
;
426 cur_field
->first
< options
.insn_bit_size
;
427 cur_field
= cur_field
->next
)
429 /* Always expand named fields (even if constant), so
430 references are valid. */
431 if (cur_field
->type
== insn_field_string
)
433 cache_entry
*cache_rule
;
434 cache_entry_type value_type
= cache_value
;
435 line_ref
*value_line
= instruction
->line
;
436 /* check the cache table to see if it contains a rule
437 overriding the default cache action for an
439 for (cache_rule
= cache_rules
;
440 cache_rule
!= NULL
; cache_rule
= cache_rule
->next
)
442 if (filter_is_subset (instruction
->field_names
,
443 cache_rule
->original_fields
)
444 && strcmp (cache_rule
->name
,
445 cur_field
->val_string
) == 0)
447 value_type
= cache_rule
->entry_type
;
448 value_line
= cache_rule
->line
;
449 if (value_type
== compute_value
)
451 options
.warning (cache_rule
->line
,
452 "instruction field of type `compute' changed to `cache'\n");
453 cache_rule
->entry_type
= cache_value
;
458 /* Define an entry for the field within the
460 print_icache_extraction (file
, instruction
->format_name
, value_type
, cur_field
->val_string
, /* name */
462 NULL
, /* expression */
463 cur_field
->val_string
, /* insn field */
467 what_to_declare
, what_to_do
);
473 /* pass two - any cache fields not processed above */
475 cache_entry
*cache_rule
;
476 for (cache_rule
= cache_rules
;
477 cache_rule
!= NULL
; cache_rule
= cache_rule
->next
)
479 if (filter_is_subset (instruction
->field_names
,
480 cache_rule
->original_fields
)
481 && !filter_is_member (instruction
->field_names
, cache_rule
->name
))
483 const char *single_field
=
484 filter_next (cache_rule
->original_fields
, "");
485 if (filter_next (cache_rule
->original_fields
, single_field
) !=
488 print_icache_extraction (file
, instruction
->format_name
, cache_rule
->entry_type
, cache_rule
->name
, cache_rule
->type
, cache_rule
->expression
, single_field
, cache_rule
->line
, NULL
, /* cur_field */
490 what_to_declare
, what_to_do
);
495 lf_print__internal_ref (file
);
500 typedef struct _form_fields form_fields
;
509 insn_table_cache_fields (const insn_table
*isa
)
511 form_fields
*forms
= NULL
;
513 for (insn
= isa
->insns
; insn
!= NULL
; insn
= insn
->next
)
515 form_fields
**form
= &forms
;
520 /* new format name, add it */
521 form_fields
*new_form
= ZALLOC (form_fields
);
522 new_form
->name
= insn
->format_name
;
523 filter_add (&new_form
->fields
, insn
->field_names
);
527 else if (strcmp ((*form
)->name
, insn
->format_name
) == 0)
529 /* already present, add field names to the existing list */
530 filter_add (&(*form
)->fields
, insn
->field_names
);
533 form
= &(*form
)->next
;
542 print_icache_struct (lf
*file
, const insn_table
*isa
, cache_entry
*cache_rules
)
544 /* Create a list of all the different instruction formats with their
545 corresponding field names. */
546 form_fields
*formats
= insn_table_cache_fields (isa
);
548 lf_printf (file
, "\n");
549 lf_printf (file
, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
550 options
.module
.global
.prefix
.u
,
551 (options
.gen
.icache
? options
.gen
.icache_size
: 0));
552 lf_printf (file
, "\n");
554 /* create an instruction cache if being used */
555 if (options
.gen
.icache
)
557 lf_printf (file
, "typedef struct _%sidecode_cache {\n",
558 options
.module
.global
.prefix
.l
);
559 lf_indent (file
, +2);
562 lf_printf (file
, "unsigned_word address;\n");
563 lf_printf (file
, "void *semantic;\n");
564 lf_printf (file
, "union {\n");
565 lf_indent (file
, +2);
566 for (format
= formats
; format
!= NULL
; format
= format
->next
)
568 lf_printf (file
, "struct {\n");
569 lf_indent (file
, +2);
571 cache_entry
*cache_rule
;
573 /* space for any instruction words */
574 if (options
.gen
.insn_in_icache
)
575 lf_printf (file
, "instruction_word insn[%d];\n",
577 /* define an entry for any applicable cache rules */
578 for (cache_rule
= cache_rules
;
579 cache_rule
!= NULL
; cache_rule
= cache_rule
->next
)
581 /* nb - sort of correct - should really check against
582 individual instructions */
584 (format
->fields
, cache_rule
->original_fields
))
587 lf_printf (file
, "%s %s;",
588 (cache_rule
->type
== NULL
590 : cache_rule
->type
), cache_rule
->name
);
591 lf_printf (file
, " /*");
593 filter_next (cache_rule
->original_fields
, "");
596 filter_next (cache_rule
->original_fields
, memb
))
598 lf_printf (file
, " %s", memb
);
600 lf_printf (file
, " */\n");
603 /* define an entry for any fields not covered by a cache rule */
604 for (field
= filter_next (format
->fields
, "");
605 field
!= NULL
; field
= filter_next (format
->fields
, field
))
607 cache_entry
*cache_rule
;
609 for (cache_rule
= cache_rules
;
610 cache_rule
!= NULL
; cache_rule
= cache_rule
->next
)
612 if (strcmp (cache_rule
->name
, field
) == 0)
619 lf_printf (file
, "unsigned %s; /* default */\n", field
);
622 lf_indent (file
, -2);
623 lf_printf (file
, "} %s;\n", format
->name
);
625 lf_indent (file
, -2);
626 lf_printf (file
, "} crack;\n");
628 lf_indent (file
, -2);
629 lf_printf (file
, "} %sidecode_cache;\n",
630 options
.module
.global
.prefix
.l
);
634 /* alernativly, since no cache, emit a dummy definition for
635 idecode_cache so that code referring to the type can still compile */
636 lf_printf (file
, "typedef void %sidecode_cache;\n",
637 options
.module
.global
.prefix
.l
);
639 lf_printf (file
, "\n");
645 print_icache_function (lf
*file
,
646 const insn_entry
*instruction
,
647 const opcode_bits
*expanded_bits
,
648 const insn_opcodes
*opcodes
,
649 cache_entry
*cache_rules
, int nr_prefetched_words
)
653 /* generate code to enter decoded instruction into the icache */
654 lf_printf (file
, "\n");
655 lf_print__function_type_function (file
, print_icache_function_type
,
656 "EXTERN_ICACHE", "\n");
657 indent
= print_function_name (file
,
659 instruction
->format_name
,
661 expanded_bits
, function_name_prefix_icache
);
662 indent
+= lf_printf (file
, " ");
663 lf_indent (file
, +indent
);
664 lf_printf (file
, "(");
665 print_icache_function_formal (file
, nr_prefetched_words
);
666 lf_printf (file
, ")\n");
667 lf_indent (file
, -indent
);
669 /* function header */
670 lf_printf (file
, "{\n");
671 lf_indent (file
, +2);
673 print_my_defines (file
,
675 instruction
->format_name
, expanded_bits
);
676 print_itrace (file
, instruction
, 1 /*putting-value-in-cache */ );
678 print_idecode_validate (file
, instruction
, opcodes
);
680 lf_printf (file
, "\n");
681 lf_printf (file
, "{\n");
682 lf_indent (file
, +2);
683 if (options
.gen
.semantic_icache
)
684 lf_printf (file
, "unsigned_word nia;\n");
685 print_icache_body (file
,
689 (options
.gen
.direct_access
691 : declare_variables
),
692 (options
.gen
.semantic_icache
693 ? both_values_and_icache
694 : put_values_in_icache
), nr_prefetched_words
);
696 lf_printf (file
, "\n");
697 lf_printf (file
, "cache_entry->address = cia;\n");
698 lf_printf (file
, "cache_entry->semantic = ");
699 print_function_name (file
,
701 instruction
->format_name
,
702 NULL
, expanded_bits
, function_name_prefix_semantics
);
703 lf_printf (file
, ";\n");
704 lf_printf (file
, "\n");
706 if (options
.gen
.semantic_icache
)
708 lf_printf (file
, "/* semantic routine */\n");
709 print_semantic_body (file
, instruction
, expanded_bits
, opcodes
);
710 lf_printf (file
, "return nia;\n");
713 if (!options
.gen
.semantic_icache
)
715 lf_printf (file
, "/* return the function proper */\n");
716 lf_printf (file
, "return ");
717 print_function_name (file
,
719 instruction
->format_name
,
721 expanded_bits
, function_name_prefix_semantics
);
722 lf_printf (file
, ";\n");
725 if (options
.gen
.direct_access
)
727 print_icache_body (file
,
732 (options
.gen
.semantic_icache
733 ? both_values_and_icache
734 : put_values_in_icache
), nr_prefetched_words
);
737 lf_indent (file
, -2);
738 lf_printf (file
, "}\n");
739 lf_indent (file
, -2);
740 lf_printf (file
, "}\n");
745 print_icache_definition (lf
*file
,
746 const insn_entry
*insn
,
747 const opcode_bits
*expanded_bits
,
748 const insn_opcodes
*opcodes
,
749 cache_entry
*cache_rules
, int nr_prefetched_words
)
751 print_icache_function (file
,
754 opcodes
, cache_rules
, nr_prefetched_words
);
760 print_icache_internal_function_declaration (lf
*file
,
761 const function_entry
*function
,
764 ASSERT (options
.gen
.icache
);
765 if (function
->is_internal
)
767 lf_printf (file
, "\n");
768 lf_print__function_type_function (file
, print_icache_function_type
,
769 "INLINE_ICACHE", "\n");
770 print_function_name (file
,
772 NULL
, NULL
, NULL
, function_name_prefix_icache
);
773 lf_printf (file
, "\n(");
774 print_icache_function_formal (file
, 0);
775 lf_printf (file
, ");\n");
781 print_icache_internal_function_definition (lf
*file
,
782 const function_entry
*function
,
785 ASSERT (options
.gen
.icache
);
786 if (function
->is_internal
)
788 lf_printf (file
, "\n");
789 lf_print__function_type_function (file
, print_icache_function_type
,
790 "INLINE_ICACHE", "\n");
791 print_function_name (file
,
793 NULL
, NULL
, NULL
, function_name_prefix_icache
);
794 lf_printf (file
, "\n(");
795 print_icache_function_formal (file
, 0);
796 lf_printf (file
, ")\n");
797 lf_printf (file
, "{\n");
798 lf_indent (file
, +2);
799 lf_printf (file
, "/* semantic routine */\n");
800 if (options
.gen
.semantic_icache
)
802 lf_print__line_ref (file
, function
->code
->line
);
803 table_print_code (file
, function
->code
);
805 "error (\"Internal function must longjump\\n\");\n");
806 lf_printf (file
, "return 0;\n");
810 lf_printf (file
, "return ");
811 print_function_name (file
,
814 NULL
, NULL
, function_name_prefix_semantics
);
815 lf_printf (file
, ";\n");
818 lf_print__internal_ref (file
);
819 lf_indent (file
, -2);
820 lf_printf (file
, "}\n");