Import final gcc2 snapshot (990109)
[official-gcc.git] / gcc / bc-emit.c
blob1a9357beec6481ab09f6041f59b01d912c45b346
1 /* Output bytecodes for GNU C-compiler.
2 Copyright (C) 1993, 1994, 1996, 1997, 1998 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 #include "system.h"
24 #include "machmode.h"
25 #include "rtl.h"
26 #include "real.h"
27 #include "obstack.h"
28 #include "bytecode.h"
29 #ifdef __GNUC__
30 #include "bytetypes.h"
31 #endif
32 #include "bc-emit.h"
33 #include "bc-opcode.h"
34 #include "bc-typecd.h"
35 #include "bi-run.h"
37 extern char *xmalloc (), *xrealloc ();
39 extern struct obstack *rtl_obstack;
41 /* Indexed by mode class, gives the narrowest mode for each class. */
43 extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
45 /* Commonly used modes. */
46 /* Mode whose width is BITS_PER_UNIT */
47 extern enum machine_mode byte_mode;
49 /* Mode whose width is BITS_PER_WORD */
50 extern enum machine_mode word_mode;
52 /* Vector indexed by opcode giving info about the args for each opcode. */
53 static struct arityvec arityvec[] = {
54 #include "bc-arity.h"
57 /* How to print a symbol name for the assembler. */
59 static void
60 prsym (file, s)
61 FILE *file;
62 char *s;
64 if (*s == '*')
65 fprintf (file, "%s", s + 1);
66 else
68 #ifdef NAMES_HAVE_UNDERSCORES
69 fprintf (file, "_%s", s);
70 #else
71 fprintf (file, "%s", s);
72 #endif
76 /* Maintain a bucket hash table for symbol names. */
78 #define HASH_BITS 32
79 #define HASH_SIZE 509
81 static struct bc_sym *hashtab[HASH_SIZE];
83 static unsigned int
84 hash (name)
85 char *name;
87 unsigned int hash = 0;
89 while (*name)
91 hash = hash << 3 | hash >> HASH_BITS - 3;
92 hash += *name++;
95 return hash % HASH_SIZE;
99 /* Look up the named symbol, creating it if it doesn't exist. */
101 struct bc_sym *
102 sym_lookup (name)
103 char *name;
105 int i;
106 struct bc_sym *s;
108 i = hash (name);
109 for (s = hashtab[i]; s; s = s->next)
110 if (!strcmp (s->name, name))
111 return s;
113 s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
114 s->name = xmalloc (strlen (name) + 1);
115 strcpy (s->name, name);
116 s->defined = s->global = s->common = 0;
117 s->val = 0;
118 s->next = hashtab[i];
119 hashtab[i] = s;
120 return s;
124 /* Write out .globl and common symbols to the named file. */
126 static void
127 bc_sym_write (file)
128 FILE *file;
130 int i;
131 struct bc_sym *s;
133 for (i = 0; i < HASH_SIZE; ++i)
134 for (s = hashtab[i]; s; s = s->next)
136 if (s->global)
138 fprintf (file, "\n\t.globl ");
139 prsym (file, s->name);
140 putc ('\n', file);
141 if (s->common)
143 fprintf (file, "\n\t.comm ");
144 prsym (file, s->name);
145 fprintf (file, ", %lu\n", s->val);
148 else if (s->common)
150 fprintf (file, "\n\t.lcomm ");
151 prsym (file, s->name);
152 fprintf (file, ", %lu\n", s->val);
160 /* Create and initialize a new segment. */
162 static struct bc_seg *
163 seg_create ()
165 struct bc_seg *result;
167 result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
168 result->alloc = 256;
169 result->data = xmalloc (result->alloc);
170 result->size = 0;
171 result->syms = 0;
172 result->relocs = 0;
173 return result;
177 /* Advance the segment index to the next alignment boundary. */
179 static void
180 seg_align (seg, log)
181 struct bc_seg *seg;
182 int log;
184 unsigned int oldsize = seg->size;
186 seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
187 if (seg->size > seg->alloc)
189 while (seg->size > seg->alloc)
190 seg->alloc *= 2;
191 seg->data = xrealloc (seg->data, seg->alloc);
193 bzero (seg->data + oldsize, seg->size - oldsize);
197 /* Append the given data to the given segment. */
199 static void
200 seg_data (seg, data, size)
201 struct bc_seg *seg;
202 char *data;
203 unsigned int size;
205 if (seg->size + size > seg->alloc)
207 while (seg->size + size > seg->alloc)
208 seg->alloc *= 2;
209 seg->data = xrealloc (seg->data, seg->alloc);
212 bcopy (data, seg->data + seg->size, size);
213 seg->size += size;
217 /* Append a zero-filled skip to the given segment. */
219 static void
220 seg_skip (seg, size)
221 struct bc_seg *seg;
222 unsigned int size;
224 if (seg->size + size > seg->alloc)
226 while (seg->size + size > seg->alloc)
227 seg->alloc *= 2;
228 seg->data = xrealloc (seg->data, seg->alloc);
231 memset (seg->data + seg->size, 0, size);
232 seg->size += size;
236 /* Define the given name as the current offset in the given segment. It
237 is an error if the name is already defined. Return 0 or 1 indicating
238 failure or success respectively. */
240 static int
241 seg_defsym (seg, name)
242 struct bc_seg *seg;
243 char *name;
245 struct bc_sym *sym;
246 struct bc_segsym *segsym;
248 sym = sym_lookup (name);
249 if (sym->defined)
250 return 0;
252 sym->defined = 1;
253 sym->val = seg->size;
254 segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
255 segsym->sym = sym;
256 segsym->next = seg->syms;
257 seg->syms = segsym;
258 return 1;
262 /* Generate in seg's data a reference to the given sym, adjusted by
263 the given offset. */
265 static void
266 seg_refsym (seg, name, offset)
267 struct bc_seg *seg;
268 char *name;
269 int offset;
271 struct bc_sym *sym;
272 struct bc_segreloc *segreloc;
274 sym = sym_lookup (name);
275 segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
276 segreloc->offset = seg->size;
277 segreloc->sym = sym;
278 segreloc->next = seg->relocs;
279 seg->relocs = segreloc;
280 seg_data (seg, (char *) &offset, sizeof offset);
284 /* Concatenate the contents of given segments into the first argument. */
286 static void
287 seg_concat (result, seg)
288 struct bc_seg *result, *seg;
290 unsigned int fix;
291 struct bc_segsym *segsym;
292 struct bc_segreloc *segreloc;
294 seg_align (result, MACHINE_SEG_ALIGN);
295 fix = result->size;
296 seg_data (result, seg->data, seg->size);
297 free (seg->data);
299 /* Go through the symbols and relocs of SEG, adjusting their offsets
300 for their new location in RESULT. */
301 if (seg->syms)
303 segsym = seg->syms;
305 segsym->sym->val += fix;
306 while (segsym->next && (segsym = segsym->next));
307 segsym->next = result->syms;
308 result->syms = seg->syms;
310 if (seg->relocs)
312 segreloc = seg->relocs;
314 segreloc->offset += fix;
315 while (segreloc->next && (segreloc = segreloc->next));
316 segreloc->next = result->relocs;
317 result->relocs = seg->relocs;
320 free ((char *) seg);
323 /* Write a segment to a file. */
325 static void
326 bc_seg_write (seg, file)
327 struct bc_seg *seg;
328 FILE *file;
330 struct bc_segsym *segsym, *nsegsym, *psegsym;
331 struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
332 int i, offset, flag;
334 /* Reverse the list of symbols. */
335 for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
337 nsegsym = segsym->next;
338 segsym->next = psegsym;
339 psegsym = segsym;
341 seg->syms = psegsym;
343 /* Reverse the list of relocs. */
344 for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
346 nsegreloc = segreloc->next;
347 segreloc->next = psegreloc;
348 psegreloc = segreloc;
350 seg->relocs = psegreloc;
352 /* Output each byte of the segment. */
353 for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
355 while (segsym && segsym->sym->val == i)
357 if (i % 8 != 0)
358 putc ('\n', file);
360 BC_WRITE_SEGSYM (segsym, file);
361 segsym = segsym->next;
362 flag = 1;
364 if (segreloc && segreloc->offset == i)
366 if (i % 8 != 0)
367 putc ('\n', file);
369 bcopy (seg->data + i, (char *) &offset, sizeof (int));
370 i += sizeof (int) - 1;
372 BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
373 segreloc = segreloc->next;
374 flag = 1;
376 else
378 if (i % 8 == 0 || flag)
379 BC_START_BYTECODE_LINE (file);
381 BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
382 seg->data[i] & 0xFF,
383 file);
384 flag = 0;
385 if (i % 8 == 7)
386 putc ('\n', file);
390 /* Paranoia check--we should have visited all syms and relocs during
391 the output pass. */
393 if (segsym || segreloc)
394 abort ();
399 /* Text and data segments of the object file in making. */
400 static struct bc_seg *bc_text_seg;
401 static struct bc_seg *bc_data_seg;
403 /* Called before anything else in this module. */
405 void
406 bc_initialize ()
408 int min_class_size[(int) MAX_MODE_CLASS];
409 enum machine_mode mode;
410 int i;
412 bc_init_mode_to_code_map ();
414 bc_text_seg = seg_create ();
415 bc_data_seg = seg_create ();
417 dconst0 = REAL_VALUE_ATOF ("0", DFmode);
418 dconst1 = REAL_VALUE_ATOF ("1", DFmode);
419 dconst2 = REAL_VALUE_ATOF ("2", DFmode);
420 dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
422 /* Find the narrowest mode for each class and compute the word and byte
423 modes. */
425 for (i = 0; i < (int) MAX_MODE_CLASS; i++)
426 min_class_size[i] = 1000;
428 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
429 mode = (enum machine_mode) ((int) mode + 1))
431 if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
433 class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
434 min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
436 if (GET_MODE_CLASS (mode) == MODE_INT
437 && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
438 byte_mode = mode;
440 if (GET_MODE_CLASS (mode) == MODE_INT
441 && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
442 word_mode = mode;
447 /* External addresses referenced in a function. Rather than trying to
448 work relocatable address directly into bytecoded functions (which would
449 require us to provide hairy location info and possibly obey alignment
450 rules imposed by the architecture) we build an auxiliary table of
451 pointer constants, and encode just offsets into this table into the
452 actual bytecode. */
453 static struct bc_seg *ptrconsts;
455 /* Trampoline code for the function entry. */
456 struct bc_seg *trampoline;
458 /* Actual byte code of the function. */
459 struct bc_seg *bytecode;
461 /* List of labels defined in the function. */
462 struct bc_label *labels;
464 /* List of label references in the function. */
465 struct bc_labelref *labelrefs;
468 /* Add symbol to pointer table. Return offset into table where
469 pointer was stored. The offset usually goes into the bytecode
470 stream as a constP literal. */
473 bc_define_pointer (p)
474 char *p;
476 int offset = ptrconsts->size;
478 seg_refsym (ptrconsts, p, 0);
479 return offset;
483 /* Begin a bytecoded function. */
486 bc_begin_function (name)
487 char *name;
489 ptrconsts = seg_create ();
490 trampoline = seg_create ();
491 bytecode = seg_create ();
492 return seg_defsym (trampoline, name);
496 /* Force alignment in inline bytecode. */
498 void
499 bc_align_bytecode (align)
500 int align;
502 seg_align (bytecode, align);
506 /* Emit data inline into bytecode. */
508 void
509 bc_emit_bytecode_const (data, size)
510 char *data;
511 unsigned int size;
513 if (bytecode)
514 seg_data (bytecode, data, size);
518 /* Create a new "bytecode label", to have its value defined later.
519 Bytecode labels have nothing to do with the object file symbol table,
520 and are purely local to a given bytecoded function. */
522 struct bc_label *
523 bc_get_bytecode_label ()
525 struct bc_label *result;
527 result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
528 result->defined = 0;
529 result->next = labels;
530 result->uid = 0;
531 labels = result;
532 return result;
536 /* Define the given label with the current location counter. */
539 bc_emit_bytecode_labeldef (label)
540 struct bc_label *label;
542 extern int bc_new_uid ();
544 if (!label || label->defined)
545 return 0;
547 label->offset = bytecode->size;
548 label->defined = 1;
549 label->uid = bc_new_uid ();
551 #ifdef DEBUG_PRINT_CODE
552 fprintf (stderr, "$%lx:\n", label);
553 #endif
555 return 1;
559 /* Generate a location-relative reference to the given bytecode label.
560 It need not be defined yet; label references will be backpatched later. */
562 void
563 bc_emit_bytecode_labelref (label)
564 struct bc_label *label;
566 struct bc_labelref *labelref;
567 static int zero;
569 labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
570 labelref->label = label;
571 labelref->offset = bytecode->size;
572 labelref->next = labelrefs;
573 labelrefs = labelref;
575 #ifdef DEBUG_PRINT_CODE
576 fprintf (stderr, " $%lx", label);
577 #endif
579 seg_data (bytecode, (char *) &zero, sizeof zero);
583 /* Emit a reference to an external address; generate the reference in the
584 ptrconst area, and emit an offset in the bytecode. */
586 void
587 bc_emit_code_labelref (name, offset)
588 char *name;
589 int offset;
591 int ptroff;
593 ptroff = ptrconsts->size / sizeof (char *);
594 seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
595 seg_refsym (ptrconsts, name, offset);
597 #ifdef DEBUG_PRINT_CODE
598 fprintf (stderr, " [external <%x> %s]", ptroff, name);
599 #endif
603 /* Backpatch label references in the byte code, and concatenate the bytecode
604 and pointer constant segments to the cumulative text for the object file.
605 Return a label name for the pointer constants region. */
607 char *
608 bc_end_function ()
610 int addr;
611 struct bc_label *label, *next;
612 struct bc_labelref *ref, *nextref;
613 char ptrconsts_label[20];
614 static int nlab;
616 /* Backpatch bytecode label references. */
617 for (ref = labelrefs; ref; ref = ref->next)
618 if (ref->label->defined)
620 addr = ref->label->offset;
621 bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
624 /* Free the chains of labelrefs and labeldefs. */
625 for (ref = labelrefs; ref; ref = nextref)
627 nextref = ref->next;
628 free ((char *) ref);
631 for (label = labels; label; label = next)
633 next = label->next;
634 free ((char *) label);
637 seg_concat (trampoline, bytecode);
638 seg_align (trampoline, MACHINE_SEG_ALIGN);
639 sprintf (ptrconsts_label, "*LP%d", nlab++);
640 seg_defsym (trampoline, ptrconsts_label);
641 seg_concat (trampoline, ptrconsts);
642 seg_concat (bc_text_seg, trampoline);
644 labels = 0;
645 labelrefs = 0;
646 trampoline = 0;
647 bytecode = 0;
648 ptrconsts = 0;
650 return sym_lookup (ptrconsts_label)->name;
653 /* Force alignment in const data. */
655 void
656 bc_align_const (align)
657 int align;
659 seg_align (bc_text_seg, align);
662 /* Emit const data. */
664 void
665 bc_emit_const (data, size)
666 char *data;
667 unsigned int size;
669 seg_data (bc_text_seg, data, size);
672 /* Emit a zero-filled constant skip. */
674 void
675 bc_emit_const_skip (size)
676 unsigned int size;
678 seg_skip (bc_text_seg, size);
681 /* Emit a label definition in const data. */
684 bc_emit_const_labeldef (name)
685 char *name;
687 return seg_defsym (bc_text_seg, name);
690 /* Emit a label reference in const data. */
692 void
693 bc_emit_const_labelref (name, offset)
694 char *name;
695 int offset;
697 seg_refsym (bc_text_seg, name, offset);
700 /* Force alignment in data. */
702 void
703 bc_align_data (align)
704 int align;
706 seg_align (bc_data_seg, align);
709 /* Emit data. */
711 void
712 bc_emit_data (data, size)
713 char *data;
714 unsigned int size;
716 seg_data (bc_data_seg, data, size);
719 /* Emit a zero-filled data skip. */
721 void
722 bc_emit_data_skip (size)
723 unsigned int size;
725 seg_skip (bc_data_seg, size);
728 /* Emit label definition in data. */
731 bc_emit_data_labeldef (name)
732 char *name;
734 return seg_defsym (bc_data_seg, name);
737 /* Emit label reference in data. */
739 void
740 bc_emit_data_labelref (name, offset)
741 char *name;
742 int offset;
744 seg_refsym (bc_data_seg, name, offset);
747 /* Emit a common block of the given name and size. Note that
748 when the .o file is actually written non-global "common"
749 blocks will have to be turned into space in the data section. */
752 bc_emit_common (name, size)
753 char *name;
754 unsigned int size;
756 struct bc_sym *sym;
758 sym = sym_lookup (name);
759 if (sym->defined)
760 return 0;
762 sym->defined = 1;
763 sym->common = 1;
764 sym->val = size;
765 return 1;
768 /* Globalize the given label. */
770 void
771 bc_globalize_label (name)
772 char *name;
774 struct bc_sym *sym;
776 sym = sym_lookup (name);
777 sym->global = 1;
780 static enum { in_text, in_data } section = in_text;
782 void
783 bc_text ()
785 section = in_text;
788 void
789 bc_data ()
791 section = in_data;
794 void
795 bc_align (align)
796 int align;
798 if (section == in_text)
799 bc_align_const (align);
800 else
801 bc_align_data (align);
804 void
805 bc_emit (data, size)
806 char *data;
807 unsigned int size;
809 if (section == in_text)
810 bc_emit_const (data, size);
811 else
812 bc_emit_data (data, size);
815 void
816 bc_emit_skip (size)
817 unsigned int size;
819 if (section == in_text)
820 bc_emit_const_skip (size);
821 else
822 bc_emit_data_skip (size);
826 bc_emit_labeldef (name)
827 char *name;
829 if (section == in_text)
830 return bc_emit_const_labeldef (name);
831 else
832 return bc_emit_data_labeldef (name);
835 void
836 bc_emit_labelref (name, offset)
837 char *name;
838 int offset;
840 if (section == in_text)
841 bc_emit_const_labelref (name, offset);
842 else
843 bc_emit_data_labelref (name, offset);
846 void
847 bc_write_file (file)
848 FILE *file;
850 BC_WRITE_FILE (file);
854 /* Allocate a new bytecode rtx.
855 If you supply a null BC_LABEL, we generate one. */
858 bc_gen_rtx (label, offset, bc_label)
859 char *label;
860 int offset;
861 struct bc_label *bc_label;
863 rtx r;
865 if (bc_label == 0)
866 bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
868 r = gen_rtx_CODE_LABEL (VOIDmode, 0, 0, 0, (int) (HOST_WIDE_INT) bc_label,
869 label);
870 bc_label->offset = offset;
872 return r;
876 /* Print bytecode rtx */
878 void
879 bc_print_rtl (fp, r)
880 FILE *fp;
881 rtx r;
883 #if 0 /* This needs to get fixed to really work again. */
884 /* BC_WRITE_RTL has a definition
885 that doesn't even make sense for this use. */
886 BC_WRITE_RTL (r, fp);
887 #endif
891 /* Emit a bytecode, keeping a running tally of the stack depth. */
893 void
894 bc_emit_bytecode (bytecode)
895 enum bytecode_opcode bytecode;
897 char byte;
898 static int prev_lineno = -1;
900 byte = (char) bytecode;
902 #ifdef BCDEBUG_PRINT_CODE
903 if (lineno != prev_lineno)
905 fprintf (stderr, "<line %d>\n", lineno);
906 prev_lineno = lineno;
909 fputs (opcode_name[(unsigned int) bytecode], stderr);
910 #endif
912 /* Due to errors we are often requested to output bytecodes that
913 will cause an interpreter stack undeflow when executed. Instead of
914 dumping core on such occasions, we omit the bytecode. Erroneous code
915 should not be executed, regardless. This makes life much easier, since
916 we don't have to deceive ourselves about the known stack depth. */
918 bc_emit_bytecode_const (&byte, 1);
920 if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
922 if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
923 max_stack_depth = stack_depth;
926 #ifdef VALIDATE_STACK_FOR_BC
927 VALIDATE_STACK_FOR_BC ();
928 #endif
932 #ifdef BCDEBUG_PRINT_CODE
933 #define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR)
934 #else
935 #define PRLIT(X,Y)
936 #endif
938 /* Emit a complete bytecode instruction, expecting the correct number
939 of literal values in the call. First argument is the instruction, the
940 remaining arguments are literals of size HOST_WIDE_INT or smaller. */
942 void
943 bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
945 #ifndef ANSI_PROTOTYPES
946 enum bytecode_opcode opcode;
947 #endif
948 va_list arguments;
949 int nliteral, instruction;
951 VA_START (arguments, opcode);
953 #ifndef ANSI_PROTOTYPES
954 opcode = va_arg (arguments, enum bytecode_opcode);
955 #endif
957 /* Emit instruction bytecode */
958 bc_emit_bytecode (opcode);
959 instruction = (int) opcode;
961 /* Loop literals and emit as bytecode constants */
962 for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
964 switch (arityvec[instruction].literals[nliteral])
966 /* This conditional is a kludge, but it's necessary
967 because TYPE might be long long. */
968 #ifdef __GNUC__
969 /* Expand definitions into case statements */
970 #define DEFTYPECODE(CODE, NAME, MODE, TYPE) \
971 case CODE: \
973 TYPE temp = va_arg (arguments, TYPE); \
974 bc_emit_bytecode_const ((void *) &temp, sizeof temp); \
975 PRLIT (TYPE, &temp); } \
976 break;
978 #include "bc-typecd.def"
980 #undef DEFTYPECODE
981 #endif /* __GNUC__ */
983 default:
984 abort ();
988 va_end (arguments);
990 #ifdef BCDEBUG_PRINT_CODE
991 fputc ('\n', stderr);
992 #endif
995 /* Emit the machine-code interface trampoline at the beginning of a byte
996 coded function. The argument is a label name of the interpreter
997 bytecode callinfo structure; the return value is a label name for
998 the beginning of the actual bytecode. */
1000 char *
1001 bc_emit_trampoline (callinfo)
1002 char *callinfo;
1004 char mylab[20];
1005 static int n;
1007 sprintf (mylab, "*LB%d", n++);
1009 BC_EMIT_TRAMPOLINE (trampoline, callinfo);
1011 seg_defsym (bytecode, mylab);
1012 return sym_lookup (mylab)->name;