(*zeroextract[qs]i_compare0_scratch): Use const_int_operand
[official-gcc.git] / gcc / bc-emit.c
blob9a7c0f981b62e44a5199146a8226bf1565c0eed7
1 /* Output bytecodes for GNU C-compiler.
2 Copyright (C) 1993, 1994 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 ();
44 extern void free ();
46 extern struct obstack *rtl_obstack;
48 /* Indexed by mode class, gives the narrowest mode for each class. */
50 extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
52 /* Commonly used modes. */
53 /* Mode whose width is BITS_PER_UNIT */
54 extern enum machine_mode byte_mode;
56 /* Mode whose width is BITS_PER_WORD */
57 extern enum machine_mode word_mode;
59 /* Vector indexed by opcode giving info about the args for each opcode. */
60 static struct arityvec arityvec[] = {
61 #include "bc-arity.h"
64 /* 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. */
106 struct bc_sym *
107 sym_lookup (name)
108 char *name;
110 int i;
111 struct bc_sym *s;
113 i = hash (name);
114 for (s = hashtab[i]; s; s = s->next)
115 if (!strcmp (s->name, name))
116 return s;
118 s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
119 s->name = xmalloc (strlen (name) + 1);
120 strcpy (s->name, name);
121 s->defined = s->global = s->common = 0;
122 s->val = 0;
123 s->next = hashtab[i];
124 hashtab[i] = s;
125 return s;
129 /* Write out .globl and common symbols to the named file. */
130 static void
131 bc_sym_write (file)
132 FILE *file;
134 int i;
135 struct bc_sym *s;
137 for (i = 0; i < HASH_SIZE; ++i)
138 for (s = hashtab[i]; s; s = s->next)
140 if (s->global)
142 fprintf (file, "\n\t.globl ");
143 prsym (file, s->name);
144 putc ('\n', file);
145 if (s->common)
147 fprintf (file, "\n\t.comm ");
148 prsym (file, s->name);
149 fprintf (file, ", %lu\n", s->val);
152 else if (s->common)
154 fprintf (file, "\n\t.lcomm ");
155 prsym (file, s->name);
156 fprintf (file, ", %lu\n", s->val);
164 /* Create and initialize a new segment. */
165 static struct bc_seg *
166 seg_create ()
168 struct bc_seg *result;
170 result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
171 result->alloc = 256;
172 result->data = xmalloc (result->alloc);
173 result->size = 0;
174 result->syms = 0;
175 result->relocs = 0;
176 return result;
180 /* Advance the segment index to the next alignment boundary. */
181 static void
182 seg_align (seg, log)
183 struct bc_seg *seg;
184 int log;
186 unsigned int oldsize = seg->size;
188 seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
189 if (seg->size > seg->alloc)
191 while (seg->size > seg->alloc)
192 seg->alloc *= 2;
193 seg->data = xrealloc (seg->data, seg->alloc);
195 bzero (seg->data + oldsize, seg->size - oldsize);
199 /* Append the given data to the given segment. */
200 static void
201 seg_data (seg, data, size)
202 struct bc_seg *seg;
203 char *data;
204 unsigned int size;
206 if (seg->size + size > seg->alloc)
208 while (seg->size + size > seg->alloc)
209 seg->alloc *= 2;
210 seg->data = xrealloc (seg->data, seg->alloc);
213 bcopy (data, seg->data + seg->size, size);
214 seg->size += size;
218 /* 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. */
239 static int
240 seg_defsym (seg, name)
241 struct bc_seg *seg;
242 char *name;
244 struct bc_sym *sym;
245 struct bc_segsym *segsym;
247 sym = sym_lookup (name);
248 if (sym->defined)
249 return 0;
251 sym->defined = 1;
252 sym->val = seg->size;
253 segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
254 segsym->sym = sym;
255 segsym->next = seg->syms;
256 seg->syms = segsym;
257 return 1;
261 /* Generate in seg's data a reference to the given sym, adjusted by
262 the given offset. */
263 static void
264 seg_refsym (seg, name, offset)
265 struct bc_seg *seg;
266 char *name;
267 int offset;
269 struct bc_sym *sym;
270 struct bc_segreloc *segreloc;
272 sym = sym_lookup (name);
273 segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
274 segreloc->offset = seg->size;
275 segreloc->sym = sym;
276 segreloc->next = seg->relocs;
277 seg->relocs = segreloc;
278 seg_data (seg, (char *) &offset, sizeof offset);
282 /* Concatenate the contents of given segments into the first argument. */
283 static void
284 seg_concat (result, seg)
285 struct bc_seg *result, *seg;
287 unsigned int fix;
288 struct bc_segsym *segsym;
289 struct bc_segreloc *segreloc;
291 seg_align (result, MACHINE_SEG_ALIGN);
292 fix = result->size;
293 seg_data (result, seg->data, seg->size);
294 free (seg->data);
296 /* Go through the symbols and relocs of SEG, adjusting their offsets
297 for their new location in RESULT. */
298 if (seg->syms)
300 segsym = seg->syms;
302 segsym->sym->val += fix;
303 while (segsym->next && (segsym = segsym->next));
304 segsym->next = result->syms;
305 result->syms = seg->syms;
307 if (seg->relocs)
309 segreloc = seg->relocs;
311 segreloc->offset += fix;
312 while (segreloc->next && (segreloc = segreloc->next));
313 segreloc->next = result->relocs;
314 result->relocs = seg->relocs;
317 free ((char *) seg);
320 /* Write a segment to a file. */
321 static void
322 bc_seg_write (seg, file)
323 struct bc_seg *seg;
324 FILE *file;
326 struct bc_segsym *segsym, *nsegsym, *psegsym;
327 struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
328 int i, offset, flag;
330 /* Reverse the list of symbols. */
331 for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
333 nsegsym = segsym->next;
334 segsym->next = psegsym;
335 psegsym = segsym;
337 seg->syms = psegsym;
339 /* Reverse the list of relocs. */
340 for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
342 nsegreloc = segreloc->next;
343 segreloc->next = psegreloc;
344 psegreloc = segreloc;
346 seg->relocs = psegreloc;
348 /* Output each byte of the segment. */
349 for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
351 while (segsym && segsym->sym->val == i)
353 if (i % 8 != 0)
354 putc ('\n', file);
356 BC_WRITE_SEGSYM (segsym, file);
357 segsym = segsym->next;
358 flag = 1;
360 if (segreloc && segreloc->offset == i)
362 if (i % 8 != 0)
363 putc ('\n', file);
365 bcopy (seg->data + i, (char *) &offset, sizeof (int));
366 i += sizeof (int) - 1;
368 BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
369 segreloc = segreloc->next;
370 flag = 1;
372 else
374 if (i % 8 == 0 || flag)
375 BC_START_BYTECODE_LINE (file);
377 BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
378 seg->data[i] & 0xFF,
379 file);
380 flag = 0;
381 if (i % 8 == 7)
382 putc ('\n', file);
386 /* Paranoia check--we should have visited all syms and relocs during
387 the output pass. */
389 if (segsym || segreloc)
390 abort ();
395 /* Text and data segments of the object file in making. */
396 static struct bc_seg *bc_text_seg;
397 static struct bc_seg *bc_data_seg;
399 /* Called before anything else in this module. */
400 void
401 bc_initialize ()
403 int min_class_size[(int) MAX_MODE_CLASS];
404 enum machine_mode mode;
405 int i;
407 bc_init_mode_to_code_map ();
409 bc_text_seg = seg_create ();
410 bc_data_seg = seg_create ();
412 dconst0 = REAL_VALUE_ATOF ("0", DFmode);
413 dconst1 = REAL_VALUE_ATOF ("1", DFmode);
414 dconst2 = REAL_VALUE_ATOF ("2", DFmode);
415 dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
417 /* Find the narrowest mode for each class and compute the word and byte
418 modes. */
420 for (i = 0; i < (int) MAX_MODE_CLASS; i++)
421 min_class_size[i] = 1000;
423 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
424 mode = (enum machine_mode) ((int) mode + 1))
426 if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
428 class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
429 min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
431 if (GET_MODE_CLASS (mode) == MODE_INT
432 && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
433 byte_mode = mode;
435 if (GET_MODE_CLASS (mode) == MODE_INT
436 && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
437 word_mode = mode;
442 /* External addresses referenced in a function. Rather than trying to
443 work relocatable address directly into bytecoded functions (which would
444 require us to provide hairy location info and possibly obey alignment
445 rules imposed by the architecture) we build an auxiliary table of
446 pointer constants, and encode just offsets into this table into the
447 actual bytecode. */
448 static struct bc_seg *ptrconsts;
450 /* Trampoline code for the function entry. */
451 struct bc_seg *trampoline;
453 /* Actual byte code of the function. */
454 struct bc_seg *bytecode;
456 /* List of labels defined in the function. */
457 struct bc_label *labels;
459 /* List of label references in the function. */
460 struct bc_labelref *labelrefs;
463 /* Add symbol to pointer table. Return offset into table where
464 pointer was stored. The offset usually goes into the bytecode
465 stream as a constP literal. */
467 bc_define_pointer (p)
468 char *p;
470 int offset = ptrconsts->size;
472 seg_refsym (ptrconsts, p, 0);
473 return offset;
477 /* Begin a bytecoded function. */
479 bc_begin_function (name)
480 char *name;
482 ptrconsts = seg_create ();
483 trampoline = seg_create ();
484 bytecode = seg_create ();
485 return seg_defsym (trampoline, name);
489 /* Force alignment in inline bytecode. */
490 void
491 bc_align_bytecode (align)
492 int align;
494 seg_align (bytecode, align);
498 /* Emit data inline into bytecode. */
499 void
500 bc_emit_bytecode_const (data, size)
501 char *data;
502 unsigned int size;
504 if (bytecode)
505 seg_data (bytecode, data, size);
509 /* Create a new "bytecode label", to have its value defined later.
510 Bytecode labels have nothing to do with the object file symbol table,
511 and are purely local to a given bytecoded function. */
512 struct bc_label *
513 bc_get_bytecode_label ()
515 struct bc_label *result;
517 result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
518 result->defined = 0;
519 result->next = labels;
520 result->uid = 0;
521 labels = result;
522 return result;
526 /* Define the given label with the current location counter. */
528 bc_emit_bytecode_labeldef (label)
529 struct bc_label *label;
531 extern int bc_new_uid ();
533 if (!label || label->defined)
534 return 0;
536 label->offset = bytecode->size;
537 label->defined = 1;
538 label->uid = bc_new_uid ();
540 #ifdef DEBUG_PRINT_CODE
541 fprintf (stderr, "$%lx:\n", label);
542 #endif
544 return 1;
548 /* Generate a location-relative reference to the given bytecode label.
549 It need not be defined yet; label references will be backpatched later. */
550 void
551 bc_emit_bytecode_labelref (label)
552 struct bc_label *label;
554 struct bc_labelref *labelref;
555 static int zero;
557 labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
558 labelref->label = label;
559 labelref->offset = bytecode->size;
560 labelref->next = labelrefs;
561 labelrefs = labelref;
563 #ifdef DEBUG_PRINT_CODE
564 fprintf (stderr, " $%lx", label);
565 #endif
567 seg_data (bytecode, (char *) &zero, sizeof zero);
571 /* Emit a reference to an external address; generate the reference in the
572 ptrconst area, and emit an offset in the bytecode. */
573 void
574 bc_emit_code_labelref (name, offset)
575 char *name;
576 int offset;
578 int ptroff;
580 ptroff = ptrconsts->size / sizeof (char *);
581 seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
582 seg_refsym (ptrconsts, name, offset);
584 #ifdef DEBUG_PRINT_CODE
585 fprintf (stderr, " [external <%x> %s]", ptroff, name);
586 #endif
590 /* Backpatch label references in the byte code, and concatenate the bytecode
591 and pointer constant segments to the cumulative text for the object file.
592 Return a label name for the pointer constants region. */
593 char *
594 bc_end_function ()
596 int addr;
597 struct bc_label *label, *next;
598 struct bc_labelref *ref, *nextref;
599 char ptrconsts_label[20];
600 static int nlab;
602 /* Backpatch bytecode label references. */
603 for (ref = labelrefs; ref; ref = ref->next)
604 if (ref->label->defined)
606 addr = ref->label->offset;
607 bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
610 /* Free the chains of labelrefs and labeldefs. */
611 for (ref = labelrefs; ref; ref = nextref)
613 nextref = ref->next;
614 free ((char *) ref);
617 for (label = labels; label; label = next)
619 next = label->next;
620 free ((char *) label);
623 seg_concat (trampoline, bytecode);
624 seg_align (trampoline, MACHINE_SEG_ALIGN);
625 sprintf (ptrconsts_label, "*LP%d", nlab++);
626 seg_defsym (trampoline, ptrconsts_label);
627 seg_concat (trampoline, ptrconsts);
628 seg_concat (bc_text_seg, trampoline);
630 labels = 0;
631 labelrefs = 0;
632 trampoline = 0;
633 bytecode = 0;
634 ptrconsts = 0;
636 return sym_lookup (ptrconsts_label)->name;
639 /* Force alignment in const data. */
640 void
641 bc_align_const (align)
642 int align;
644 seg_align (bc_text_seg, align);
647 /* Emit const data. */
648 void
649 bc_emit_const (data, size)
650 char *data;
651 unsigned int size;
653 seg_data (bc_text_seg, data, size);
656 /* Emit a zero-filled constant skip. */
657 void
658 bc_emit_const_skip (size)
659 unsigned int size;
661 seg_skip (bc_text_seg, size);
664 /* Emit a label definition in const data. */
666 bc_emit_const_labeldef (name)
667 char *name;
669 return seg_defsym (bc_text_seg, name);
672 /* Emit a label reference in const data. */
673 void
674 bc_emit_const_labelref (name, offset)
675 char *name;
676 int offset;
678 seg_refsym (bc_text_seg, name, offset);
681 /* Force alignment in data. */
682 void
683 bc_align_data (align)
684 int align;
686 seg_align (bc_data_seg, align);
689 /* Emit data. */
690 void
691 bc_emit_data (data, size)
692 char *data;
693 unsigned int size;
695 seg_data (bc_data_seg, data, size);
698 /* Emit a zero-filled data skip. */
699 void
700 bc_emit_data_skip (size)
701 unsigned int size;
703 seg_skip (bc_data_seg, size);
706 /* Emit label definition in data. */
708 bc_emit_data_labeldef (name)
709 char *name;
711 return seg_defsym (bc_data_seg, name);
714 /* Emit label reference in data. */
715 void
716 bc_emit_data_labelref (name, offset)
717 char *name;
718 int offset;
720 seg_refsym (bc_data_seg, name, offset);
723 /* Emit a common block of the given name and size. Note that
724 when the .o file is actually written non-global "common"
725 blocks will have to be turned into space in the data section. */
727 bc_emit_common (name, size)
728 char *name;
729 unsigned int size;
731 struct bc_sym *sym;
733 sym = sym_lookup (name);
734 if (sym->defined)
735 return 0;
737 sym->defined = 1;
738 sym->common = 1;
739 sym->val = size;
740 return 1;
743 /* Globalize the given label. */
744 void
745 bc_globalize_label (name)
746 char *name;
748 struct bc_sym *sym;
750 sym = sym_lookup (name);
751 sym->global = 1;
754 static enum { in_text, in_data } section = in_text;
756 void
757 bc_text ()
759 section = in_text;
762 void
763 bc_data ()
765 section = in_data;
768 void
769 bc_align (align)
770 int align;
772 if (section == in_text)
773 bc_align_const (align);
774 else
775 bc_align_data (align);
778 void
779 bc_emit (data, size)
780 char *data;
781 unsigned int size;
783 if (section == in_text)
784 bc_emit_const (data, size);
785 else
786 bc_emit_data (data, size);
789 void
790 bc_emit_skip (size)
791 unsigned int size;
793 if (section == in_text)
794 bc_emit_const_skip (size);
795 else
796 bc_emit_data_skip (size);
800 bc_emit_labeldef (name)
801 char *name;
803 if (section == in_text)
804 return bc_emit_const_labeldef (name);
805 else
806 return bc_emit_data_labeldef (name);
809 void
810 bc_emit_labelref (name, offset)
811 char *name;
812 int offset;
814 if (section == in_text)
815 bc_emit_const_labelref (name, offset);
816 else
817 bc_emit_data_labelref (name, offset);
820 void
821 bc_write_file (file)
822 FILE *file;
824 BC_WRITE_FILE (file);
828 /* Allocate a new bytecode rtx.
829 If you supply a null BC_LABEL, we generate one. */
832 bc_gen_rtx (label, offset, bc_label)
833 char *label;
834 int offset;
835 struct bc_label *bc_label;
837 rtx r;
839 if (bc_label == 0)
840 bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
842 r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
843 bc_label->offset = offset;
845 return r;
849 /* Print bytecode rtx */
850 void
851 bc_print_rtl (fp, r)
852 FILE *fp;
853 rtx r;
855 #if 0 /* This needs to get fixed to really work again. */
856 /* BC_WRITE_RTL has a definition
857 that doesn't even make sense for this use. */
858 BC_WRITE_RTL (r, fp);
859 #endif
863 /* Emit a bytecode, keeping a running tally of the stack depth. */
864 void
865 bc_emit_bytecode (bytecode)
866 enum bytecode_opcode bytecode;
868 char byte;
869 static int prev_lineno = -1;
871 byte = (char) bytecode;
873 #ifdef BCDEBUG_PRINT_CODE
874 if (lineno != prev_lineno)
876 fprintf (stderr, "<line %d>\n", lineno);
877 prev_lineno = lineno;
880 fputs (opcode_name[(unsigned int) bytecode], stderr);
881 #endif
883 /* Due to errors we are often requested to output bytecodes that
884 will cause an interpreter stack undeflow when executed. Instead of
885 dumping core on such occasions, we omit the bytecode. Erroneous code
886 should not be executed, regardless. This makes life much easier, since
887 we don't have to deceive ourselves about the known stack depth. */
889 bc_emit_bytecode_const (&byte, 1);
891 if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
893 if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
894 max_stack_depth = stack_depth;
897 #ifdef VALIDATE_STACK_FOR_BC
898 VALIDATE_STACK_FOR_BC ();
899 #endif
903 #ifdef BCDEBUG_PRINT_CODE
904 #define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR)
905 #else
906 #define PRLIT(X,Y)
907 #endif
909 /* Emit a complete bytecode instruction, expecting the correct number
910 of literal values in the call. First argument is the instruction, the
911 remaining arguments are literals of size HOST_WIDE_INT or smaller. */
912 void
913 bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
915 #ifndef __STDC__
916 enum bytecode_opcode opcode;
917 #endif
918 va_list arguments;
919 int nliteral, instruction;
921 VA_START (arguments, opcode);
923 #ifndef __STDC__
924 opcode = va_arg (arguments, enum bytecode_opcode);
925 #endif
927 /* Emit instruction bytecode */
928 bc_emit_bytecode (opcode);
929 instruction = (int) opcode;
931 /* Loop literals and emit as bytecode constants */
932 for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
934 switch (arityvec[instruction].literals[nliteral])
936 /* This conditional is a kludge, but it's necessary
937 because TYPE might be long long. */
938 #ifdef __GNUC__
939 /* Expand definitions into case statements */
940 #define DEFTYPECODE(CODE, NAME, MODE, TYPE) \
941 case CODE: \
943 TYPE temp = va_arg (arguments, TYPE); \
944 bc_emit_bytecode_const ((void *) &temp, sizeof temp); \
945 PRLIT (TYPE, &temp); } \
946 break;
948 #include "bc-typecd.def"
950 #undef DEFTYPECODE
951 #endif /* __GNUC__ */
953 default:
954 abort ();
958 #ifdef BCDEBUG_PRINT_CODE
959 fputc ('\n', stderr);
960 #endif
963 /* Emit the machine-code interface trampoline at the beginning of a byte
964 coded function. The argument is a label name of the interpreter
965 bytecode callinfo structure; the return value is a label name for
966 the beginning of the actual bytecode. */
967 char *
968 bc_emit_trampoline (callinfo)
969 char *callinfo;
971 char mylab[20];
972 static int n;
974 sprintf (mylab, "*LB%d", n++);
976 BC_EMIT_TRAMPOLINE (trampoline, callinfo);
978 seg_defsym (bytecode, mylab);
979 return sym_lookup (mylab)->name;
983 /* Simple strdup */
984 char *
985 bc_xstrdup (str)
986 char *str;
988 char *tmp = xmalloc (strlen (str) + 1);
990 strcpy (tmp, str);
991 return tmp;