]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/gen-icache.c
sim: include stdlib.h for atoi()
[thirdparty/binutils-gdb.git] / sim / igen / gen-icache.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
3666a048 3 Copyright 2002-2021 Free Software Foundation, Inc.
feaee4bd
AC
4
5 Contributed by Andrew Cagney.
6
7 This file is part of GDB.
8
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
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
feaee4bd
AC
12 (at your option) any later version.
13
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.
18
19 You should have received a copy of the GNU General Public License
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 21
3d52735b 22#include <stdlib.h>
c906108c
SS
23
24#include "misc.h"
25#include "lf.h"
26#include "table.h"
27#include "filter.h"
28#include "igen.h"
29
30#include "ld-insn.h"
31#include "ld-decode.h"
32
33#include "gen.h"
34
35#include "gen-semantics.h"
36#include "gen-idecode.h"
37#include "gen-icache.h"
38
39
40
41static void
42print_icache_function_header (lf *file,
43 const char *basename,
44 const char *format_name,
45 opcode_bits *expanded_bits,
46 int is_function_definition,
47 int nr_prefetched_words)
48{
4e0bf4c4 49 lf_printf (file, "\n");
c906108c
SS
50 lf_print__function_type_function (file, print_icache_function_type,
51 "EXTERN_ICACHE", " ");
52 print_function_name (file,
53 basename, format_name, NULL,
4e0bf4c4 54 expanded_bits, function_name_prefix_icache);
c906108c
SS
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");
61}
62
63
64void
65print_icache_declaration (lf *file,
4e0bf4c4 66 insn_entry * insn,
c906108c 67 opcode_bits *expanded_bits,
4e0bf4c4 68 insn_opcodes *opcodes, int nr_prefetched_words)
c906108c
SS
69{
70 print_icache_function_header (file,
71 insn->name,
72 insn->format_name,
73 expanded_bits,
4e0bf4c4 74 0 /* is not function definition */ ,
c906108c
SS
75 nr_prefetched_words);
76}
77
78
79
80static void
81print_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,
88 line_ref *line,
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)
93{
94 const char *expression;
95 opcode_bits *bits;
96 char *reason;
97 ASSERT (format_name != NULL);
98 ASSERT (entry_name != NULL);
4e0bf4c4 99
c906108c
SS
100 /* figure out exactly what should be going on here */
101 switch (cache_type)
102 {
103 case scratch_value:
104 if ((what_to_do & put_values_in_icache)
105 || what_to_do == do_not_use_icache)
106 {
107 reason = "scratch";
108 what_to_do = do_not_use_icache;
109 }
110 else
111 return;
112 break;
113 case compute_value:
114 if ((what_to_do & get_values_from_icache)
115 || what_to_do == do_not_use_icache)
116 {
117 reason = "compute";
118 what_to_do = do_not_use_icache;
119 }
120 else
121 return;
122 break;
123 case cache_value:
124 if ((what_to_declare != undef_variables)
125 || !(what_to_do & put_values_in_icache))
126 {
127 reason = "cache";
128 what_to_declare = ((what_to_do & put_values_in_icache)
4e0bf4c4 129 ? declare_variables : what_to_declare);
c906108c
SS
130 }
131 else
132 return;
133 break;
78e731cd 134 default:
4e0bf4c4 135 abort (); /* Bad switch. */
c906108c 136 }
4e0bf4c4 137
c906108c
SS
138 /* For the type, default to a simple unsigned */
139 if (entry_type == NULL || strlen (entry_type) == 0)
140 entry_type = "unsigned";
4e0bf4c4 141
c906108c
SS
142 /* look through the set of expanded sub fields to see if this field
143 has been given a constant value */
4e0bf4c4 144 for (bits = expanded_bits; bits != NULL; bits = bits->next)
c906108c
SS
145 {
146 if (bits->field == cur_field)
147 break;
148 }
4e0bf4c4 149
c906108c
SS
150 /* Define a storage area for the cache element */
151 switch (what_to_declare)
152 {
153 case undef_variables:
154 /* We've finished with the #define value - destory it */
155 lf_indent_suppress (file);
156 lf_printf (file, "#undef %s\n", entry_name);
157 return;
158 case define_variables:
159 /* Using direct access for this entry, clear any prior
160 definition, then define it */
161 lf_indent_suppress (file);
162 lf_printf (file, "#undef %s\n", entry_name);
163 /* Don't type cast pointer types! */
164 lf_indent_suppress (file);
165 if (strchr (entry_type, '*') != NULL)
166 lf_printf (file, "#define %s (", entry_name);
167 else
168 lf_printf (file, "#define %s ((%s) ", entry_name, entry_type);
169 break;
170 case declare_variables:
171 /* using variables to define the value */
172 if (line != NULL)
173 lf_print__line_ref (file, line);
174 lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
175 break;
176 }
4e0bf4c4
AC
177
178
c906108c
SS
179 /* define a value for that storage area as determined by what is in
180 the cache */
181 if (bits != NULL
182 && single_insn_field != NULL
183 && strcmp (entry_name, single_insn_field) == 0
184 && strcmp (entry_name, cur_field->val_string) == 0
185 && ((bits->opcode->is_boolean && bits->value == 0)
186 || (!bits->opcode->is_boolean)))
187 {
188 /* The cache rule is specifying what to do with a simple
189 instruction field.
4e0bf4c4
AC
190
191 Because of instruction expansion, the field is either a
192 constant value or equal to the specified constant (boolean
193 comparison). (The latter indicated by bits->value == 0).
194
c906108c
SS
195 The case of a field not being equal to the specified boolean
196 value is handled later. */
197 expression = "constant field";
198 ASSERT (bits->field == cur_field);
199 if (bits->opcode->is_boolean)
200 {
201 ASSERT (bits->value == 0);
202 lf_printf (file, "%d", bits->opcode->boolean_constant);
203 }
204 else if (bits->opcode->last < bits->field->last)
205 {
206 lf_printf (file, "%d",
207 bits->value << (bits->field->last - bits->opcode->last));
208 }
209 else
210 {
211 lf_printf (file, "%d", bits->value);
212 }
213 }
214 else if (bits != NULL
215 && single_insn_field != NULL
216 && strncmp (entry_name,
217 single_insn_field,
218 strlen (single_insn_field)) == 0
219 && strncmp (entry_name + strlen (single_insn_field),
220 "_is_",
221 strlen ("_is_")) == 0
222 && ((bits->opcode->is_boolean
4e0bf4c4
AC
223 && ((unsigned)
224 atol (entry_name + strlen (single_insn_field) +
225 strlen ("_is_")) == bits->opcode->boolean_constant))
c906108c
SS
226 || (!bits->opcode->is_boolean)))
227 {
228 /* The cache rule defines an entry for the comparison between a
4e0bf4c4
AC
229 single instruction field and a constant. The value of the
230 comparison in someway matches that of the opcode field that
231 was made constant through expansion. */
c906108c
SS
232 expression = "constant compare";
233 if (bits->opcode->is_boolean)
234 {
235 lf_printf (file, "%d /* %s == %d */",
236 bits->value == 0,
4e0bf4c4 237 single_insn_field, bits->opcode->boolean_constant);
c906108c
SS
238 }
239 else if (bits->opcode->last < bits->field->last)
240 {
241 lf_printf (file, "%d /* %s == %d */",
4e0bf4c4
AC
242 (atol
243 (entry_name + strlen (single_insn_field) +
244 strlen ("_is_")) ==
245 (bits->
246 value << (bits->field->last - bits->opcode->last))),
c906108c 247 single_insn_field,
4e0bf4c4
AC
248 (bits->
249 value << (bits->field->last - bits->opcode->last)));
c906108c
SS
250 }
251 else
252 {
253 lf_printf (file, "%d /* %s == %d */",
4e0bf4c4
AC
254 (atol
255 (entry_name + strlen (single_insn_field) +
256 strlen ("_is_")) == bits->value), single_insn_field,
c906108c
SS
257 bits->value);
258 }
259 }
260 else
261 {
262 /* put the field in the local variable, possibly also enter it
4e0bf4c4 263 into the cache */
c906108c
SS
264 expression = "extraction";
265 /* handle the cache */
266 if ((what_to_do & get_values_from_icache)
267 || (what_to_do & put_values_in_icache))
268 {
269 lf_printf (file, "cache_entry->crack.%s.%s",
4e0bf4c4
AC
270 format_name, entry_name);
271 if (what_to_do & put_values_in_icache) /* also put it in the cache? */
c906108c
SS
272 {
273 lf_printf (file, " = ");
274 }
275 }
276 if ((what_to_do & put_values_in_icache)
277 || what_to_do == do_not_use_icache)
278 {
279 if (cur_field != NULL)
280 {
281 if (entry_expression != NULL && strlen (entry_expression) > 0)
4e0bf4c4
AC
282 error (line,
283 "Instruction field entry with nonempty expression\n");
284 if (cur_field->first == 0
285 && cur_field->last == options.insn_bit_size - 1)
286 lf_printf (file, "(instruction_%d)", cur_field->word_nr);
c906108c
SS
287 else if (cur_field->last == options.insn_bit_size - 1)
288 lf_printf (file, "MASKED%d (instruction_%d, %d, %d)",
289 options.insn_bit_size,
290 cur_field->word_nr,
291 i2target (options.hi_bit_nr, cur_field->first),
292 i2target (options.hi_bit_nr, cur_field->last));
293 else
294 lf_printf (file, "EXTRACTED%d (instruction_%d, %d, %d)",
295 options.insn_bit_size,
296 cur_field->word_nr,
297 i2target (options.hi_bit_nr, cur_field->first),
298 i2target (options.hi_bit_nr, cur_field->last));
299 }
300 else
301 {
302 lf_printf (file, "%s", entry_expression);
303 }
304 }
305 }
4e0bf4c4 306
c906108c
SS
307 switch (what_to_declare)
308 {
309 case define_variables:
310 lf_printf (file, ")");
311 break;
312 case undef_variables:
313 break;
314 case declare_variables:
315 lf_printf (file, ";");
316 break;
317 }
318
319 ASSERT (reason != NULL && expression != NULL);
320 lf_printf (file, " /* %s - %s */\n", reason, expression);
321}
322
323
324void
325print_icache_body (lf *file,
4e0bf4c4 326 insn_entry * instruction,
c906108c
SS
327 opcode_bits *expanded_bits,
328 cache_entry *cache_rules,
329 icache_decl_type what_to_declare,
4e0bf4c4 330 icache_body_type what_to_do, int nr_prefetched_words)
c906108c
SS
331{
332 /* extract instruction fields */
333 lf_printf (file, "/* Extraction: %s\n", instruction->name);
334 lf_printf (file, " ");
335 switch (what_to_declare)
336 {
337 case define_variables:
338 lf_printf (file, "#define");
339 break;
340 case declare_variables:
341 lf_printf (file, "declare");
342 break;
343 case undef_variables:
344 lf_printf (file, "#undef");
345 break;
346 }
347 lf_printf (file, " ");
348 switch (what_to_do)
349 {
350 case get_values_from_icache:
351 lf_printf (file, "get-values-from-icache");
352 break;
353 case put_values_in_icache:
354 lf_printf (file, "put-values-in-icache");
355 break;
356 case both_values_and_icache:
357 lf_printf (file, "get-values-from-icache|put-values-in-icache");
358 break;
359 case do_not_use_icache:
360 lf_printf (file, "do-not-use-icache");
361 break;
362 }
363 lf_printf (file, "\n ");
364 print_insn_words (file, instruction);
4e0bf4c4
AC
365 lf_printf (file, " */\n");
366
c906108c
SS
367 /* pass zero - fetch from memory any missing instructions.
368
369 Some of the instructions will have already been fetched (in the
370 instruction array), others will still need fetching. */
371 switch (what_to_do)
372 {
373 case get_values_from_icache:
374 break;
375 case put_values_in_icache:
376 case both_values_and_icache:
377 case do_not_use_icache:
378 {
379 int word_nr;
380 switch (what_to_declare)
381 {
382 case undef_variables:
383 break;
384 case define_variables:
385 case declare_variables:
386 for (word_nr = nr_prefetched_words;
4e0bf4c4 387 word_nr < instruction->nr_words; word_nr++)
c906108c
SS
388 {
389 /* FIXME - should be using print_icache_extraction? */
4e0bf4c4
AC
390 lf_printf (file,
391 "%sinstruction_word instruction_%d UNUSED = ",
392 options.module.global.prefix.l, word_nr);
c906108c
SS
393 lf_printf (file, "IMEM%d_IMMED (cia, %d)",
394 options.insn_bit_size, word_nr);
395 lf_printf (file, ";\n");
396 }
397 }
398 }
399 }
400
401 /* if putting the instruction words in the cache, define references
402 for them */
4e0bf4c4
AC
403 if (options.gen.insn_in_icache)
404 {
405 /* FIXME: is the instruction_word type correct? */
406 print_icache_extraction (file, instruction->format_name, cache_value, "insn", /* name */
407 "instruction_word", /* type */
408 "instruction", /* expression */
409 NULL, /* origin */
410 NULL, /* line */
411 NULL, NULL, what_to_declare, what_to_do);
412 }
413 lf_printf (file, "\n");
c906108c
SS
414
415 /* pass one - process instruction fields.
416
417 If there is no cache rule, the default is to enter the field into
418 the cache */
419 {
420 insn_word_entry *word;
4e0bf4c4 421 for (word = instruction->words; word != NULL; word = word->next)
c906108c
SS
422 {
423 insn_field_entry *cur_field;
424 for (cur_field = word->first;
425 cur_field->first < options.insn_bit_size;
426 cur_field = cur_field->next)
427 {
af342558
HPN
428 /* Always expand named fields (even if constant), so
429 references are valid. */
c906108c
SS
430 if (cur_field->type == insn_field_string)
431 {
432 cache_entry *cache_rule;
433 cache_entry_type value_type = cache_value;
434 line_ref *value_line = instruction->line;
435 /* check the cache table to see if it contains a rule
436 overriding the default cache action for an
437 instruction field */
438 for (cache_rule = cache_rules;
4e0bf4c4 439 cache_rule != NULL; cache_rule = cache_rule->next)
c906108c
SS
440 {
441 if (filter_is_subset (instruction->field_names,
442 cache_rule->original_fields)
4e0bf4c4
AC
443 && strcmp (cache_rule->name,
444 cur_field->val_string) == 0)
c906108c
SS
445 {
446 value_type = cache_rule->entry_type;
447 value_line = cache_rule->line;
448 if (value_type == compute_value)
449 {
450 options.warning (cache_rule->line,
451 "instruction field of type `compute' changed to `cache'\n");
452 cache_rule->entry_type = cache_value;
453 }
454 break;
455 }
456 }
457 /* Define an entry for the field within the
4e0bf4c4
AC
458 instruction */
459 print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string, /* name */
460 NULL, /* type */
461 NULL, /* expression */
462 cur_field->val_string, /* insn field */
c906108c
SS
463 value_line,
464 cur_field,
465 expanded_bits,
4e0bf4c4 466 what_to_declare, what_to_do);
c906108c
SS
467 }
468 }
469 }
470 }
471
472 /* pass two - any cache fields not processed above */
473 {
474 cache_entry *cache_rule;
475 for (cache_rule = cache_rules;
4e0bf4c4 476 cache_rule != NULL; cache_rule = cache_rule->next)
c906108c
SS
477 {
478 if (filter_is_subset (instruction->field_names,
479 cache_rule->original_fields)
4e0bf4c4 480 && !filter_is_member (instruction->field_names, cache_rule->name))
c906108c 481 {
4e0bf4c4
AC
482 char *single_field =
483 filter_next (cache_rule->original_fields, "");
484 if (filter_next (cache_rule->original_fields, single_field) !=
485 NULL)
c906108c 486 single_field = NULL;
4e0bf4c4 487 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 */
c906108c 488 expanded_bits,
4e0bf4c4 489 what_to_declare, what_to_do);
c906108c
SS
490 }
491 }
492 }
493
494 lf_print__internal_ref (file);
495}
496
497
498
499typedef struct _form_fields form_fields;
4e0bf4c4
AC
500struct _form_fields
501{
c906108c
SS
502 char *name;
503 filter *fields;
504 form_fields *next;
505};
506
507static form_fields *
508insn_table_cache_fields (insn_table *isa)
509{
510 form_fields *forms = NULL;
511 insn_entry *insn;
4e0bf4c4
AC
512 for (insn = isa->insns; insn != NULL; insn = insn->next)
513 {
514 form_fields **form = &forms;
515 while (1)
516 {
517 if (*form == NULL)
518 {
519 /* new format name, add it */
520 form_fields *new_form = ZALLOC (form_fields);
521 new_form->name = insn->format_name;
522 filter_add (&new_form->fields, insn->field_names);
523 *form = new_form;
524 break;
525 }
526 else if (strcmp ((*form)->name, insn->format_name) == 0)
527 {
528 /* already present, add field names to the existing list */
529 filter_add (&(*form)->fields, insn->field_names);
530 break;
531 }
532 form = &(*form)->next;
533 }
534 }
c906108c
SS
535 return forms;
536}
537
538
539
540extern void
4e0bf4c4 541print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules)
c906108c
SS
542{
543 /* Create a list of all the different instruction formats with their
544 corresponding field names. */
545 form_fields *formats = insn_table_cache_fields (isa);
4e0bf4c4 546
c906108c
SS
547 lf_printf (file, "\n");
548 lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
549 options.module.global.prefix.u,
550 (options.gen.icache ? options.gen.icache_size : 0));
551 lf_printf (file, "\n");
4e0bf4c4 552
c906108c 553 /* create an instruction cache if being used */
4e0bf4c4 554 if (options.gen.icache)
c906108c 555 {
4e0bf4c4
AC
556 lf_printf (file, "typedef struct _%sidecode_cache {\n",
557 options.module.global.prefix.l);
c906108c 558 lf_indent (file, +2);
4e0bf4c4
AC
559 {
560 form_fields *format;
561 lf_printf (file, "unsigned_word address;\n");
562 lf_printf (file, "void *semantic;\n");
563 lf_printf (file, "union {\n");
564 lf_indent (file, +2);
565 for (format = formats; format != NULL; format = format->next)
c906108c 566 {
4e0bf4c4
AC
567 lf_printf (file, "struct {\n");
568 lf_indent (file, +2);
569 {
570 cache_entry *cache_rule;
571 char *field;
572 /* space for any instruction words */
573 if (options.gen.insn_in_icache)
574 lf_printf (file, "instruction_word insn[%d];\n",
575 isa->max_nr_words);
576 /* define an entry for any applicable cache rules */
577 for (cache_rule = cache_rules;
578 cache_rule != NULL; cache_rule = cache_rule->next)
579 {
580 /* nb - sort of correct - should really check against
581 individual instructions */
582 if (filter_is_subset
583 (format->fields, cache_rule->original_fields))
584 {
585 char *memb;
586 lf_printf (file, "%s %s;",
587 (cache_rule->type == NULL
588 ? "unsigned"
589 : cache_rule->type), cache_rule->name);
590 lf_printf (file, " /*");
591 for (memb =
592 filter_next (cache_rule->original_fields, "");
593 memb != NULL;
594 memb =
595 filter_next (cache_rule->original_fields, memb))
596 {
597 lf_printf (file, " %s", memb);
598 }
599 lf_printf (file, " */\n");
600 }
601 }
602 /* define an entry for any fields not covered by a cache rule */
603 for (field = filter_next (format->fields, "");
604 field != NULL; field = filter_next (format->fields, field))
605 {
606 cache_entry *cache_rule;
607 int found_rule = 0;
608 for (cache_rule = cache_rules;
609 cache_rule != NULL; cache_rule = cache_rule->next)
610 {
611 if (strcmp (cache_rule->name, field) == 0)
612 {
613 found_rule = 1;
614 break;
615 }
616 }
617 if (!found_rule)
618 lf_printf (file, "unsigned %s; /* default */\n", field);
619 }
620 }
621 lf_indent (file, -2);
622 lf_printf (file, "} %s;\n", format->name);
c906108c 623 }
4e0bf4c4
AC
624 lf_indent (file, -2);
625 lf_printf (file, "} crack;\n");
626 }
c906108c 627 lf_indent (file, -2);
4e0bf4c4
AC
628 lf_printf (file, "} %sidecode_cache;\n",
629 options.module.global.prefix.l);
c906108c 630 }
c906108c
SS
631 else
632 {
633 /* alernativly, since no cache, emit a dummy definition for
4e0bf4c4
AC
634 idecode_cache so that code refering to the type can still compile */
635 lf_printf (file, "typedef void %sidecode_cache;\n",
636 options.module.global.prefix.l);
c906108c
SS
637 }
638 lf_printf (file, "\n");
639}
640
641
642
643static void
644print_icache_function (lf *file,
4e0bf4c4 645 insn_entry * instruction,
c906108c
SS
646 opcode_bits *expanded_bits,
647 insn_opcodes *opcodes,
4e0bf4c4 648 cache_entry *cache_rules, int nr_prefetched_words)
c906108c
SS
649{
650 int indent;
651
652 /* generate code to enter decoded instruction into the icache */
4e0bf4c4 653 lf_printf (file, "\n");
c906108c
SS
654 lf_print__function_type_function (file, print_icache_function_type,
655 "EXTERN_ICACHE", "\n");
656 indent = print_function_name (file,
657 instruction->name,
658 instruction->format_name,
659 NULL,
4e0bf4c4 660 expanded_bits, function_name_prefix_icache);
c906108c
SS
661 indent += lf_printf (file, " ");
662 lf_indent (file, +indent);
663 lf_printf (file, "(");
664 print_icache_function_formal (file, nr_prefetched_words);
665 lf_printf (file, ")\n");
666 lf_indent (file, -indent);
4e0bf4c4 667
c906108c
SS
668 /* function header */
669 lf_printf (file, "{\n");
670 lf_indent (file, +2);
4e0bf4c4 671
c906108c
SS
672 print_my_defines (file,
673 instruction->name,
4e0bf4c4
AC
674 instruction->format_name, expanded_bits);
675 print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
676
c906108c 677 print_idecode_validate (file, instruction, opcodes);
4e0bf4c4 678
c906108c
SS
679 lf_printf (file, "\n");
680 lf_printf (file, "{\n");
681 lf_indent (file, +2);
682 if (options.gen.semantic_icache)
683 lf_printf (file, "unsigned_word nia;\n");
684 print_icache_body (file,
685 instruction,
686 expanded_bits,
687 cache_rules,
688 (options.gen.direct_access
689 ? define_variables
690 : declare_variables),
691 (options.gen.semantic_icache
692 ? both_values_and_icache
4e0bf4c4
AC
693 : put_values_in_icache), nr_prefetched_words);
694
c906108c
SS
695 lf_printf (file, "\n");
696 lf_printf (file, "cache_entry->address = cia;\n");
697 lf_printf (file, "cache_entry->semantic = ");
698 print_function_name (file,
699 instruction->name,
700 instruction->format_name,
4e0bf4c4 701 NULL, expanded_bits, function_name_prefix_semantics);
c906108c
SS
702 lf_printf (file, ";\n");
703 lf_printf (file, "\n");
704
4e0bf4c4
AC
705 if (options.gen.semantic_icache)
706 {
707 lf_printf (file, "/* semantic routine */\n");
708 print_semantic_body (file, instruction, expanded_bits, opcodes);
709 lf_printf (file, "return nia;\n");
710 }
711
c906108c
SS
712 if (!options.gen.semantic_icache)
713 {
714 lf_printf (file, "/* return the function proper */\n");
715 lf_printf (file, "return ");
716 print_function_name (file,
717 instruction->name,
718 instruction->format_name,
719 NULL,
4e0bf4c4 720 expanded_bits, function_name_prefix_semantics);
c906108c
SS
721 lf_printf (file, ";\n");
722 }
4e0bf4c4 723
c906108c
SS
724 if (options.gen.direct_access)
725 {
726 print_icache_body (file,
727 instruction,
728 expanded_bits,
729 cache_rules,
730 undef_variables,
731 (options.gen.semantic_icache
732 ? both_values_and_icache
4e0bf4c4 733 : put_values_in_icache), nr_prefetched_words);
c906108c 734 }
4e0bf4c4 735
c906108c
SS
736 lf_indent (file, -2);
737 lf_printf (file, "}\n");
738 lf_indent (file, -2);
739 lf_printf (file, "}\n");
740}
741
742
743void
744print_icache_definition (lf *file,
4e0bf4c4 745 insn_entry * insn,
c906108c
SS
746 opcode_bits *expanded_bits,
747 insn_opcodes *opcodes,
4e0bf4c4 748 cache_entry *cache_rules, int nr_prefetched_words)
c906108c
SS
749{
750 print_icache_function (file,
751 insn,
752 expanded_bits,
4e0bf4c4 753 opcodes, cache_rules, nr_prefetched_words);
c906108c
SS
754}
755
756
757
758void
759print_icache_internal_function_declaration (lf *file,
4e0bf4c4 760 function_entry * function,
c906108c
SS
761 void *data)
762{
763 ASSERT (options.gen.icache);
764 if (function->is_internal)
765 {
766 lf_printf (file, "\n");
767 lf_print__function_type_function (file, print_icache_function_type,
768 "INLINE_ICACHE", "\n");
769 print_function_name (file,
770 function->name,
4e0bf4c4 771 NULL, NULL, NULL, function_name_prefix_icache);
c906108c
SS
772 lf_printf (file, "\n(");
773 print_icache_function_formal (file, 0);
774 lf_printf (file, ");\n");
775 }
776}
777
778
779void
780print_icache_internal_function_definition (lf *file,
4e0bf4c4 781 function_entry * function,
c906108c
SS
782 void *data)
783{
784 ASSERT (options.gen.icache);
785 if (function->is_internal)
786 {
787 lf_printf (file, "\n");
788 lf_print__function_type_function (file, print_icache_function_type,
789 "INLINE_ICACHE", "\n");
790 print_function_name (file,
791 function->name,
4e0bf4c4 792 NULL, NULL, NULL, function_name_prefix_icache);
c906108c
SS
793 lf_printf (file, "\n(");
794 print_icache_function_formal (file, 0);
795 lf_printf (file, ")\n");
796 lf_printf (file, "{\n");
797 lf_indent (file, +2);
798 lf_printf (file, "/* semantic routine */\n");
799 if (options.gen.semantic_icache)
800 {
801 lf_print__line_ref (file, function->code->line);
802 table_print_code (file, function->code);
4e0bf4c4
AC
803 lf_printf (file,
804 "error (\"Internal function must longjump\\n\");\n");
c906108c
SS
805 lf_printf (file, "return 0;\n");
806 }
807 else
808 {
809 lf_printf (file, "return ");
810 print_function_name (file,
811 function->name,
812 NULL,
4e0bf4c4 813 NULL, NULL, function_name_prefix_semantics);
c906108c
SS
814 lf_printf (file, ";\n");
815 }
4e0bf4c4 816
c906108c
SS
817 lf_print__internal_ref (file);
818 lf_indent (file, -2);
819 lf_printf (file, "}\n");
820 }
821}