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