]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/gen-icache.c
This commit was manufactured by cvs2svn to create branch
[thirdparty/binutils-gdb.git] / sim / igen / gen-icache.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
9b254dd1 3 Copyright 2002, 2007, 2008 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 {
427 if (cur_field->type == insn_field_string)
428 {
429 cache_entry *cache_rule;
430 cache_entry_type value_type = cache_value;
431 line_ref *value_line = instruction->line;
432 /* check the cache table to see if it contains a rule
433 overriding the default cache action for an
434 instruction field */
435 for (cache_rule = cache_rules;
4e0bf4c4 436 cache_rule != NULL; cache_rule = cache_rule->next)
c906108c
SS
437 {
438 if (filter_is_subset (instruction->field_names,
439 cache_rule->original_fields)
4e0bf4c4
AC
440 && strcmp (cache_rule->name,
441 cur_field->val_string) == 0)
c906108c
SS
442 {
443 value_type = cache_rule->entry_type;
444 value_line = cache_rule->line;
445 if (value_type == compute_value)
446 {
447 options.warning (cache_rule->line,
448 "instruction field of type `compute' changed to `cache'\n");
449 cache_rule->entry_type = cache_value;
450 }
451 break;
452 }
453 }
454 /* Define an entry for the field within the
4e0bf4c4
AC
455 instruction */
456 print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string, /* name */
457 NULL, /* type */
458 NULL, /* expression */
459 cur_field->val_string, /* insn field */
c906108c
SS
460 value_line,
461 cur_field,
462 expanded_bits,
4e0bf4c4 463 what_to_declare, what_to_do);
c906108c
SS
464 }
465 }
466 }
467 }
468
469 /* pass two - any cache fields not processed above */
470 {
471 cache_entry *cache_rule;
472 for (cache_rule = cache_rules;
4e0bf4c4 473 cache_rule != NULL; cache_rule = cache_rule->next)
c906108c
SS
474 {
475 if (filter_is_subset (instruction->field_names,
476 cache_rule->original_fields)
4e0bf4c4 477 && !filter_is_member (instruction->field_names, cache_rule->name))
c906108c 478 {
4e0bf4c4
AC
479 char *single_field =
480 filter_next (cache_rule->original_fields, "");
481 if (filter_next (cache_rule->original_fields, single_field) !=
482 NULL)
c906108c 483 single_field = NULL;
4e0bf4c4 484 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 485 expanded_bits,
4e0bf4c4 486 what_to_declare, what_to_do);
c906108c
SS
487 }
488 }
489 }
490
491 lf_print__internal_ref (file);
492}
493
494
495
496typedef struct _form_fields form_fields;
4e0bf4c4
AC
497struct _form_fields
498{
c906108c
SS
499 char *name;
500 filter *fields;
501 form_fields *next;
502};
503
504static form_fields *
505insn_table_cache_fields (insn_table *isa)
506{
507 form_fields *forms = NULL;
508 insn_entry *insn;
4e0bf4c4
AC
509 for (insn = isa->insns; insn != NULL; insn = insn->next)
510 {
511 form_fields **form = &forms;
512 while (1)
513 {
514 if (*form == NULL)
515 {
516 /* new format name, add it */
517 form_fields *new_form = ZALLOC (form_fields);
518 new_form->name = insn->format_name;
519 filter_add (&new_form->fields, insn->field_names);
520 *form = new_form;
521 break;
522 }
523 else if (strcmp ((*form)->name, insn->format_name) == 0)
524 {
525 /* already present, add field names to the existing list */
526 filter_add (&(*form)->fields, insn->field_names);
527 break;
528 }
529 form = &(*form)->next;
530 }
531 }
c906108c
SS
532 return forms;
533}
534
535
536
537extern void
4e0bf4c4 538print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules)
c906108c
SS
539{
540 /* Create a list of all the different instruction formats with their
541 corresponding field names. */
542 form_fields *formats = insn_table_cache_fields (isa);
4e0bf4c4 543
c906108c
SS
544 lf_printf (file, "\n");
545 lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
546 options.module.global.prefix.u,
547 (options.gen.icache ? options.gen.icache_size : 0));
548 lf_printf (file, "\n");
4e0bf4c4 549
c906108c 550 /* create an instruction cache if being used */
4e0bf4c4 551 if (options.gen.icache)
c906108c 552 {
4e0bf4c4
AC
553 lf_printf (file, "typedef struct _%sidecode_cache {\n",
554 options.module.global.prefix.l);
c906108c 555 lf_indent (file, +2);
4e0bf4c4
AC
556 {
557 form_fields *format;
558 lf_printf (file, "unsigned_word address;\n");
559 lf_printf (file, "void *semantic;\n");
560 lf_printf (file, "union {\n");
561 lf_indent (file, +2);
562 for (format = formats; format != NULL; format = format->next)
c906108c 563 {
4e0bf4c4
AC
564 lf_printf (file, "struct {\n");
565 lf_indent (file, +2);
566 {
567 cache_entry *cache_rule;
568 char *field;
569 /* space for any instruction words */
570 if (options.gen.insn_in_icache)
571 lf_printf (file, "instruction_word insn[%d];\n",
572 isa->max_nr_words);
573 /* define an entry for any applicable cache rules */
574 for (cache_rule = cache_rules;
575 cache_rule != NULL; cache_rule = cache_rule->next)
576 {
577 /* nb - sort of correct - should really check against
578 individual instructions */
579 if (filter_is_subset
580 (format->fields, cache_rule->original_fields))
581 {
582 char *memb;
583 lf_printf (file, "%s %s;",
584 (cache_rule->type == NULL
585 ? "unsigned"
586 : cache_rule->type), cache_rule->name);
587 lf_printf (file, " /*");
588 for (memb =
589 filter_next (cache_rule->original_fields, "");
590 memb != NULL;
591 memb =
592 filter_next (cache_rule->original_fields, memb))
593 {
594 lf_printf (file, " %s", memb);
595 }
596 lf_printf (file, " */\n");
597 }
598 }
599 /* define an entry for any fields not covered by a cache rule */
600 for (field = filter_next (format->fields, "");
601 field != NULL; field = filter_next (format->fields, field))
602 {
603 cache_entry *cache_rule;
604 int found_rule = 0;
605 for (cache_rule = cache_rules;
606 cache_rule != NULL; cache_rule = cache_rule->next)
607 {
608 if (strcmp (cache_rule->name, field) == 0)
609 {
610 found_rule = 1;
611 break;
612 }
613 }
614 if (!found_rule)
615 lf_printf (file, "unsigned %s; /* default */\n", field);
616 }
617 }
618 lf_indent (file, -2);
619 lf_printf (file, "} %s;\n", format->name);
c906108c 620 }
4e0bf4c4
AC
621 lf_indent (file, -2);
622 lf_printf (file, "} crack;\n");
623 }
c906108c 624 lf_indent (file, -2);
4e0bf4c4
AC
625 lf_printf (file, "} %sidecode_cache;\n",
626 options.module.global.prefix.l);
c906108c 627 }
c906108c
SS
628 else
629 {
630 /* alernativly, since no cache, emit a dummy definition for
4e0bf4c4
AC
631 idecode_cache so that code refering to the type can still compile */
632 lf_printf (file, "typedef void %sidecode_cache;\n",
633 options.module.global.prefix.l);
c906108c
SS
634 }
635 lf_printf (file, "\n");
636}
637
638
639
640static void
641print_icache_function (lf *file,
4e0bf4c4 642 insn_entry * instruction,
c906108c
SS
643 opcode_bits *expanded_bits,
644 insn_opcodes *opcodes,
4e0bf4c4 645 cache_entry *cache_rules, int nr_prefetched_words)
c906108c
SS
646{
647 int indent;
648
649 /* generate code to enter decoded instruction into the icache */
4e0bf4c4 650 lf_printf (file, "\n");
c906108c
SS
651 lf_print__function_type_function (file, print_icache_function_type,
652 "EXTERN_ICACHE", "\n");
653 indent = print_function_name (file,
654 instruction->name,
655 instruction->format_name,
656 NULL,
4e0bf4c4 657 expanded_bits, function_name_prefix_icache);
c906108c
SS
658 indent += lf_printf (file, " ");
659 lf_indent (file, +indent);
660 lf_printf (file, "(");
661 print_icache_function_formal (file, nr_prefetched_words);
662 lf_printf (file, ")\n");
663 lf_indent (file, -indent);
4e0bf4c4 664
c906108c
SS
665 /* function header */
666 lf_printf (file, "{\n");
667 lf_indent (file, +2);
4e0bf4c4 668
c906108c
SS
669 print_my_defines (file,
670 instruction->name,
4e0bf4c4
AC
671 instruction->format_name, expanded_bits);
672 print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
673
c906108c 674 print_idecode_validate (file, instruction, opcodes);
4e0bf4c4 675
c906108c
SS
676 lf_printf (file, "\n");
677 lf_printf (file, "{\n");
678 lf_indent (file, +2);
679 if (options.gen.semantic_icache)
680 lf_printf (file, "unsigned_word nia;\n");
681 print_icache_body (file,
682 instruction,
683 expanded_bits,
684 cache_rules,
685 (options.gen.direct_access
686 ? define_variables
687 : declare_variables),
688 (options.gen.semantic_icache
689 ? both_values_and_icache
4e0bf4c4
AC
690 : put_values_in_icache), nr_prefetched_words);
691
c906108c
SS
692 lf_printf (file, "\n");
693 lf_printf (file, "cache_entry->address = cia;\n");
694 lf_printf (file, "cache_entry->semantic = ");
695 print_function_name (file,
696 instruction->name,
697 instruction->format_name,
4e0bf4c4 698 NULL, expanded_bits, function_name_prefix_semantics);
c906108c
SS
699 lf_printf (file, ";\n");
700 lf_printf (file, "\n");
701
4e0bf4c4
AC
702 if (options.gen.semantic_icache)
703 {
704 lf_printf (file, "/* semantic routine */\n");
705 print_semantic_body (file, instruction, expanded_bits, opcodes);
706 lf_printf (file, "return nia;\n");
707 }
708
c906108c
SS
709 if (!options.gen.semantic_icache)
710 {
711 lf_printf (file, "/* return the function proper */\n");
712 lf_printf (file, "return ");
713 print_function_name (file,
714 instruction->name,
715 instruction->format_name,
716 NULL,
4e0bf4c4 717 expanded_bits, function_name_prefix_semantics);
c906108c
SS
718 lf_printf (file, ";\n");
719 }
4e0bf4c4 720
c906108c
SS
721 if (options.gen.direct_access)
722 {
723 print_icache_body (file,
724 instruction,
725 expanded_bits,
726 cache_rules,
727 undef_variables,
728 (options.gen.semantic_icache
729 ? both_values_and_icache
4e0bf4c4 730 : put_values_in_icache), nr_prefetched_words);
c906108c 731 }
4e0bf4c4 732
c906108c
SS
733 lf_indent (file, -2);
734 lf_printf (file, "}\n");
735 lf_indent (file, -2);
736 lf_printf (file, "}\n");
737}
738
739
740void
741print_icache_definition (lf *file,
4e0bf4c4 742 insn_entry * insn,
c906108c
SS
743 opcode_bits *expanded_bits,
744 insn_opcodes *opcodes,
4e0bf4c4 745 cache_entry *cache_rules, int nr_prefetched_words)
c906108c
SS
746{
747 print_icache_function (file,
748 insn,
749 expanded_bits,
4e0bf4c4 750 opcodes, cache_rules, nr_prefetched_words);
c906108c
SS
751}
752
753
754
755void
756print_icache_internal_function_declaration (lf *file,
4e0bf4c4 757 function_entry * function,
c906108c
SS
758 void *data)
759{
760 ASSERT (options.gen.icache);
761 if (function->is_internal)
762 {
763 lf_printf (file, "\n");
764 lf_print__function_type_function (file, print_icache_function_type,
765 "INLINE_ICACHE", "\n");
766 print_function_name (file,
767 function->name,
4e0bf4c4 768 NULL, NULL, NULL, function_name_prefix_icache);
c906108c
SS
769 lf_printf (file, "\n(");
770 print_icache_function_formal (file, 0);
771 lf_printf (file, ");\n");
772 }
773}
774
775
776void
777print_icache_internal_function_definition (lf *file,
4e0bf4c4 778 function_entry * function,
c906108c
SS
779 void *data)
780{
781 ASSERT (options.gen.icache);
782 if (function->is_internal)
783 {
784 lf_printf (file, "\n");
785 lf_print__function_type_function (file, print_icache_function_type,
786 "INLINE_ICACHE", "\n");
787 print_function_name (file,
788 function->name,
4e0bf4c4 789 NULL, NULL, NULL, function_name_prefix_icache);
c906108c
SS
790 lf_printf (file, "\n(");
791 print_icache_function_formal (file, 0);
792 lf_printf (file, ")\n");
793 lf_printf (file, "{\n");
794 lf_indent (file, +2);
795 lf_printf (file, "/* semantic routine */\n");
796 if (options.gen.semantic_icache)
797 {
798 lf_print__line_ref (file, function->code->line);
799 table_print_code (file, function->code);
4e0bf4c4
AC
800 lf_printf (file,
801 "error (\"Internal function must longjump\\n\");\n");
c906108c
SS
802 lf_printf (file, "return 0;\n");
803 }
804 else
805 {
806 lf_printf (file, "return ");
807 print_function_name (file,
808 function->name,
809 NULL,
4e0bf4c4 810 NULL, NULL, function_name_prefix_semantics);
c906108c
SS
811 lf_printf (file, ";\n");
812 }
4e0bf4c4 813
c906108c
SS
814 lf_print__internal_ref (file);
815 lf_indent (file, -2);
816 lf_printf (file, "}\n");
817 }
818}