source: trunk/third/gcc/bc-emit.c @ 8834

Revision 8834, 20.9 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
1/* Output bytecodes for GNU C-compiler.
2   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21
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"
40
41#include <stdio.h>
42
43extern char *xmalloc (), *xrealloc ();
44extern void free ();
45
46extern struct obstack *rtl_obstack;
47
48/* Indexed by mode class, gives the narrowest mode for each class.  */
49
50extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
51
52/* Commonly used modes.  */
53/* Mode whose width is BITS_PER_UNIT */
54extern enum machine_mode byte_mode;
55
56/* Mode whose width is BITS_PER_WORD */
57extern enum machine_mode word_mode;
58
59/* Vector indexed by opcode giving info about the args for each opcode. */
60static struct arityvec arityvec[] = {
61#include "bc-arity.h"
62};
63
64/* How to print a symbol name for the assembler.  */
65static void
66prsym (file, s)
67     FILE *file;
68     char *s;
69{
70  if (*s == '*')
71    fprintf (file, "%s", s + 1);
72  else
73
74#ifdef NAMES_HAVE_UNDERSCORES
75    fprintf (file, "_%s", s);
76#else
77    fprintf (file, "%s", s);
78#endif
79
80}
81
82/* Maintain a bucket hash table for symbol names. */
83
84#define HASH_BITS 32
85#define HASH_SIZE 509
86
87static struct bc_sym *hashtab[HASH_SIZE];
88
89static unsigned int
90hash (name)
91     char *name;
92{
93  unsigned int hash = 0;
94
95  while (*name)
96    {
97      hash = hash << 3 | hash >> HASH_BITS - 3;
98      hash += *name++;
99    }
100
101  return hash % HASH_SIZE;
102}
103
104
105/* Look up the named symbol, creating it if it doesn't exist. */
106struct bc_sym *
107sym_lookup (name)
108     char *name;
109{
110  int i;
111  struct bc_sym *s;
112
113  i = hash (name);
114  for (s = hashtab[i]; s; s = s->next)
115    if (!strcmp (s->name, name))
116      return s;
117
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;
126}
127
128
129/* Write out .globl and common symbols to the named file.  */
130static void
131bc_sym_write (file)
132     FILE *file;
133{
134  int i;
135  struct bc_sym *s;
136
137  for (i = 0; i < HASH_SIZE; ++i)
138    for (s = hashtab[i]; s; s = s->next)
139      {
140        if (s->global)
141          {
142            fprintf (file, "\n\t.globl ");
143            prsym (file, s->name);
144            putc ('\n', file);
145            if (s->common)
146              {
147                fprintf (file, "\n\t.comm ");
148                prsym (file, s->name);
149                fprintf (file, ", %lu\n", s->val);
150              }
151          }
152        else if (s->common)
153          {
154            fprintf (file, "\n\t.lcomm ");
155            prsym (file, s->name);
156            fprintf (file, ", %lu\n", s->val);
157          }
158      }
159}
160
161
162
163
164/* Create and initialize a new segment. */
165static struct bc_seg *
166seg_create ()
167{
168  struct bc_seg *result;
169
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;
177}
178
179
180/* Advance the segment index to the next alignment boundary. */
181static void
182seg_align (seg, log)
183     struct bc_seg *seg;
184     int log;
185{
186  unsigned int oldsize = seg->size;
187
188  seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
189  if (seg->size > seg->alloc)
190    {
191      while (seg->size > seg->alloc)
192        seg->alloc *= 2;
193      seg->data = xrealloc (seg->data, seg->alloc);
194    }
195  bzero (seg->data + oldsize, seg->size - oldsize);
196}
197
198
199/* Append the given data to the given segment. */
200static void
201seg_data (seg, data, size)
202     struct bc_seg *seg;
203     char *data;
204     unsigned int size;
205{
206  if (seg->size + size > seg->alloc)
207    {
208      while (seg->size + size > seg->alloc)
209        seg->alloc *= 2;
210      seg->data = xrealloc (seg->data, seg->alloc);
211    }
212
213  bcopy (data, seg->data + seg->size, size);
214  seg->size += size;
215}
216
217
218/* Append a zero-filled skip to the given segment.  */
219static void
220seg_skip (seg, size)
221     struct bc_seg *seg;
222     unsigned int size;
223{
224  if (seg->size + size > seg->alloc)
225    {
226      while (seg->size + size > seg->alloc)
227        seg->alloc *= 2;
228      seg->data = xrealloc (seg->data, seg->alloc);
229    }
230
231  memset (seg->data + seg->size, 0, size);
232  seg->size += size;
233}
234
235
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. */
239static int
240seg_defsym (seg, name)
241     struct bc_seg *seg;
242     char *name;
243{
244  struct bc_sym *sym;
245  struct bc_segsym *segsym;
246
247  sym = sym_lookup (name);
248  if (sym->defined)
249    return 0;
250
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;
258}
259
260
261/* Generate in seg's data a reference to the given sym, adjusted by
262   the given offset. */
263static void
264seg_refsym (seg, name, offset)
265     struct bc_seg *seg;
266     char *name;
267     int offset;
268{
269  struct bc_sym *sym;
270  struct bc_segreloc *segreloc;
271
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);
279}
280
281
282/* Concatenate the contents of given segments into the first argument. */
283static void
284seg_concat (result, seg)
285     struct bc_seg *result, *seg;
286{
287  unsigned int fix;
288  struct bc_segsym *segsym;
289  struct bc_segreloc *segreloc;
290
291  seg_align (result, MACHINE_SEG_ALIGN);
292  fix = result->size;
293  seg_data (result, seg->data, seg->size);
294  free (seg->data);
295
296  /* Go through the symbols and relocs of SEG, adjusting their offsets
297     for their new location in RESULT. */
298  if (seg->syms)
299    {
300      segsym = seg->syms;
301      do
302        segsym->sym->val += fix;
303      while (segsym->next && (segsym = segsym->next));
304      segsym->next = result->syms;
305      result->syms = seg->syms;
306    }
307  if (seg->relocs)
308    {
309      segreloc = seg->relocs;
310      do
311        segreloc->offset += fix;
312      while (segreloc->next && (segreloc = segreloc->next));
313      segreloc->next = result->relocs;
314      result->relocs = seg->relocs;
315    }
316
317  free ((char *) seg);
318}
319
320/* Write a segment to a file.  */
321static void
322bc_seg_write (seg, file)
323     struct bc_seg *seg;
324     FILE *file;
325{
326  struct bc_segsym *segsym, *nsegsym, *psegsym;
327  struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
328  int i, offset, flag;
329
330  /* Reverse the list of symbols.  */
331  for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
332    {
333      nsegsym = segsym->next;
334      segsym->next = psegsym;
335      psegsym = segsym;
336    }
337  seg->syms = psegsym;
338
339  /* Reverse the list of relocs.  */
340  for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
341    {
342      nsegreloc = segreloc->next;
343      segreloc->next = psegreloc;
344      psegreloc = segreloc;
345    }
346  seg->relocs = psegreloc;
347
348  /* Output each byte of the segment.  */
349  for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
350    {
351      while (segsym && segsym->sym->val == i)
352        {
353          if (i % 8 != 0)
354            putc ('\n', file);
355
356          BC_WRITE_SEGSYM (segsym, file);
357          segsym = segsym->next;
358          flag = 1;
359        }
360      if (segreloc && segreloc->offset == i)
361        {
362          if (i % 8 != 0)
363            putc ('\n', file);
364
365          bcopy (seg->data + i, (char *) &offset, sizeof (int));
366          i += sizeof (int) - 1;
367
368          BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
369          segreloc = segreloc->next;
370          flag = 1;
371        }
372      else
373        {
374          if (i % 8 == 0 || flag)
375            BC_START_BYTECODE_LINE (file);
376
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);
383        }
384    }
385
386  /* Paranoia check--we should have visited all syms and relocs during
387     the output pass.  */
388
389  if (segsym || segreloc)
390    abort ();
391}
392
393
394
395/* Text and data segments of the object file in making. */
396static struct bc_seg *bc_text_seg;
397static struct bc_seg *bc_data_seg;
398
399/* Called before anything else in this module. */
400void
401bc_initialize ()
402{
403  int min_class_size[(int) MAX_MODE_CLASS];
404  enum machine_mode mode;
405  int i;
406
407  bc_init_mode_to_code_map ();
408
409  bc_text_seg = seg_create ();
410  bc_data_seg = seg_create ();
411
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);
416
417  /* Find the narrowest mode for each class and compute the word and byte
418     modes.  */
419
420  for (i = 0; i < (int) MAX_MODE_CLASS; i++)
421    min_class_size[i] = 1000;
422
423  for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
424       mode = (enum machine_mode) ((int) mode + 1))
425    {
426      if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
427        {
428          class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
429          min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
430        }
431      if (GET_MODE_CLASS (mode) == MODE_INT
432          && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
433        byte_mode = mode;
434
435      if (GET_MODE_CLASS (mode) == MODE_INT
436          && GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
437        word_mode = mode;
438    }
439}
440
441
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. */
448static struct bc_seg *ptrconsts;
449
450/* Trampoline code for the function entry.  */
451struct bc_seg *trampoline;
452
453/* Actual byte code of the function. */
454struct bc_seg *bytecode;
455
456/* List of labels defined in the function. */
457struct bc_label *labels;
458
459/* List of label references in the function. */
460struct bc_labelref *labelrefs;
461
462
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. */
466int
467bc_define_pointer (p)
468     char *p;
469{
470  int offset = ptrconsts->size;
471
472  seg_refsym (ptrconsts, p, 0);
473  return offset;
474}
475
476
477/* Begin a bytecoded function.  */
478int
479bc_begin_function (name)
480    char *name;
481{
482  ptrconsts = seg_create ();
483  trampoline = seg_create ();
484  bytecode = seg_create ();
485  return seg_defsym (trampoline, name);
486}
487
488
489/* Force alignment in inline bytecode.  */
490void
491bc_align_bytecode (align)
492    int align;
493{
494  seg_align (bytecode, align);
495}
496
497
498/* Emit data inline into bytecode.  */
499void
500bc_emit_bytecode_const (data, size)
501     char *data;
502     unsigned int size;
503{
504  if (bytecode)
505    seg_data (bytecode, data, size);
506}
507
508
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. */
512struct bc_label *
513bc_get_bytecode_label ()
514{
515  struct bc_label *result;
516
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;
523}
524
525
526/* Define the given label with the current location counter. */
527int
528bc_emit_bytecode_labeldef (label)
529     struct bc_label *label;
530{
531  extern int bc_new_uid ();
532
533  if (!label || label->defined)
534    return 0;
535
536  label->offset = bytecode->size;
537  label->defined = 1;
538  label->uid = bc_new_uid ();
539
540#ifdef DEBUG_PRINT_CODE
541  fprintf (stderr, "$%lx:\n", label);
542#endif
543
544  return 1;
545}
546
547
548/* Generate a location-relative reference to the given bytecode label.
549   It need not be defined yet; label references will be backpatched later. */
550void
551bc_emit_bytecode_labelref (label)
552     struct bc_label *label;
553{
554  struct bc_labelref *labelref;
555  static int zero;
556
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;
562
563#ifdef DEBUG_PRINT_CODE
564  fprintf (stderr, " $%lx", label);
565#endif
566
567  seg_data (bytecode, (char *) &zero, sizeof zero);
568}
569
570
571/* Emit a reference to an external address; generate the reference in the
572   ptrconst area, and emit an offset in the bytecode. */
573void
574bc_emit_code_labelref (name, offset)
575     char *name;
576     int offset;
577{
578  int ptroff;
579
580  ptroff = ptrconsts->size / sizeof (char *);
581  seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
582  seg_refsym (ptrconsts, name, offset);
583
584#ifdef DEBUG_PRINT_CODE
585  fprintf (stderr, " [external <%x> %s]", ptroff, name);
586#endif
587}
588
589
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.  */
593char *
594bc_end_function ()
595{
596  int addr;
597  struct bc_label *label, *next;
598  struct bc_labelref *ref, *nextref;
599  char ptrconsts_label[20];
600  static int nlab;
601
602  /* Backpatch bytecode label references. */
603  for (ref = labelrefs; ref; ref = ref->next)
604    if (ref->label->defined)
605      {
606        addr = ref->label->offset;
607        bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
608      }
609
610  /* Free the chains of labelrefs and labeldefs. */
611  for (ref = labelrefs; ref; ref = nextref)
612    {
613      nextref = ref->next;
614      free ((char *) ref);
615    }
616
617  for (label = labels; label; label = next)
618    {
619      next = label->next;
620      free ((char *) label);
621    }
622
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);
629
630  labels = 0;
631  labelrefs = 0;
632  trampoline = 0;
633  bytecode = 0;
634  ptrconsts = 0;
635
636  return sym_lookup (ptrconsts_label)->name;
637}
638
639/* Force alignment in const data. */
640void
641bc_align_const (align)
642     int align;
643{
644  seg_align (bc_text_seg, align);
645}
646
647/* Emit const data. */
648void
649bc_emit_const (data, size)
650     char *data;
651     unsigned int size;
652{
653  seg_data (bc_text_seg, data, size);
654}
655
656/* Emit a zero-filled constant skip. */
657void
658bc_emit_const_skip (size)
659     unsigned int size;
660{
661  seg_skip (bc_text_seg, size);
662}
663
664/* Emit a label definition in const data. */
665int
666bc_emit_const_labeldef (name)
667     char *name;
668{
669  return seg_defsym (bc_text_seg, name);
670}
671
672/* Emit a label reference in const data. */
673void
674bc_emit_const_labelref (name, offset)
675     char *name;
676     int offset;
677{
678  seg_refsym (bc_text_seg, name, offset);
679}
680
681/* Force alignment in data. */
682void
683bc_align_data (align)
684     int align;
685{
686  seg_align (bc_data_seg, align);
687}
688
689/* Emit data. */
690void
691bc_emit_data (data, size)
692     char *data;
693     unsigned int size;
694{
695  seg_data (bc_data_seg, data, size);
696}
697
698/* Emit a zero-filled data skip.  */
699void
700bc_emit_data_skip (size)
701     unsigned int size;
702{
703  seg_skip (bc_data_seg, size);
704}
705
706/* Emit label definition in data. */
707int
708bc_emit_data_labeldef (name)
709     char *name;
710{
711  return seg_defsym (bc_data_seg, name);
712}
713
714/* Emit label reference in data. */
715void
716bc_emit_data_labelref (name, offset)
717     char *name;
718     int offset;
719{
720  seg_refsym (bc_data_seg, name, offset);
721}
722
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.  */
726int
727bc_emit_common (name, size)
728     char *name;
729     unsigned int size;
730{
731  struct bc_sym *sym;
732
733  sym = sym_lookup (name);
734  if (sym->defined)
735    return 0;
736
737  sym->defined = 1;
738  sym->common = 1;
739  sym->val = size;
740  return 1;
741}
742
743/* Globalize the given label. */
744void
745bc_globalize_label (name)
746     char *name;
747{
748  struct bc_sym *sym;
749
750  sym = sym_lookup (name);
751  sym->global = 1;
752}
753
754static enum { in_text, in_data } section = in_text;
755
756void
757bc_text ()
758{
759  section = in_text;
760}
761
762void
763bc_data ()
764{
765  section = in_data;
766}
767
768void
769bc_align (align)
770     int align;
771{
772  if (section == in_text)
773    bc_align_const (align);
774  else
775    bc_align_data (align);
776}
777
778void
779bc_emit (data, size)
780     char *data;
781     unsigned int size;
782{
783  if (section == in_text)
784    bc_emit_const (data, size);
785  else
786    bc_emit_data (data, size);
787}
788
789void
790bc_emit_skip (size)
791     unsigned int size;
792{
793  if (section == in_text)
794    bc_emit_const_skip (size);
795  else
796    bc_emit_data_skip (size);
797}
798
799int
800bc_emit_labeldef (name)
801     char *name;
802{
803  if (section == in_text)
804    return bc_emit_const_labeldef (name);
805  else
806    return bc_emit_data_labeldef (name);
807}
808
809void
810bc_emit_labelref (name, offset)
811     char *name;
812     int offset;
813{
814  if (section == in_text)
815    bc_emit_const_labelref (name, offset);
816  else
817    bc_emit_data_labelref (name, offset);
818}
819
820void
821bc_write_file (file)
822     FILE *file;
823{
824  BC_WRITE_FILE (file);
825}
826
827
828/* Allocate a new bytecode rtx.
829   If you supply a null BC_LABEL, we generate one.  */
830
831rtx
832bc_gen_rtx (label, offset, bc_label)
833     char *label;
834     int offset;
835     struct bc_label *bc_label;
836{
837  rtx r;
838
839  if (bc_label == 0)
840    bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
841
842  r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
843  bc_label->offset = offset;
844
845  return r;
846}
847
848
849/* Print bytecode rtx */
850void
851bc_print_rtl (fp, r)
852     FILE *fp;
853     rtx r;
854{
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
860}
861
862
863/* Emit a bytecode, keeping a running tally of the stack depth.  */
864void
865bc_emit_bytecode (bytecode)
866     enum bytecode_opcode bytecode;
867{
868  char byte;
869  static int prev_lineno = -1;
870
871  byte = (char) bytecode;
872
873#ifdef BCDEBUG_PRINT_CODE
874  if (lineno != prev_lineno)
875    {
876      fprintf (stderr, "<line %d>\n", lineno);
877      prev_lineno = lineno;
878    }
879
880  fputs (opcode_name[(unsigned int) bytecode], stderr);
881#endif
882
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. */
888
889  bc_emit_bytecode_const (&byte, 1);
890
891  if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
892    {
893      if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
894        max_stack_depth = stack_depth;
895    }
896
897#ifdef VALIDATE_STACK_FOR_BC
898  VALIDATE_STACK_FOR_BC ();
899#endif
900}
901
902
903#ifdef BCDEBUG_PRINT_CODE
904#define PRLIT(TYPE, PTR)  fprintf (stderr, " [%x]", *(TYPE *) PTR)
905#else
906#define PRLIT(X,Y)
907#endif
908
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. */
912void
913bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
914{
915#ifndef __STDC__
916  enum bytecode_opcode opcode;
917#endif
918  va_list arguments;
919  int nliteral, instruction;
920
921  VA_START (arguments, opcode);
922
923#ifndef __STDC__
924  opcode = va_arg (arguments, enum bytecode_opcode);
925#endif
926
927  /* Emit instruction bytecode */
928  bc_emit_bytecode (opcode);
929  instruction = (int) opcode;
930
931  /* Loop literals and emit as bytecode constants */
932  for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
933    {
934      switch (arityvec[instruction].literals[nliteral])
935        {
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:                                                      \
942          {                                                             \
943            TYPE temp = va_arg (arguments, TYPE);                       \
944            bc_emit_bytecode_const ((void *) &temp, sizeof temp);       \
945            PRLIT (TYPE, &temp); }                                      \
946          break;
947
948#include "bc-typecd.def"
949
950#undef DEFTYPECODE
951#endif /* __GNUC__ */
952
953        default:
954          abort ();
955        }
956    }
957
958#ifdef BCDEBUG_PRINT_CODE
959  fputc ('\n', stderr);
960#endif
961}
962
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.  */
967char *
968bc_emit_trampoline (callinfo)
969     char *callinfo;
970{
971  char mylab[20];
972  static int n;
973
974  sprintf (mylab, "*LB%d", n++);
975 
976  BC_EMIT_TRAMPOLINE (trampoline, callinfo);
977
978  seg_defsym (bytecode, mylab);
979  return sym_lookup (mylab)->name;
980}
981
982
983/* Simple strdup */
984char *
985bc_xstrdup (str)
986     char *str;
987{
988  char *tmp = xmalloc (strlen (str) + 1);
989
990  strcpy (tmp, str);
991  return tmp;
992}
Note: See TracBrowser for help on using the repository browser.