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