(TARGET_CPU_arm*, TARGET_CPU_strongarm*, TARGET_CPU_generic):
[official-gcc.git] / gcc / bc-emit.c
blobc93195df9e1b80693dc488c6389c851ae0304fb7
1 /* Output bytecodes for GNU C-compiler.
2 Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #ifdef __STDC__
24 #include <stdarg.h>
25 #else
26 #include <varargs.h>
27 #endif
28 #include "machmode.h"
29 #include "rtl.h"
30 #include "real.h"
31 #include "obstack.h"
32 #include "bytecode.h"
33 #ifdef __GNUC__
34 #include "bytetypes.h"
35 #endif
36 #include "bc-emit.h"
37 #include "bc-opcode.h"
38 #include "bc-typecd.h"
39 #include "bi-run.h"
41 #include <stdio.h>
43 extern char *xmalloc (), *xrealloc ();
45 extern struct obstack *rtl_obstack;
47 /* Indexed by mode class, gives the narrowest mode for each class. */
49 extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
51 /* Commonly used modes. */
52 /* Mode whose width is BITS_PER_UNIT */
53 extern enum machine_mode byte_mode;
55 /* Mode whose width is BITS_PER_WORD */
56 extern enum machine_mode word_mode;
58 /* Vector indexed by opcode giving info about the args for each opcode. */
59 static struct arityvec arityvec[] = {
60 #include "bc-arity.h"
63 /* How to print a symbol name for the assembler. */
65 static void
66 prsym (file, s)
67 FILE *file;
68 char *s;
70 if (*s == '*')
71 fprintf (file, "%s", s + 1);
72 else
74 #ifdef NAMES_HAVE_UNDERSCORES
75 fprintf (file, "_%s", s);
76 #else
77 fprintf (file, "%s", s);
78 #endif
82 /* Maintain a bucket hash table for symbol names. */
84 #define HASH_BITS 32
85 #define HASH_SIZE 509
87 static struct bc_sym *hashtab[HASH_SIZE];
89 static unsigned int
90 hash (name)
91 char *name;
93 unsigned int hash = 0;
95 while (*name)
97 hash = hash << 3 | hash >> HASH_BITS - 3;
98 hash += *name++;
101 return hash % HASH_SIZE;
105 /* Look up the named symbol, creating it if it doesn't exist. */
107 struct bc_sym *
108 sym_lookup (name)
109 char *name;
111 int i;
112 struct bc_sym *s;
114 i = hash (name);
115 for (s = hashtab[i]; s; s = s->next)
116 if (!strcmp (s->name, name))
117 return s;
119 s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
120 s->name = xmalloc (strlen (name) + 1);
121 strcpy (s->name, name);
122 s->defined = s->global = s->common = 0;
123 s->val = 0;
124 s->next = hashtab[i];
125 hashtab[i] = s;
126 return s;
130 /* Write out .globl and common symbols to the named file. */
132 static void
133 bc_sym_write (file)
134 FILE *file;
136 int i;
137 struct bc_sym *s;
139 for (i = 0; i < HASH_SIZE; ++i)
140 for (s = hashtab[i]; s; s = s->next)
142 if (s->global)
144 fprintf (file, "\n\t.globl ");
145 prsym (file, s->name);
146 putc ('\n', file);
147 if (s->common)
149 fprintf (file, "\n\t.comm ");
150 prsym (file, s->name);
151 fprintf (file, ", %lu\n", s->val);
154 else if (s->common)
156 fprintf (file, "\n\t.lcomm ");
157 prsym (file, s->name);
158 fprintf (file, ", %lu\n", s->val);
166 /* Create and initialize a new segment. */
168 static struct bc_seg *
169 seg_create ()
171 struct bc_seg *result;
173 result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
174 result->alloc = 256;
175 result->data = xmalloc (result->alloc);
176 result->size = 0;
177 result->syms = 0;
178 result->relocs = 0;
179 return result;
183 /* Advance the segment index to the next alignment boundary. */
185 static void
186 seg_align (seg, log)
187 struct bc_seg *seg;
188 int log;
190 unsigned int oldsize = seg->size;
192 seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
193 if (seg->size > seg->alloc)
195 while (seg->size > seg->alloc)
196 seg->alloc *= 2;
197 seg->data = xrealloc (seg->data, seg->alloc);
199 bzero (seg->data + oldsize, seg->size - oldsize);
203 /* Append the given data to the given segment. */
205 static void
206 seg_data (seg, data, size)
207 struct bc_seg *seg;
208 char *data;
209 unsigned int size;
211 if (seg->size + size > seg->alloc)
213 while (seg->size + size > seg->alloc)
214 seg->alloc *= 2;
215 seg->data = xrealloc (seg->data, seg->alloc);
218 bcopy (data, seg->data + seg->size, size);
219 seg->size += size;
223 /* Append a zero-filled skip to the given segment. */
225 static void
226 seg_skip (seg, size)
227 struct bc_seg *seg;
228 unsigned int size;
230 if (seg->size + size > seg->alloc)
232 while (seg->size + size > seg->alloc)
233 seg->alloc *= 2;
234 seg->data = xrealloc (seg->data, seg->alloc);
237 memset (seg->data + seg->size, 0, size);
238 seg->size += size;
242 /* Define the given name as the current offset in the given segment. It
243 is an error if the name is already defined. Return 0 or 1 indicating
244 failure or success respectively. */
246 static int
247 seg_defsym (seg, name)
248 struct bc_seg *seg;
249 char *name;
251 struct bc_sym *sym;
252 struct bc_segsym *segsym;
254 sym = sym_lookup (name);
255 if (sym->defined)
256 return 0;
258 sym->defined = 1;
259 sym->val = seg->size;
260 segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
261 segsym->sym = sym;
262 segsym->next = seg->syms;
263 seg->syms = segsym;
264 return 1;
268 /* Generate in seg's data a reference to the given sym, adjusted by
269 the given offset. */
271 static void
272 seg_refsym (seg, name, offset)
273 struct bc_seg *seg;
274 char *name;
275 int offset;
277 struct bc_sym *sym;
278 struct bc_segreloc *segreloc;
280 sym = sym_lookup (name);
281 segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
282 segreloc->offset = seg->size;
283 segreloc->sym = sym;
284 segreloc->next = seg->relocs;
285 seg->relocs = segreloc;
286 seg_data (seg, (char *) &offset, sizeof offset);
290 /* Concatenate the contents of given segments into the first argument. */
292 static void
293 seg_concat (result, seg)
294 struct bc_seg *result, *seg;
296 unsigned int fix;
297 struct bc_segsym *segsym;
298 struct bc_segreloc *segreloc;
300 seg_align (result, MACHINE_SEG_ALIGN);
301 fix = result->size;
302 seg_data (result, seg->data, seg->size);
303 free (seg->data);
305 /* Go through the symbols and relocs of SEG, adjusting their offsets
306 for their new location in RESULT. */
307 if (seg->syms)
309 segsym = seg->syms;
311 segsym->sym->val += fix;
312 while (segsym->next && (segsym = segsym->next));
313 segsym->next = result->syms;
314 result->syms = seg->syms;
316 if (seg->relocs)
318 segreloc = seg->relocs;
320 segreloc->offset += fix;
321 while (segreloc->next && (segreloc = segreloc->next));
322 segreloc->next = result->relocs;
323 result->relocs = seg->relocs;
326 free ((char *) seg);
329 /* Write a segment to a file. */
331 static void
332 bc_seg_write (seg, file)
333 struct bc_seg *seg;
334 FILE *file;
336 struct bc_segsym *segsym, *nsegsym, *psegsym;
337 struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
338 int i, offset, flag;
340 /* Reverse the list of symbols. */
341 for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
343 nsegsym = segsym->next;
344 segsym->next = psegsym;
345 psegsym = segsym;
347 seg->syms = psegsym;
349 /* Reverse the list of relocs. */
350 for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
352 nsegreloc = segreloc->next;
353 segreloc->next = psegreloc;
354 psegreloc = segreloc;
356 seg->relocs = psegreloc;
358 /* Output each byte of the segment. */
359 for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
361 while (segsym && segsym->sym->val == i)
363 if (i % 8 != 0)
364 putc ('\n', file);
366 BC_WRITE_SEGSYM (segsym, file);
367 segsym = segsym->next;
368 flag = 1;
370 if (segreloc && segreloc->offset == i)
372 if (i % 8 != 0)
373 putc ('\n', file);
375 bcopy (seg->data + i, (char *) &offset, sizeof (int));
376 i += sizeof (int) - 1;
378 BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
379 segreloc = segreloc->next;
380 flag = 1;
382 else
384 if (i % 8 == 0 || flag)
385 BC_START_BYTECODE_LINE (file);
387 BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
388 seg->data[i] & 0xFF,
389 file);
390 flag = 0;
391 if (i % 8 == 7)
392 putc ('\n', file);
396 /* Paranoia check--we should have visited all syms and relocs during
397 the output pass. */
399 if (segsym || segreloc)
400 abort ();
405 /* Text and data segments of the object file in making. */
406 static struct bc_seg *bc_text_seg;
407 static struct bc_seg *bc_data_seg;
409 /* Called before anything else in this module. */
411 void
412 bc_initialize ()
414 int min_class_size[(int) MAX_MODE_CLASS];
415 enum machine_mode mode;
416 int i;
418 bc_init_mode_to_code_map ();
420 bc_text_seg = seg_create ();
421 bc_data_seg = seg_create ();
423 dconst0 = REAL_VALUE_ATOF ("0", DFmode);
424 dconst1 = REAL_VALUE_ATOF ("1", DFmode);
425 dconst2 = REAL_VALUE_ATOF ("2", DFmode);
426 dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
428 /* Find the narrowest mode for each class and compute the word and byte
429 modes. */
431 for (i = 0; i < (int) MAX_MODE_CLASS; i++)
432 min_class_size[i] = 1000;
434 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
435 mode = (enum machine_mode) ((int) mode + 1))
437 if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
439 class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
440 min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
442 if (GET_MODE_CLASS (mode) == MODE_INT
443 && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
444 byte_mode = mode;
446 if (GET_MODE_CLASS (mode) == MODE_INT
447 && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
448 word_mode = mode;
453 /* External addresses referenced in a function. Rather than trying to
454 work relocatable address directly into bytecoded functions (which would
455 require us to provide hairy location info and possibly obey alignment
456 rules imposed by the architecture) we build an auxiliary table of
457 pointer constants, and encode just offsets into this table into the
458 actual bytecode. */
459 static struct bc_seg *ptrconsts;
461 /* Trampoline code for the function entry. */
462 struct bc_seg *trampoline;
464 /* Actual byte code of the function. */
465 struct bc_seg *bytecode;
467 /* List of labels defined in the function. */
468 struct bc_label *labels;
470 /* List of label references in the function. */
471 struct bc_labelref *labelrefs;
474 /* Add symbol to pointer table. Return offset into table where
475 pointer was stored. The offset usually goes into the bytecode
476 stream as a constP literal. */
479 bc_define_pointer (p)
480 char *p;
482 int offset = ptrconsts->size;
484 seg_refsym (ptrconsts, p, 0);
485 return offset;
489 /* Begin a bytecoded function. */
492 bc_begin_function (name)
493 char *name;
495 ptrconsts = seg_create ();
496 trampoline = seg_create ();
497 bytecode = seg_create ();
498 return seg_defsym (trampoline, name);
502 /* Force alignment in inline bytecode. */
504 void
505 bc_align_bytecode (align)
506 int align;
508 seg_align (bytecode, align);
512 /* Emit data inline into bytecode. */
514 void
515 bc_emit_bytecode_const (data, size)
516 char *data;
517 unsigned int size;
519 if (bytecode)
520 seg_data (bytecode, data, size);
524 /* Create a new "bytecode label", to have its value defined later.
525 Bytecode labels have nothing to do with the object file symbol table,
526 and are purely local to a given bytecoded function. */
528 struct bc_label *
529 bc_get_bytecode_label ()
531 struct bc_label *result;
533 result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
534 result->defined = 0;
535 result->next = labels;
536 result->uid = 0;
537 labels = result;
538 return result;
542 /* Define the given label with the current location counter. */
545 bc_emit_bytecode_labeldef (label)
546 struct bc_label *label;
548 extern int bc_new_uid ();
550 if (!label || label->defined)
551 return 0;
553 label->offset = bytecode->size;
554 label->defined = 1;
555 label->uid = bc_new_uid ();
557 #ifdef DEBUG_PRINT_CODE
558 fprintf (stderr, "$%lx:\n", label);
559 #endif
561 return 1;
565 /* Generate a location-relative reference to the given bytecode label.
566 It need not be defined yet; label references will be backpatched later. */
568 void
569 bc_emit_bytecode_labelref (label)
570 struct bc_label *label;
572 struct bc_labelref *labelref;
573 static int zero;
575 labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
576 labelref->label = label;
577 labelref->offset = bytecode->size;
578 labelref->next = labelrefs;
579 labelrefs = labelref;
581 #ifdef DEBUG_PRINT_CODE
582 fprintf (stderr, " $%lx", label);
583 #endif
585 seg_data (bytecode, (char *) &zero, sizeof zero);
589 /* Emit a reference to an external address; generate the reference in the
590 ptrconst area, and emit an offset in the bytecode. */
592 void
593 bc_emit_code_labelref (name, offset)
594 char *name;
595 int offset;
597 int ptroff;
599 ptroff = ptrconsts->size / sizeof (char *);
600 seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
601 seg_refsym (ptrconsts, name, offset);
603 #ifdef DEBUG_PRINT_CODE
604 fprintf (stderr, " [external <%x> %s]", ptroff, name);
605 #endif
609 /* Backpatch label references in the byte code, and concatenate the bytecode
610 and pointer constant segments to the cumulative text for the object file.
611 Return a label name for the pointer constants region. */
613 char *
614 bc_end_function ()
616 int addr;
617 struct bc_label *label, *next;
618 struct bc_labelref *ref, *nextref;
619 char ptrconsts_label[20];
620 static int nlab;
622 /* Backpatch bytecode label references. */
623 for (ref = labelrefs; ref; ref = ref->next)
624 if (ref->label->defined)
626 addr = ref->label->offset;
627 bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
630 /* Free the chains of labelrefs and labeldefs. */
631 for (ref = labelrefs; ref; ref = nextref)
633 nextref = ref->next;
634 free ((char *) ref);
637 for (label = labels; label; label = next)
639 next = label->next;
640 free ((char *) label);
643 seg_concat (trampoline, bytecode);
644 seg_align (trampoline, MACHINE_SEG_ALIGN);
645 sprintf (ptrconsts_label, "*LP%d", nlab++);
646 seg_defsym (trampoline, ptrconsts_label);
647 seg_concat (trampoline, ptrconsts);
648 seg_concat (bc_text_seg, trampoline);
650 labels = 0;
651 labelrefs = 0;
652 trampoline = 0;
653 bytecode = 0;
654 ptrconsts = 0;
656 return sym_lookup (ptrconsts_label)->name;
659 /* Force alignment in const data. */
661 void
662 bc_align_const (align)
663 int align;
665 seg_align (bc_text_seg, align);
668 /* Emit const data. */
670 void
671 bc_emit_const (data, size)
672 char *data;
673 unsigned int size;
675 seg_data (bc_text_seg, data, size);
678 /* Emit a zero-filled constant skip. */
680 void
681 bc_emit_const_skip (size)
682 unsigned int size;
684 seg_skip (bc_text_seg, size);
687 /* Emit a label definition in const data. */
690 bc_emit_const_labeldef (name)
691 char *name;
693 return seg_defsym (bc_text_seg, name);
696 /* Emit a label reference in const data. */
698 void
699 bc_emit_const_labelref (name, offset)
700 char *name;
701 int offset;
703 seg_refsym (bc_text_seg, name, offset);
706 /* Force alignment in data. */
708 void
709 bc_align_data (align)
710 int align;
712 seg_align (bc_data_seg, align);
715 /* Emit data. */
717 void
718 bc_emit_data (data, size)
719 char *data;
720 unsigned int size;
722 seg_data (bc_data_seg, data, size);
725 /* Emit a zero-filled data skip. */
727 void
728 bc_emit_data_skip (size)
729 unsigned int size;
731 seg_skip (bc_data_seg, size);
734 /* Emit label definition in data. */
737 bc_emit_data_labeldef (name)
738 char *name;
740 return seg_defsym (bc_data_seg, name);
743 /* Emit label reference in data. */
745 void
746 bc_emit_data_labelref (name, offset)
747 char *name;
748 int offset;
750 seg_refsym (bc_data_seg, name, offset);
753 /* Emit a common block of the given name and size. Note that
754 when the .o file is actually written non-global "common"
755 blocks will have to be turned into space in the data section. */
758 bc_emit_common (name, size)
759 char *name;
760 unsigned int size;
762 struct bc_sym *sym;
764 sym = sym_lookup (name);
765 if (sym->defined)
766 return 0;
768 sym->defined = 1;
769 sym->common = 1;
770 sym->val = size;
771 return 1;
774 /* Globalize the given label. */
776 void
777 bc_globalize_label (name)
778 char *name;
780 struct bc_sym *sym;
782 sym = sym_lookup (name);
783 sym->global = 1;
786 static enum { in_text, in_data } section = in_text;
788 void
789 bc_text ()
791 section = in_text;
794 void
795 bc_data ()
797 section = in_data;
800 void
801 bc_align (align)
802 int align;
804 if (section == in_text)
805 bc_align_const (align);
806 else
807 bc_align_data (align);
810 void
811 bc_emit (data, size)
812 char *data;
813 unsigned int size;
815 if (section == in_text)
816 bc_emit_const (data, size);
817 else
818 bc_emit_data (data, size);
821 void
822 bc_emit_skip (size)
823 unsigned int size;
825 if (section == in_text)
826 bc_emit_const_skip (size);
827 else
828 bc_emit_data_skip (size);
832 bc_emit_labeldef (name)
833 char *name;
835 if (section == in_text)
836 return bc_emit_const_labeldef (name);
837 else
838 return bc_emit_data_labeldef (name);
841 void
842 bc_emit_labelref (name, offset)
843 char *name;
844 int offset;
846 if (section == in_text)
847 bc_emit_const_labelref (name, offset);
848 else
849 bc_emit_data_labelref (name, offset);
852 void
853 bc_write_file (file)
854 FILE *file;
856 BC_WRITE_FILE (file);
860 /* Allocate a new bytecode rtx.
861 If you supply a null BC_LABEL, we generate one. */
864 bc_gen_rtx (label, offset, bc_label)
865 char *label;
866 int offset;
867 struct bc_label *bc_label;
869 rtx r;
871 if (bc_label == 0)
872 bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
874 r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
875 bc_label->offset = offset;
877 return r;
881 /* Print bytecode rtx */
883 void
884 bc_print_rtl (fp, r)
885 FILE *fp;
886 rtx r;
888 #if 0 /* This needs to get fixed to really work again. */
889 /* BC_WRITE_RTL has a definition
890 that doesn't even make sense for this use. */
891 BC_WRITE_RTL (r, fp);
892 #endif
896 /* Emit a bytecode, keeping a running tally of the stack depth. */
898 void
899 bc_emit_bytecode (bytecode)
900 enum bytecode_opcode bytecode;
902 char byte;
903 static int prev_lineno = -1;
905 byte = (char) bytecode;
907 #ifdef BCDEBUG_PRINT_CODE
908 if (lineno != prev_lineno)
910 fprintf (stderr, "<line %d>\n", lineno);
911 prev_lineno = lineno;
914 fputs (opcode_name[(unsigned int) bytecode], stderr);
915 #endif
917 /* Due to errors we are often requested to output bytecodes that
918 will cause an interpreter stack undeflow when executed. Instead of
919 dumping core on such occasions, we omit the bytecode. Erroneous code
920 should not be executed, regardless. This makes life much easier, since
921 we don't have to deceive ourselves about the known stack depth. */
923 bc_emit_bytecode_const (&byte, 1);
925 if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
927 if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
928 max_stack_depth = stack_depth;
931 #ifdef VALIDATE_STACK_FOR_BC
932 VALIDATE_STACK_FOR_BC ();
933 #endif
937 #ifdef BCDEBUG_PRINT_CODE
938 #define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR)
939 #else
940 #define PRLIT(X,Y)
941 #endif
943 /* Emit a complete bytecode instruction, expecting the correct number
944 of literal values in the call. First argument is the instruction, the
945 remaining arguments are literals of size HOST_WIDE_INT or smaller. */
947 void
948 bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
950 #ifndef __STDC__
951 enum bytecode_opcode opcode;
952 #endif
953 va_list arguments;
954 int nliteral, instruction;
956 VA_START (arguments, opcode);
958 #ifndef __STDC__
959 opcode = va_arg (arguments, enum bytecode_opcode);
960 #endif
962 /* Emit instruction bytecode */
963 bc_emit_bytecode (opcode);
964 instruction = (int) opcode;
966 /* Loop literals and emit as bytecode constants */
967 for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
969 switch (arityvec[instruction].literals[nliteral])
971 /* This conditional is a kludge, but it's necessary
972 because TYPE might be long long. */
973 #ifdef __GNUC__
974 /* Expand definitions into case statements */
975 #define DEFTYPECODE(CODE, NAME, MODE, TYPE) \
976 case CODE: \
978 TYPE temp = va_arg (arguments, TYPE); \
979 bc_emit_bytecode_const ((void *) &temp, sizeof temp); \
980 PRLIT (TYPE, &temp); } \
981 break;
983 #include "bc-typecd.def"
985 #undef DEFTYPECODE
986 #endif /* __GNUC__ */
988 default:
989 abort ();
993 va_end (arguments);
995 #ifdef BCDEBUG_PRINT_CODE
996 fputc ('\n', stderr);
997 #endif
1000 /* Emit the machine-code interface trampoline at the beginning of a byte
1001 coded function. The argument is a label name of the interpreter
1002 bytecode callinfo structure; the return value is a label name for
1003 the beginning of the actual bytecode. */
1005 char *
1006 bc_emit_trampoline (callinfo)
1007 char *callinfo;
1009 char mylab[20];
1010 static int n;
1012 sprintf (mylab, "*LB%d", n++);
1014 BC_EMIT_TRAMPOLINE (trampoline, callinfo);
1016 seg_defsym (bytecode, mylab);
1017 return sym_lookup (mylab)->name;