This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / sim / igen / gen-icache.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22 #include "misc.h"
23 #include "lf.h"
24 #include "table.h"
25 #include "filter.h"
26 #include "igen.h"
27
28 #include "ld-insn.h"
29 #include "ld-decode.h"
30
31 #include "gen.h"
32
33 #include "gen-semantics.h"
34 #include "gen-idecode.h"
35 #include "gen-icache.h"
36
37
38
39 static void
40 print_icache_function_header (lf *file,
41 const char *basename,
42 const char *format_name,
43 opcode_bits *expanded_bits,
44 int is_function_definition,
45 int nr_prefetched_words)
46 {
47 lf_printf(file, "\n");
48 lf_print__function_type_function (file, print_icache_function_type,
49 "EXTERN_ICACHE", " ");
50 print_function_name (file,
51 basename, format_name, NULL,
52 expanded_bits,
53 function_name_prefix_icache);
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
63 void
64 print_icache_declaration (lf *file,
65 insn_entry *insn,
66 opcode_bits *expanded_bits,
67 insn_opcodes *opcodes,
68 int nr_prefetched_words)
69 {
70 print_icache_function_header (file,
71 insn->name,
72 insn->format_name,
73 expanded_bits,
74 0/* is not function definition */,
75 nr_prefetched_words);
76 }
77
78
79
80 static void
81 print_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);
99
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)
129 ? declare_variables
130 : what_to_declare);
131 }
132 else
133 return;
134 break;
135 default:
136 abort (); /* Bad switch. */
137 }
138
139 /* For the type, default to a simple unsigned */
140 if (entry_type == NULL || strlen (entry_type) == 0)
141 entry_type = "unsigned";
142
143 /* look through the set of expanded sub fields to see if this field
144 has been given a constant value */
145 for (bits = expanded_bits;
146 bits != NULL;
147 bits = bits->next)
148 {
149 if (bits->field == cur_field)
150 break;
151 }
152
153 /* Define a storage area for the cache element */
154 switch (what_to_declare)
155 {
156 case undef_variables:
157 /* We've finished with the #define value - destory it */
158 lf_indent_suppress (file);
159 lf_printf (file, "#undef %s\n", entry_name);
160 return;
161 case define_variables:
162 /* Using direct access for this entry, clear any prior
163 definition, then define it */
164 lf_indent_suppress (file);
165 lf_printf (file, "#undef %s\n", entry_name);
166 /* Don't type cast pointer types! */
167 lf_indent_suppress (file);
168 if (strchr (entry_type, '*') != NULL)
169 lf_printf (file, "#define %s (", entry_name);
170 else
171 lf_printf (file, "#define %s ((%s) ", entry_name, entry_type);
172 break;
173 case declare_variables:
174 /* using variables to define the value */
175 if (line != NULL)
176 lf_print__line_ref (file, line);
177 lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name);
178 break;
179 }
180
181
182 /* define a value for that storage area as determined by what is in
183 the cache */
184 if (bits != NULL
185 && single_insn_field != NULL
186 && strcmp (entry_name, single_insn_field) == 0
187 && strcmp (entry_name, cur_field->val_string) == 0
188 && ((bits->opcode->is_boolean && bits->value == 0)
189 || (!bits->opcode->is_boolean)))
190 {
191 /* The cache rule is specifying what to do with a simple
192 instruction field.
193
194 Because of instruction expansion, the field is either a
195 constant value or equal to the specified constant (boolean
196 comparison). (The latter indicated by bits->value == 0).
197
198 The case of a field not being equal to the specified boolean
199 value is handled later. */
200 expression = "constant field";
201 ASSERT (bits->field == cur_field);
202 if (bits->opcode->is_boolean)
203 {
204 ASSERT (bits->value == 0);
205 lf_printf (file, "%d", bits->opcode->boolean_constant);
206 }
207 else if (bits->opcode->last < bits->field->last)
208 {
209 lf_printf (file, "%d",
210 bits->value << (bits->field->last - bits->opcode->last));
211 }
212 else
213 {
214 lf_printf (file, "%d", bits->value);
215 }
216 }
217 else if (bits != NULL
218 && single_insn_field != NULL
219 && strncmp (entry_name,
220 single_insn_field,
221 strlen (single_insn_field)) == 0
222 && strncmp (entry_name + strlen (single_insn_field),
223 "_is_",
224 strlen ("_is_")) == 0
225 && ((bits->opcode->is_boolean
226 && ((unsigned) atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
227 == bits->opcode->boolean_constant))
228 || (!bits->opcode->is_boolean)))
229 {
230 /* The cache rule defines an entry for the comparison between a
231 single instruction field and a constant. The value of the
232 comparison in someway matches that of the opcode field that
233 was made constant through expansion. */
234 expression = "constant compare";
235 if (bits->opcode->is_boolean)
236 {
237 lf_printf (file, "%d /* %s == %d */",
238 bits->value == 0,
239 single_insn_field,
240 bits->opcode->boolean_constant);
241 }
242 else if (bits->opcode->last < bits->field->last)
243 {
244 lf_printf (file, "%d /* %s == %d */",
245 (atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
246 == (bits->value << (bits->field->last - bits->opcode->last))),
247 single_insn_field,
248 (bits->value << (bits->field->last - bits->opcode->last)));
249 }
250 else
251 {
252 lf_printf (file, "%d /* %s == %d */",
253 (atol (entry_name + strlen (single_insn_field) + strlen ("_is_"))
254 == bits->value),
255 single_insn_field,
256 bits->value);
257 }
258 }
259 else
260 {
261 /* put the field in the local variable, possibly also enter it
262 into the cache */
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",
269 format_name,
270 entry_name);
271 if (what_to_do & put_values_in_icache) /* also put it in the cache? */
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)
282 error (line, "Instruction field entry with nonempty expression\n");
283 if (cur_field->first == 0 && cur_field->last == options.insn_bit_size - 1)
284 lf_printf (file, "(instruction_%d)",
285 cur_field->word_nr);
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 }
305
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
323 void
324 print_icache_body (lf *file,
325 insn_entry *instruction,
326 opcode_bits *expanded_bits,
327 cache_entry *cache_rules,
328 icache_decl_type what_to_declare,
329 icache_body_type what_to_do,
330 int nr_prefetched_words)
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);
365 lf_printf(file, " */\n");
366
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;
387 word_nr < instruction->nr_words;
388 word_nr++)
389 {
390 /* FIXME - should be using print_icache_extraction? */
391 lf_printf (file, "%sinstruction_word instruction_%d UNUSED = ",
392 options.module.global.prefix.l,
393 word_nr);
394 lf_printf (file, "IMEM%d_IMMED (cia, %d)",
395 options.insn_bit_size, word_nr);
396 lf_printf (file, ";\n");
397 }
398 }
399 }
400 }
401
402 /* if putting the instruction words in the cache, define references
403 for them */
404 if (options.gen.insn_in_icache) {
405 /* FIXME: is the instruction_word type correct? */
406 print_icache_extraction (file,
407 instruction->format_name,
408 cache_value,
409 "insn", /* name */
410 "instruction_word", /* type */
411 "instruction", /* expression */
412 NULL, /* origin */
413 NULL, /* line */
414 NULL, NULL,
415 what_to_declare,
416 what_to_do);
417 }
418 lf_printf(file, "\n");
419
420 /* pass one - process instruction fields.
421
422 If there is no cache rule, the default is to enter the field into
423 the cache */
424 {
425 insn_word_entry *word;
426 for (word = instruction->words;
427 word != NULL;
428 word = word->next)
429 {
430 insn_field_entry *cur_field;
431 for (cur_field = word->first;
432 cur_field->first < options.insn_bit_size;
433 cur_field = cur_field->next)
434 {
435 if (cur_field->type == insn_field_string)
436 {
437 cache_entry *cache_rule;
438 cache_entry_type value_type = cache_value;
439 line_ref *value_line = instruction->line;
440 /* check the cache table to see if it contains a rule
441 overriding the default cache action for an
442 instruction field */
443 for (cache_rule = cache_rules;
444 cache_rule != NULL;
445 cache_rule = cache_rule->next)
446 {
447 if (filter_is_subset (instruction->field_names,
448 cache_rule->original_fields)
449 && strcmp (cache_rule->name, cur_field->val_string) == 0)
450 {
451 value_type = cache_rule->entry_type;
452 value_line = cache_rule->line;
453 if (value_type == compute_value)
454 {
455 options.warning (cache_rule->line,
456 "instruction field of type `compute' changed to `cache'\n");
457 cache_rule->entry_type = cache_value;
458 }
459 break;
460 }
461 }
462 /* Define an entry for the field within the
463 instruction */
464 print_icache_extraction (file,
465 instruction->format_name,
466 value_type,
467 cur_field->val_string, /* name */
468 NULL, /* type */
469 NULL, /* expression */
470 cur_field->val_string, /* insn field */
471 value_line,
472 cur_field,
473 expanded_bits,
474 what_to_declare,
475 what_to_do);
476 }
477 }
478 }
479 }
480
481 /* pass two - any cache fields not processed above */
482 {
483 cache_entry *cache_rule;
484 for (cache_rule = cache_rules;
485 cache_rule != NULL;
486 cache_rule = cache_rule->next)
487 {
488 if (filter_is_subset (instruction->field_names,
489 cache_rule->original_fields)
490 && !filter_is_member (instruction->field_names,
491 cache_rule->name))
492 {
493 char *single_field = filter_next (cache_rule->original_fields, "");
494 if (filter_next (cache_rule->original_fields, single_field) != NULL)
495 single_field = NULL;
496 print_icache_extraction (file,
497 instruction->format_name,
498 cache_rule->entry_type,
499 cache_rule->name,
500 cache_rule->type,
501 cache_rule->expression,
502 single_field,
503 cache_rule->line,
504 NULL, /* cur_field */
505 expanded_bits,
506 what_to_declare,
507 what_to_do);
508 }
509 }
510 }
511
512 lf_print__internal_ref (file);
513 }
514
515
516
517 typedef struct _form_fields form_fields;
518 struct _form_fields {
519 char *name;
520 filter *fields;
521 form_fields *next;
522 };
523
524 static form_fields *
525 insn_table_cache_fields (insn_table *isa)
526 {
527 form_fields *forms = NULL;
528 insn_entry *insn;
529 for (insn = isa->insns;
530 insn != NULL;
531 insn = insn->next) {
532 form_fields **form = &forms;
533 while (1)
534 {
535 if (*form == NULL)
536 {
537 /* new format name, add it */
538 form_fields *new_form = ZALLOC (form_fields);
539 new_form->name = insn->format_name;
540 filter_add (&new_form->fields, insn->field_names);
541 *form = new_form;
542 break;
543 }
544 else if (strcmp ((*form)->name, insn->format_name) == 0)
545 {
546 /* already present, add field names to the existing list */
547 filter_add (&(*form)->fields, insn->field_names);
548 break;
549 }
550 form = &(*form)->next;
551 }
552 }
553 return forms;
554 }
555
556
557
558 extern void
559 print_icache_struct (lf *file,
560 insn_table *isa,
561 cache_entry *cache_rules)
562 {
563 /* Create a list of all the different instruction formats with their
564 corresponding field names. */
565 form_fields *formats = insn_table_cache_fields (isa);
566
567 lf_printf (file, "\n");
568 lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n",
569 options.module.global.prefix.u,
570 (options.gen.icache ? options.gen.icache_size : 0));
571 lf_printf (file, "\n");
572
573 /* create an instruction cache if being used */
574 if (options.gen.icache) {
575 lf_printf (file, "typedef struct _%sidecode_cache {\n",
576 options.module.global.prefix.l);
577 lf_indent (file, +2);
578 {
579 form_fields *format;
580 lf_printf (file, "unsigned_word address;\n");
581 lf_printf (file, "void *semantic;\n");
582 lf_printf (file, "union {\n");
583 lf_indent (file, +2);
584 for (format = formats;
585 format != NULL;
586 format = format->next)
587 {
588 lf_printf (file, "struct {\n");
589 lf_indent (file, +2);
590 {
591 cache_entry *cache_rule;
592 char *field;
593 /* space for any instruction words */
594 if (options.gen.insn_in_icache)
595 lf_printf (file, "instruction_word insn[%d];\n", isa->max_nr_words);
596 /* define an entry for any applicable cache rules */
597 for (cache_rule = cache_rules;
598 cache_rule != NULL;
599 cache_rule = cache_rule->next)
600 {
601 /* nb - sort of correct - should really check against
602 individual instructions */
603 if (filter_is_subset (format->fields, cache_rule->original_fields))
604 {
605 char *memb;
606 lf_printf (file, "%s %s;",
607 (cache_rule->type == NULL
608 ? "unsigned"
609 : cache_rule->type),
610 cache_rule->name);
611 lf_printf (file, " /*");
612 for (memb = filter_next (cache_rule->original_fields, "");
613 memb != NULL;
614 memb = filter_next (cache_rule->original_fields, memb))
615 {
616 lf_printf (file, " %s", memb);
617 }
618 lf_printf (file, " */\n");
619 }
620 }
621 /* define an entry for any fields not covered by a cache rule */
622 for (field = filter_next (format->fields, "");
623 field != NULL;
624 field = filter_next (format->fields, field))
625 {
626 cache_entry *cache_rule;
627 int found_rule = 0;
628 for (cache_rule = cache_rules;
629 cache_rule != NULL;
630 cache_rule = cache_rule->next)
631 {
632 if (strcmp (cache_rule->name, field) == 0)
633 {
634 found_rule = 1;
635 break;
636 }
637 }
638 if (!found_rule)
639 lf_printf (file, "unsigned %s; /* default */\n", field);
640 }
641 }
642 lf_indent (file, -2);
643 lf_printf (file, "} %s;\n", format->name);
644 }
645 lf_indent (file, -2);
646 lf_printf (file, "} crack;\n");
647 }
648 lf_indent (file, -2);
649 lf_printf (file, "} %sidecode_cache;\n", options.module.global.prefix.l);
650 }
651 else
652 {
653 /* alernativly, since no cache, emit a dummy definition for
654 idecode_cache so that code refering to the type can still compile */
655 lf_printf(file, "typedef void %sidecode_cache;\n",
656 options.module.global.prefix.l);
657 }
658 lf_printf (file, "\n");
659 }
660
661
662
663 static void
664 print_icache_function (lf *file,
665 insn_entry *instruction,
666 opcode_bits *expanded_bits,
667 insn_opcodes *opcodes,
668 cache_entry *cache_rules,
669 int nr_prefetched_words)
670 {
671 int indent;
672
673 /* generate code to enter decoded instruction into the icache */
674 lf_printf(file, "\n");
675 lf_print__function_type_function (file, print_icache_function_type,
676 "EXTERN_ICACHE", "\n");
677 indent = print_function_name (file,
678 instruction->name,
679 instruction->format_name,
680 NULL,
681 expanded_bits,
682 function_name_prefix_icache);
683 indent += lf_printf (file, " ");
684 lf_indent (file, +indent);
685 lf_printf (file, "(");
686 print_icache_function_formal (file, nr_prefetched_words);
687 lf_printf (file, ")\n");
688 lf_indent (file, -indent);
689
690 /* function header */
691 lf_printf (file, "{\n");
692 lf_indent (file, +2);
693
694 print_my_defines (file,
695 instruction->name,
696 instruction->format_name,
697 expanded_bits);
698 print_itrace (file, instruction, 1/*putting-value-in-cache*/);
699
700 print_idecode_validate (file, instruction, opcodes);
701
702 lf_printf (file, "\n");
703 lf_printf (file, "{\n");
704 lf_indent (file, +2);
705 if (options.gen.semantic_icache)
706 lf_printf (file, "unsigned_word nia;\n");
707 print_icache_body (file,
708 instruction,
709 expanded_bits,
710 cache_rules,
711 (options.gen.direct_access
712 ? define_variables
713 : declare_variables),
714 (options.gen.semantic_icache
715 ? both_values_and_icache
716 : put_values_in_icache),
717 nr_prefetched_words);
718
719 lf_printf (file, "\n");
720 lf_printf (file, "cache_entry->address = cia;\n");
721 lf_printf (file, "cache_entry->semantic = ");
722 print_function_name (file,
723 instruction->name,
724 instruction->format_name,
725 NULL,
726 expanded_bits,
727 function_name_prefix_semantics);
728 lf_printf (file, ";\n");
729 lf_printf (file, "\n");
730
731 if (options.gen.semantic_icache) {
732 lf_printf (file, "/* semantic routine */\n");
733 print_semantic_body (file,
734 instruction,
735 expanded_bits,
736 opcodes);
737 lf_printf (file, "return nia;\n");
738 }
739
740 if (!options.gen.semantic_icache)
741 {
742 lf_printf (file, "/* return the function proper */\n");
743 lf_printf (file, "return ");
744 print_function_name (file,
745 instruction->name,
746 instruction->format_name,
747 NULL,
748 expanded_bits,
749 function_name_prefix_semantics);
750 lf_printf (file, ";\n");
751 }
752
753 if (options.gen.direct_access)
754 {
755 print_icache_body (file,
756 instruction,
757 expanded_bits,
758 cache_rules,
759 undef_variables,
760 (options.gen.semantic_icache
761 ? both_values_and_icache
762 : put_values_in_icache),
763 nr_prefetched_words);
764 }
765
766 lf_indent (file, -2);
767 lf_printf (file, "}\n");
768 lf_indent (file, -2);
769 lf_printf (file, "}\n");
770 }
771
772
773 void
774 print_icache_definition (lf *file,
775 insn_entry *insn,
776 opcode_bits *expanded_bits,
777 insn_opcodes *opcodes,
778 cache_entry *cache_rules,
779 int nr_prefetched_words)
780 {
781 print_icache_function (file,
782 insn,
783 expanded_bits,
784 opcodes,
785 cache_rules,
786 nr_prefetched_words);
787 }
788
789
790
791 void
792 print_icache_internal_function_declaration (lf *file,
793 function_entry *function,
794 void *data)
795 {
796 ASSERT (options.gen.icache);
797 if (function->is_internal)
798 {
799 lf_printf (file, "\n");
800 lf_print__function_type_function (file, print_icache_function_type,
801 "INLINE_ICACHE", "\n");
802 print_function_name (file,
803 function->name,
804 NULL,
805 NULL,
806 NULL,
807 function_name_prefix_icache);
808 lf_printf (file, "\n(");
809 print_icache_function_formal (file, 0);
810 lf_printf (file, ");\n");
811 }
812 }
813
814
815 void
816 print_icache_internal_function_definition (lf *file,
817 function_entry *function,
818 void *data)
819 {
820 ASSERT (options.gen.icache);
821 if (function->is_internal)
822 {
823 lf_printf (file, "\n");
824 lf_print__function_type_function (file, print_icache_function_type,
825 "INLINE_ICACHE", "\n");
826 print_function_name (file,
827 function->name,
828 NULL,
829 NULL,
830 NULL,
831 function_name_prefix_icache);
832 lf_printf (file, "\n(");
833 print_icache_function_formal (file, 0);
834 lf_printf (file, ")\n");
835 lf_printf (file, "{\n");
836 lf_indent (file, +2);
837 lf_printf (file, "/* semantic routine */\n");
838 if (options.gen.semantic_icache)
839 {
840 lf_print__line_ref (file, function->code->line);
841 table_print_code (file, function->code);
842 lf_printf (file, "error (\"Internal function must longjump\\n\");\n");
843 lf_printf (file, "return 0;\n");
844 }
845 else
846 {
847 lf_printf (file, "return ");
848 print_function_name (file,
849 function->name,
850 NULL,
851 NULL,
852 NULL,
853 function_name_prefix_semantics);
854 lf_printf (file, ";\n");
855 }
856
857 lf_print__internal_ref (file);
858 lf_indent (file, -2);
859 lf_printf (file, "}\n");
860 }
861 }
This page took 0.046478 seconds and 5 git commands to generate.