home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / bc-emit.c < prev    next >
C/C++ Source or Header  |  1995-06-15  |  21KB  |  993 lines

  1. /* Output bytecodes for GNU C-compiler.
  2.    Copyright (C) 1993, 1994 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, 59 Temple Place - Suite 330,
  19. Boston, 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.  
  43. extern char *xmalloc (), *xrealloc ();
  44. extern void free ();
  45.  
  46. extern struct obstack *rtl_obstack;
  47.  
  48. /* Indexed by mode class, gives the narrowest mode for each class.  */
  49.  
  50. extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
  51.  
  52. /* Commonly used modes.  */
  53. /* Mode whose width is BITS_PER_UNIT */
  54. extern enum machine_mode byte_mode;
  55.  
  56. /* Mode whose width is BITS_PER_WORD */
  57. extern enum machine_mode word_mode;
  58.  
  59. /* Vector indexed by opcode giving info about the args for each opcode. */
  60. static struct arityvec arityvec[] = {
  61. #include "bc-arity.h"
  62. };
  63.  
  64. /* How to print a symbol name for the assembler.  */
  65. static void
  66. prsym (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.  
  87. static struct bc_sym *hashtab[HASH_SIZE];
  88.  
  89. static unsigned int
  90. hash (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. */
  106. struct bc_sym *
  107. sym_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.  */
  130. static void
  131. bc_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. */
  165. static struct bc_seg *
  166. seg_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. */
  181. static void
  182. seg_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. */
  200. static void
  201. seg_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.  */
  219. static void
  220. seg_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. */
  239. static int
  240. seg_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. */
  263. static void
  264. seg_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. */
  283. static void
  284. seg_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.  */
  321. static void
  322. bc_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. */
  396. static struct bc_seg *bc_text_seg;
  397. static struct bc_seg *bc_data_seg;
  398.  
  399. /* Called before anything else in this module. */
  400. void
  401. bc_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. */
  448. static struct bc_seg *ptrconsts;
  449.  
  450. /* Trampoline code for the function entry.  */
  451. struct bc_seg *trampoline;
  452.  
  453. /* Actual byte code of the function. */
  454. struct bc_seg *bytecode;
  455.  
  456. /* List of labels defined in the function. */
  457. struct bc_label *labels;
  458.  
  459. /* List of label references in the function. */
  460. struct 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. */
  466. int
  467. bc_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.  */
  478. int
  479. bc_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.  */
  490. void
  491. bc_align_bytecode (align)
  492.     int align;
  493. {
  494.   seg_align (bytecode, align);
  495. }
  496.  
  497.  
  498. /* Emit data inline into bytecode.  */
  499. void
  500. bc_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. */
  512. struct bc_label *
  513. bc_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. */
  527. int
  528. bc_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. */
  550. void
  551. bc_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. */
  573. void
  574. bc_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.  */
  593. char *
  594. bc_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. */
  640. void
  641. bc_align_const (align)
  642.      int align;
  643. {
  644.   seg_align (bc_text_seg, align);
  645. }
  646.  
  647. /* Emit const data. */
  648. void
  649. bc_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. */
  657. void
  658. bc_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. */
  665. int
  666. bc_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. */
  673. void
  674. bc_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. */
  682. void
  683. bc_align_data (align)
  684.      int align;
  685. {
  686.   seg_align (bc_data_seg, align);
  687. }
  688.  
  689. /* Emit data. */
  690. void
  691. bc_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.  */
  699. void
  700. bc_emit_data_skip (size)
  701.      unsigned int size;
  702. {
  703.   seg_skip (bc_data_seg, size);
  704. }
  705.  
  706. /* Emit label definition in data. */
  707. int
  708. bc_emit_data_labeldef (name)
  709.      char *name;
  710. {
  711.   return seg_defsym (bc_data_seg, name);
  712. }
  713.  
  714. /* Emit label reference in data. */
  715. void
  716. bc_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.  */
  726. int
  727. bc_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. */
  744. void
  745. bc_globalize_label (name)
  746.      char *name;
  747. {
  748.   struct bc_sym *sym;
  749.  
  750.   sym = sym_lookup (name);
  751.   sym->global = 1;
  752. }
  753.  
  754. static enum { in_text, in_data } section = in_text;
  755.  
  756. void
  757. bc_text ()
  758. {
  759.   section = in_text;
  760. }
  761.  
  762. void
  763. bc_data ()
  764. {
  765.   section = in_data;
  766. }
  767.  
  768. void
  769. bc_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.  
  778. void
  779. bc_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.  
  789. void
  790. bc_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.  
  799. int
  800. bc_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.  
  809. void
  810. bc_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.  
  820. void
  821. bc_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.  
  831. rtx
  832. bc_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 */
  850. void
  851. bc_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.  */
  864. void
  865. bc_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. */
  912. void
  913. bc_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.  */
  967. char *
  968. bc_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 */
  984. char *
  985. bc_xstrdup (str)
  986.      char *str;
  987. {
  988.   char *tmp = xmalloc (strlen (str) + 1);
  989.  
  990.   strcpy (tmp, str);
  991.   return tmp;
  992. }
  993.