OSDN Git Service

make sym_lookup global instead of static.
[pf3gnuchains/gcc-fork.git] / gcc / bc-emit.c
1 /* Output bytecodes for GNU C-compiler.
2    Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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.
10
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.
15
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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 #include <stdio.h>
22 #include <varargs.h>
23 #include <string.h>
24 #include "config.h"
25 #include "machmode.h"
26 #include "rtl.h"
27 #include "real.h"
28 #include "obstack.h"
29 #include "bytecode.h"
30 #include "bc-emit.h"
31 #include "bc-opcode.h"
32 #include "bc-typecd.h"
33 #include "bi-run.h"
34
35 extern char *xmalloc(), *xrealloc();
36 extern void free();
37
38 extern struct obstack *rtl_obstack;
39
40 REAL_VALUE_TYPE dconst0;
41 REAL_VALUE_TYPE dconst1;
42 REAL_VALUE_TYPE dconst2;
43 REAL_VALUE_TYPE dconstm1;
44
45
46 /* Indexed by mode class, gives the narrowest mode for each class.  */
47
48 enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
49
50 /* Commonly used modes.  */
51 /* Mode whose width is BITS_PER_UNIT */
52 enum machine_mode byte_mode;
53
54 /* Mode whose width is BITS_PER_WORD */
55 enum machine_mode word_mode;
56
57 /* Vector indexed by opcode giving info about the args for each opcode. */
58 static struct arityvec arityvec[] = {
59 #include "bc-arity.h"
60 };
61
62 /* How to print a symbol name for the assembler.  */
63 static void
64 prsym (file, s)
65      FILE *file;
66      char *s;
67 {
68   if (*s == '*')
69     fprintf (file, "%s", s + 1);
70   else
71
72 #ifdef NAMES_HAVE_UNDERSCORES
73     fprintf (file, "_%s", s);
74 #else
75     fprintf (file, "%s", s);
76 #endif
77
78 }
79
80 /* Maintain a bucket hash table for symbol names. */
81
82 #define HASH_BITS 32
83 #define HASH_SIZE 509
84
85 static struct bc_sym *hashtab[HASH_SIZE];
86
87 static unsigned int
88 hash (name)
89      char *name;
90 {
91   unsigned int hash = 0;
92
93   while (*name)
94     {
95       hash = hash << 3 | hash >> HASH_BITS - 3;
96       hash += *name++;
97     }
98
99   return hash % HASH_SIZE;
100 }
101
102
103 /* Look up the named symbol, creating it if it doesn't exist. */
104 struct bc_sym *
105 sym_lookup (name)
106      char *name;
107 {
108   int i;
109   struct bc_sym *s;
110
111   i = hash(name);
112   for (s = hashtab[i]; s; s = s->next)
113     if (!strcmp (s->name, name))
114       return s;
115
116   s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
117   s->name = xmalloc (strlen (name) + 1);
118   strcpy (s->name, name);
119   s->defined = s->global = s->common = 0;
120   s->val = 0;
121   s->next = hashtab[i];
122   hashtab[i] = s;
123   return s;
124 }
125
126
127 /* Write out .globl and common symbols to the named file.  */
128 static void
129 bc_sym_write (file)
130      FILE *file;
131 {
132   int i;
133   struct bc_sym *s;
134
135   for (i = 0; i < HASH_SIZE; ++i)
136     for (s = hashtab[i]; s; s = s->next)
137       {
138         if (s->global)
139           {
140             fprintf (file, "\n\t.globl ");
141             prsym (file, s->name);
142             putc ('\n', file);
143             if (s->common)
144               {
145                 fprintf (file, "\n\t.comm ");
146                 prsym (file, s->name);
147                 fprintf (file, ", %d\n", s->val);
148               }
149           }
150         else if (s->common)
151           {
152             fprintf (file, "\n\t.lcomm ");
153             prsym (file, s->name);
154             fprintf (file, ", %d\n", s->val);
155           }
156       }
157 }
158
159 \f
160
161
162 /* Create and initialize a new segment. */
163 static struct bc_seg *
164 seg_create ()
165 {
166   struct bc_seg *result;
167
168   result = (struct bc_seg *) xmalloc(sizeof (struct bc_seg));
169   result->alloc = 256;
170   result->data = xmalloc(result->alloc);
171   result->size = 0;
172   result->syms = 0;
173   result->relocs = 0;
174   return result;
175 }
176
177
178 /* 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;
183 {
184   unsigned int oldsize = seg->size;
185
186   seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
187   if (seg->size > seg->alloc)
188     {
189       while (seg->size > seg->alloc)
190         seg->alloc *= 2;
191       seg->data = xrealloc(seg->data, seg->alloc);
192     }
193   memset(seg->data + oldsize, 0, seg->size - oldsize);
194 }
195
196
197 /* Append the given data to the given segment. */
198 static void
199 seg_data (seg, data, size)
200      struct bc_seg *seg;
201      char *data;
202      unsigned int size;
203 {
204   if (seg->size + size > seg->alloc)
205     {
206       while (seg->size + size > seg->alloc)
207         seg->alloc *= 2;
208       seg->data = xrealloc (seg->data, seg->alloc);
209     }
210
211   memcpy (seg->data + seg->size, data, size);
212   seg->size += size;
213 }
214
215
216 /* Append a zero-filled skip to the given segment.  */
217 static void
218 seg_skip (seg, size)
219      struct bc_seg *seg;
220      unsigned int size;
221 {
222   if (seg->size + size > seg->alloc)
223     {
224       while (seg->size + size > seg->alloc)
225         seg->alloc *= 2;
226       seg->data = xrealloc (seg->data, seg->alloc);
227     }
228
229   memset (seg->data + seg->size, 0, size);
230   seg->size += size;
231 }
232
233
234 /* Define the given name as the current offset in the given segment.  It
235    is an error if the name is already defined.  Return 0 or 1 indicating
236    failure or success respectively. */
237 static int
238 seg_defsym (seg, name)
239      struct bc_seg *seg;
240      char *name;
241 {
242   struct bc_sym *sym;
243   struct bc_segsym *segsym;
244
245   sym = sym_lookup(name);
246   if (sym->defined)
247     return 0;
248
249   sym->defined = 1;
250   sym->val = seg->size;
251   segsym = (struct bc_segsym *) xmalloc(sizeof (struct bc_segsym));
252   segsym->sym = sym;
253   segsym->next = seg->syms;
254   seg->syms = segsym;
255   return 1;
256 }
257
258
259 /* Generate in seg's data a reference to the given sym, adjusted by
260    the given offset. */
261 static void
262 seg_refsym (seg, name, offset)
263      struct bc_seg *seg;
264      char *name;
265      int offset;
266 {
267   struct bc_sym *sym;
268   struct bc_segreloc *segreloc;
269
270   sym = sym_lookup(name);
271   segreloc = (struct bc_segreloc *) xmalloc(sizeof (struct bc_segreloc));
272   segreloc->offset = seg->size;
273   segreloc->sym = sym;
274   segreloc->next = seg->relocs;
275   seg->relocs = segreloc;
276   seg_data(seg, (char *) &offset, sizeof offset);
277 }
278
279
280 /* Concatenate the contents of given segments into the first argument. */
281 static void
282 seg_concat (result, seg)
283      struct bc_seg *result, *seg;
284 {
285   unsigned int fix;
286   struct bc_segsym *segsym;
287   struct bc_segreloc *segreloc;
288
289   seg_align(result, MACHINE_SEG_ALIGN);
290   fix = result->size;
291   seg_data(result, seg->data, seg->size);
292   free(seg->data);
293
294   /* Go through the symbols and relocs of SEG, adjusting their offsets
295      for their new location in RESULT. */
296   if (seg->syms)
297     {
298       segsym = seg->syms;
299       do
300         segsym->sym->val += fix;
301       while (segsym->next && (segsym = segsym->next));
302       segsym->next = result->syms;
303       result->syms = seg->syms;
304     }
305   if (seg->relocs)
306     {
307       segreloc = seg->relocs;
308       do
309         segreloc->offset += fix;
310       while (segreloc->next && (segreloc = segreloc->next));
311       segreloc->next = result->relocs;
312       result->relocs = seg->relocs;
313     }
314
315   free((char *) seg);
316 }
317
318 /* Write a segment to a file.  */
319 static void
320 bc_seg_write (seg, file)
321      struct bc_seg *seg;
322      FILE *file;
323 {
324   struct bc_segsym *segsym, *nsegsym, *psegsym;
325   struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
326   int i, offset, flag;
327
328   /* Reverse the list of symbols.  */
329   for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
330     {
331       nsegsym = segsym->next;
332       segsym->next = psegsym;
333       psegsym = segsym;
334     }
335   seg->syms = psegsym;
336
337   /* Reverse the list of relocs.  */
338   for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
339     {
340       nsegreloc = segreloc->next;
341       segreloc->next = psegreloc;
342       psegreloc = segreloc;
343     }
344   seg->relocs = psegreloc;
345
346   /* Output each byte of the segment.  */
347   for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
348     {
349       while (segsym && segsym->sym->val == i)
350         {
351           if (i % 8 != 0)
352             putc('\n', file);
353
354           BC_WRITE_SEGSYM (segsym, file);
355           segsym = segsym->next;
356           flag = 1;
357         }
358       if (segreloc && segreloc->offset == i)
359         {
360           if (i % 8 != 0)
361             putc ('\n', file);
362
363           offset = *(int *) (seg->data + i);
364           i += sizeof (int) - 1;
365
366           BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
367           segreloc = segreloc->next;
368           flag = 1;
369         }
370       else
371         {
372           if (i % 8 == 0 || flag)
373             BC_START_BYTECODE_LINE (file);
374
375           BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
376                              seg->data[i] & 0xFF,
377                              file);
378           flag = 0;
379           if (i % 8 == 7)
380             putc ('\n', file);
381         }
382     }
383
384   /* Paranoia check--we should have visited all syms and relocs during
385      the output pass.  */
386
387   if (segsym || segreloc)
388     abort ();
389 }
390
391 \f
392
393 /* Text and data segments of the object file in making. */
394 static struct bc_seg *bc_text_seg;
395 static struct bc_seg *bc_data_seg;
396
397 /* Called before anything else in this module. */
398 void
399 bc_initialize ()
400 {
401   int min_class_size[(int) MAX_MODE_CLASS];
402   enum machine_mode mode;
403   int i;
404
405   bc_init_mode_to_code_map ();
406
407   bc_text_seg = seg_create ();
408   bc_data_seg = seg_create ();
409
410   dconst0 = REAL_VALUE_ATOF ("0");
411   dconst1 = REAL_VALUE_ATOF ("1");
412   dconst2 = REAL_VALUE_ATOF ("2");
413   dconstm1 = REAL_VALUE_ATOF ("-1");
414
415   /* Find the narrowest mode for each class and compute the word and byte
416      modes.  */
417
418   for (i = 0; i < (int) MAX_MODE_CLASS; i++)
419     min_class_size[i] = 1000;
420
421   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
422        mode = (enum machine_mode) ((int) mode + 1))
423     {
424       if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
425         {
426           class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
427           min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
428         }
429       if (GET_MODE_CLASS (mode) == MODE_INT
430           && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
431         byte_mode = mode;
432
433       if (GET_MODE_CLASS (mode) == MODE_INT
434           && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
435         word_mode = mode;
436     }
437 }
438
439
440 /* External addresses referenced in a function.  Rather than trying to
441    work relocatable address directly into bytecoded functions (which would
442    require us to provide hairy location info and possibly obey alignment
443    rules imposed by the architecture) we build an auxilary table of
444    pointer constants, and encode just offsets into this table into the
445    actual bytecode. */
446 static struct bc_seg *ptrconsts;
447
448 /* Trampoline code for the function entry.  */
449 struct bc_seg *trampoline;
450
451 /* Actual byte code of the function. */
452 struct bc_seg *bytecode;
453
454 /* List of labels defined in the function. */
455 struct bc_label *labels;
456
457 /* List of label references in the function. */
458 struct bc_labelref *labelrefs;
459
460
461 /* Add symbol to pointer table.  Return offset into table where
462    pointer was stored.  The offset usually goes into the bytecode
463    stream as a constP literal. */
464 int
465 bc_define_pointer (p)
466      char *p;
467 {
468   int offset = ptrconsts->size;
469
470   seg_refsym (ptrconsts, p, 0);
471   return offset;
472 }
473
474
475 /* Begin a bytecoded function.  */
476 int
477 bc_begin_function (name)
478     char *name;
479 {
480   ptrconsts = seg_create ();
481   trampoline = seg_create ();
482   bytecode = seg_create ();
483   return seg_defsym (trampoline, name);
484 }
485
486
487 /* Force alignment in inline bytecode.  */
488 void
489 bc_align_bytecode (align)
490     int align;
491 {
492   seg_align (bytecode, align);
493 }
494
495
496 /* Emit data inline into bytecode.  */
497 void
498 bc_emit_bytecode_const (data, size)
499      char *data;
500      unsigned int size;
501 {
502   if (bytecode)
503     seg_data (bytecode, data, size);
504 }
505
506
507 /* Create a new "bytecode label", to have its value defined later.
508    Bytecode labels have nothing to do with the object file symbol table,
509    and are purely local to a given bytecoded function. */
510 struct bc_label *
511 bc_get_bytecode_label ()
512 {
513   struct bc_label *result;
514
515   result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
516   result->defined = 0;
517   result->next = labels;
518   result->uid = 0;
519   labels = result;
520   return result;
521 }
522
523
524 /* Define the given label with the current location counter. */
525 int
526 bc_emit_bytecode_labeldef (label)
527      struct bc_label *label;
528 {
529   extern int bc_new_uid ();
530
531   if (!label || label->defined)
532     return 0;
533
534   label->offset = bytecode->size;
535   label->defined = 1;
536   label->uid = bc_new_uid ();
537
538 #ifdef DEBUG_PRINT_CODE
539   fprintf (stderr, "$%lx:\n", label);
540 #endif
541
542   return 1;
543 }
544
545
546 /* Generate a location-relative reference to the given bytecode label.
547    It need not be defined yet; label references will be backpatched later. */
548 void
549 bc_emit_bytecode_labelref (label)
550      struct bc_label *label;
551 {
552   struct bc_labelref *labelref;
553   static int zero;
554
555   labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
556   labelref->label = label;
557   labelref->offset = bytecode->size;
558   labelref->next = labelrefs;
559   labelrefs = labelref;
560
561 #ifdef DEBUG_PRINT_CODE
562   fprintf (stderr, " $%lx", label);
563 #endif
564
565   seg_data (bytecode, (char *) &zero, sizeof zero);
566 }
567
568
569 /* Emit a reference to an external address; generate the reference in the
570    ptrconst area, and emit an offset in the bytecode. */
571 void
572 bc_emit_code_labelref (name, offset)
573      char *name;
574      int offset;
575 {
576   int ptroff;
577
578   ptroff = ptrconsts->size / sizeof (char *);
579   seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
580   seg_refsym (ptrconsts, name, offset);
581
582 #ifdef DEBUG_PRINT_CODE
583   fprintf (stderr, " [external <%x> %s]", ptroff, name);
584 #endif
585 }
586
587
588 /* Backpatch label references in the byte code, and concatenate the bytecode
589    and pointer constant segments to the cumulative text for the object file.
590    Return a label name for the pointer constants region.  */
591 char *
592 bc_end_function ()
593 {
594   int addr;
595   struct bc_label *label, *next;
596   struct bc_labelref *ref, *nextref;
597   char ptrconsts_label[20];
598   static int nlab;
599
600   /* Backpatch bytecode label references. */
601   for (ref = labelrefs; ref; ref = ref->next)
602     if (ref->label->defined)
603       {
604         addr = ref->label->offset;
605         memcpy (bytecode->data + ref->offset, /* incest */
606                 (char *) &addr, sizeof addr);
607       }
608
609   /* Free the chains of labelrefs and labeldefs. */
610   for (ref = labelrefs; ref; ref = nextref)
611     {
612       nextref = ref->next;
613       free ((char *) ref);
614     }
615
616   for (label = labels; label; label = next)
617     {
618       next = label->next;
619       free ((char *) label);
620     }
621
622   seg_concat (trampoline, bytecode);
623   seg_align (trampoline, MACHINE_SEG_ALIGN);
624   sprintf (ptrconsts_label, "*LP%d", nlab++);
625   seg_defsym (trampoline, ptrconsts_label);
626   seg_concat (trampoline, ptrconsts);
627   seg_concat (bc_text_seg, trampoline);
628
629   labels = 0;
630   labelrefs = 0;
631   trampoline = 0;
632   bytecode = 0;
633   ptrconsts = 0;
634
635   return sym_lookup (ptrconsts_label)->name;
636 }
637
638 /* Force alignment in const data. */
639 void
640 bc_align_const (align)
641      int align;
642 {
643   seg_align (bc_text_seg, align);
644 }
645
646 /* Emit const data. */
647 void
648 bc_emit_const (data, size)
649      char *data;
650      unsigned int size;
651 {
652   seg_data (bc_text_seg, data, size);
653 }
654
655 /* Emit a zero-filled constant skip. */
656 void
657 bc_emit_const_skip (size)
658      unsigned int size;
659 {
660   seg_skip (bc_text_seg, size);
661 }
662
663 /* Emit a label definition in const data. */
664 int
665 bc_emit_const_labeldef (name)
666      char *name;
667 {
668   return seg_defsym (bc_text_seg, name);
669 }
670
671 /* Emit a label reference in const data. */
672 void
673 bc_emit_const_labelref (name, offset)
674      char *name;
675      int offset;
676 {
677   seg_refsym (bc_text_seg, name, offset);
678 }
679
680 /* Force alignment in data. */
681 void
682 bc_align_data (align)
683      int align;
684 {
685   seg_align (bc_data_seg, align);
686 }
687
688 /* Emit data. */
689 void
690 bc_emit_data(data, size)
691      char *data;
692      unsigned int size;
693 {
694   seg_data (bc_data_seg, data, size);
695 }
696
697 /* Emit a zero-filled data skip.  */
698 void
699 bc_emit_data_skip (size)
700      unsigned int size;
701 {
702   seg_skip(bc_data_seg, size);
703 }
704
705 /* Emit label definition in data. */
706 int
707 bc_emit_data_labeldef(name)
708      char *name;
709 {
710   return seg_defsym(bc_data_seg, name);
711 }
712
713 /* Emit label reference in data. */
714 void
715 bc_emit_data_labelref(name, offset)
716      char *name;
717      int offset;
718 {
719   seg_refsym(bc_data_seg, name, offset);
720 }
721
722 /* Emit a common block of the given name and size.  Note that
723    when the .o file is actually written non-global "common"
724    blocks will have to be turned into space in the data section.  */
725 int
726 bc_emit_common(name, size)
727      char *name;
728      unsigned int size;
729 {
730   struct bc_sym *sym;
731
732   sym = sym_lookup(name);
733   if (sym->defined)
734     return 0;
735
736   sym->defined = 1;
737   sym->common = 1;
738   sym->val = size;
739   return 1;
740 }
741
742 /* Globalize the given label. */
743 void
744 bc_globalize_label(name)
745      char *name;
746 {
747   struct bc_sym *sym;
748
749   sym = sym_lookup(name);
750   sym->global = 1;
751 }
752
753 static enum { in_text, in_data } section = in_text;
754
755 void
756 bc_text ()
757 {
758   section = in_text;
759 }
760
761 void
762 bc_data ()
763 {
764   section = in_data;
765 }
766
767 void
768 bc_align (align)
769      int align;
770 {
771   if (section == in_text)
772     bc_align_const (align);
773   else
774     bc_align_data (align);
775 }
776
777 void
778 bc_emit (data, size)
779      char *data;
780      unsigned int size;
781 {
782   if (section == in_text)
783     bc_emit_const (data, size);
784   else
785     bc_emit_data (data, size);
786 }
787
788 void
789 bc_emit_skip (size)
790      unsigned int size;
791 {
792   if (section == in_text)
793     bc_emit_const_skip (size);
794   else
795     bc_emit_data_skip (size);
796 }
797
798 int
799 bc_emit_labeldef (name)
800      char *name;
801 {
802   if (section == in_text)
803     return bc_emit_const_labeldef (name);
804   else
805     return bc_emit_data_labeldef (name);
806 }
807
808 void
809 bc_emit_labelref (name, offset)
810      char *name;
811      int offset;
812 {
813   if (section == in_text)
814     bc_emit_const_labelref (name, offset);
815   else
816     bc_emit_data_labelref (name, offset);
817 }
818
819 void
820 bc_write_file (file)
821      FILE *file;
822 {
823   BC_WRITE_FILE (file);
824 }
825
826
827 /* Allocate a new bytecode rtx. */
828 rtx
829 bc_gen_rtx (label, offset, bc_label)
830      char *label;
831      int offset;
832      struct bc_label *bc_label;
833 {
834   rtx r;
835
836   r = (rtx) obstack_alloc (rtl_obstack, sizeof (struct rtx_def));
837   r->label = label;             /* FIXME: Do we need to copy here?  */
838   r->offset = offset;
839   r->bc_label = bc_label;
840   return r;
841 }
842
843
844 /* Print bytecode rtx */
845 void
846 bc_print_rtl (fp, r)
847      FILE *fp;
848      rtx r;
849 {
850   BC_WRITE_RTL (r, fp);
851 }
852
853
854 /* Emit a bytecode, keeping a running tally of the stack depth.  */
855 void
856 bc_emit_bytecode (bytecode)
857      enum bytecode_opcode bytecode;
858 {
859   char byte;
860   int npushes = arityvec[bytecode].noutputs - arityvec[bytecode].ninputs;
861   static int prev_lineno = -1;
862
863   byte = bytecode;
864
865 #ifdef BCDEBUG_PRINT_CODE
866   if (lineno != prev_lineno)
867     {
868       fprintf (stderr, "<line %d>\n", lineno);
869       prev_lineno = lineno;
870     }
871
872   fputs (opcode_name[(unsigned int) bytecode], stderr);
873 #endif
874
875   /* Due to errors we are often requested to output bytecodes that
876      will cause an interpreter stack undeflow when executed.  Instead of
877      dumping core on such occasions, we omit the bytecode.  Erroneous code
878      should not be executed, regardless.  This makes life much easier, since
879      we don't have to deceive ourselves about the known stack depth. */
880
881   bc_emit_bytecode_const (&byte, 1);
882
883   if ((stack_depth -= arityvec[bytecode].ninputs) >= 0)
884     {
885       if ((stack_depth += arityvec[bytecode].noutputs) > max_stack_depth)
886         max_stack_depth = stack_depth;
887     }
888
889 #ifdef VALIDATE_STACK
890   VALIDATE_STACK ();
891 #endif
892 }
893
894
895 #ifdef BCDEBUG_PRINT_CODE
896 #define PRLIT(TYPE, PTR)  fprintf (stderr, " [%x]", *(TYPE *) PTR)
897 #else
898 #define PRLIT(X,Y)
899 #endif
900
901 /* Emit a complete bytecode instruction, expecting the correct number
902    of literal values in the call.  First argument is the instruction, the
903    remaining arguments are literals of size HOST_WIDE_INT or smaller. */
904 void
905 bc_emit_instruction (va_alist)
906      va_dcl
907 {
908   va_list arguments;
909   enum bytecode_opcode opcode;
910   int nliteral, instruction;
911
912
913   va_start (arguments);
914
915   /* Emit instruction bytecode */
916   opcode = va_arg (arguments, enum bytecode_opcode);
917   bc_emit_bytecode (opcode);
918   instruction = (int) opcode;
919
920   /* Loop literals and emit as bytecode constants */
921   for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
922     {
923       HOST_WIDE_INT literal;
924
925       switch (arityvec[instruction].literals[nliteral])
926         {
927           /* Expand definitions into case statements */
928 #define DEFTYPECODE(CODE, NAME, MODE, TYPE)                             \
929         case CODE:                                                      \
930           { TYPE temp = va_arg (arguments, TYPE);                       \
931             bc_emit_bytecode_const ((void *) &temp, sizeof temp);       \
932             PRLIT (TYPE, &temp); }                                      \
933           break;
934
935 #include "bc-typecd.def"
936
937 #undef DEFTYPECODE
938
939         default:
940           abort ();
941         }
942     }
943
944 #ifdef BCDEBUG_PRINT_CODE
945   fputc ('\n', stderr);
946 #endif
947 }
948 \f
949 /* Emit the machine-code interface trampoline at the beginning of a byte
950    coded function.  The argument is a label name of the interpreter
951    bytecode callinfo structure; the return value is a label name for
952    the beginning of the actual bytecode.  */
953 char *
954 bc_emit_trampoline (callinfo)
955      char *callinfo;
956 {
957   char mylab[20];
958   static int n;
959
960   sprintf (mylab, "*LB%d", n++);
961   
962   BC_EMIT_TRAMPOLINE (trampoline, callinfo);
963
964   seg_defsym (bytecode, mylab);
965   return sym_lookup (mylab)->name;
966 }
967
968
969 /* Simple strdup */
970 char *
971 bc_xstrdup (str)
972      char *str;
973 {
974   char *tmp = xmalloc (strlen (str) + 1);
975
976   strcpy (tmp, str);
977   return tmp;
978 }