home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / GCC 1.37.1r14 / usr / gcc-1.37.1r14 / (gcc-1.37.π) / varasm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-05  |  66.5 KB  |  1,320 lines  |  [TEXT/KAHL]

  1. /* Output variables, constants and external declarations, for GNU compiler.
  2.    Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
  3.    Copyright (C) 1989, 1990 Apple Computer, Inc.
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. /* This file handles generation of all the assembler code
  23.    *except* the instructions of a function.
  24.    This includes declarations of variables and their initial values.
  25.  
  26.    We also output the assembler code for constants stored in memory
  27.    and are responsible for combining constants with the same value.  */
  28.  
  29. #include <stdio.h>
  30. #include <setjmp.h>
  31. /* #include <stab.h> */
  32. #include "config.h"
  33. #include "rtl.h"
  34. #include "tree.h"
  35. #include "flags.h"
  36. #include "expr.h"
  37. #include "hard-reg-set.h"
  38.  
  39. #include "obstack.h"
  40.  
  41. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  42.  
  43. /* File in which assembler code is being written.  */
  44.  
  45. extern FILE *asm_out_file;
  46.  
  47. extern struct obstack *current_obstack;
  48. extern struct obstack *saveable_obstack;
  49. extern struct obstack permanent_obstack;
  50. #define obstack_chunk_alloc xmalloc
  51. extern int xmalloc ();
  52.  
  53. /* Number for making the label on the next
  54.    constant that is stored in memory.  */
  55.  
  56. int const_labelno;
  57.  
  58. /* Number for making the label on the next
  59.    static variable internal to a function.  */
  60.  
  61. int var_labelno;
  62.  
  63. /* Nonzero if at least one function definition has been seen.  */
  64. static int function_defined;
  65.  
  66. extern FILE *asm_out_file;
  67.  
  68. #ifdef APPLE_C
  69. /* Magic function for building direct definitions. */
  70. char *build_direct_defn ();
  71. #endif /* APPLE_C */
  72. static char *compare_constant_1 ();
  73. static void record_constant_1 ();
  74. void assemble_name ();
  75. void output_addressed_constants ();
  76. void output_constant ();
  77. void output_constructor ();
  78.  
  79. #ifdef EXTRA_SECTIONS
  80. static enum in_section {no_section, in_text, in_data, EXTRA_SECTIONS} in_section
  81.   = no_section;
  82. #else
  83. static enum in_section {no_section, in_text, in_data} in_section
  84.   = no_section;
  85. #endif
  86.  
  87. /* Define functions like text_section for any extra sections.  */
  88. #ifdef EXTRA_SECTION_FUNCTIONS
  89. EXTRA_SECTION_FUNCTIONS
  90. #endif
  91.  
  92. /* Tell assembler to switch to text section.  */
  93.  
  94. void
  95. text_section ()
  96. {
  97.   if (in_section != in_text)
  98.     {
  99.       fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
  100.       in_section = in_text;
  101.     }
  102. }
  103.  
  104. /* Tell assembler to switch to data section.  */
  105.  
  106. void
  107. data_section ()
  108. {
  109.   if (in_section != in_data)
  110.     {
  111.       if (flag_shared_data)
  112.     {
  113. #ifdef SHARED_SECTION_ASM_OP
  114.       fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
  115. #else
  116.       fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
  117. #endif
  118.     }
  119.       else
  120.     fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
  121.  
  122.       in_section = in_data;
  123.     }
  124. }
  125.  
  126. /* Determine if we're in the text section. */
  127.  
  128. int
  129. in_text_section ()
  130. {
  131.   return in_section == in_text;
  132. }
  133.  
  134. /* Create the rtl to represent a function, for a function definition.
  135.    DECL is a FUNCTION_DECL node which describes which function.
  136.    The rtl is stored into DECL.  */
  137.  
  138. void
  139. make_function_rtl (decl)
  140.      tree decl;
  141. {
  142. #ifdef APPLE_C
  143.   /* Pascal functions must be mapped into all-upper-case.  Don't worry
  144.      about whether there are function names differing only in case, MPW
  145.      doesn't either... */
  146.   if (TREE_PASCAL (decl) && !TARGET_GAS)
  147.     string_upcase(DECL_ASSEMBLER_NAME (decl));
  148. #endif /* APPLE_C */
  149. #ifdef APPLE_HAX
  150.   /* Identifying the function's name as a code label need only be done
  151.      if tm.h asks for it. */
  152. #ifdef ASM_FUNCTIONIFY_NAME
  153.   ASM_FUNCTIONIFY_NAME (DECL_ASSEMBLER_NAME (decl));
  154. #endif
  155. #endif /* APPLE_HAX */
  156.  
  157.   if (DECL_RTL (decl) == 0)
  158.     DECL_RTL (decl)
  159.       = gen_rtx (MEM, DECL_MODE (decl),
  160.          gen_rtx (SYMBOL_REF, Pmode, DECL_ASSEMBLER_NAME (decl)));
  161.  
  162.   /* Record at least one function has been defined.  */
  163.   function_defined = 1;
  164. }
  165.  
  166. /* Decode an `asm' spec for a declaration as a register name.
  167.    Return the register number, or -1 if nothing specified,
  168.    or -2 if the name is not a register.  */
  169.  
  170. int
  171. decode_reg_name (asmspec)
  172.      char *asmspec;
  173. {
  174.   if (asmspec != 0)
  175.     {
  176.       int i;
  177.       extern char *reg_names[];
  178.  
  179.       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  180.     if (!strcmp (asmspec, reg_names[i]))
  181.       break;
  182.  
  183.       if (i < FIRST_PSEUDO_REGISTER)
  184.     return i;
  185.       else
  186.     return -2;
  187.     }
  188.  
  189.   return -1;
  190. }
  191.  
  192. /* Create the DECL_RTL for a declaration for a static or external variable
  193.    or static or external function.
  194.    ASMSPEC, if not 0, is the string which the user specified
  195.    as the assembler symbol name.
  196.    TOP_LEVEL is nonzero if this is a file-scope variable.
  197.  
  198.    This is never called for PARM_DECL nodes.  */
  199.  
  200. void
  201. make_decl_rtl (decl, asmspec, top_level)
  202.      tree decl;
  203.      char *asmspec;
  204.      int top_level;
  205. {
  206.   register char *name = DECL_ASSEMBLER_NAME (decl);
  207.   int reg_number = decode_reg_name (asmspec);
  208.  
  209.   if (reg_number == -2)
  210.     {
  211.       name = (char *) obstack_alloc (saveable_obstack,
  212.                      strlen (asmspec) + 2);
  213.       name[0] = '*';
  214.       strcpy (&name[1], asmspec);
  215.     }
  216.  
  217.   /* For a duplicate declaration, we can be called twice on the
  218.      same DECL node.  Don't alter the RTL already made
  219.      unless the old mode is wrong (which can happen when
  220.      the previous rtl was made when the type was incomplete).  */
  221.   if (DECL_RTL (decl) == 0
  222.       || GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
  223.     {
  224.       DECL_RTL (decl) = 0;
  225.  
  226.       /* First detect errors in declaring global registers.  */
  227.       if (TREE_REGDECL (decl) && reg_number == -1)
  228.     error_with_decl (decl,
  229.              "register name not specified for `%s'");
  230.       else if (TREE_REGDECL (decl) && reg_number == -2)
  231.     error_with_decl (decl,
  232.              "invalid register name for `%s'");
  233.       else if (reg_number >= 0 && ! TREE_REGDECL (decl))
  234.     error_with_decl (decl,
  235.              "register name given for non-register variable `%s'");
  236.       else if (TREE_REGDECL (decl) && TREE_CODE (decl) == FUNCTION_DECL)
  237.     error ("function declared `register'");
  238.       else if (TREE_REGDECL (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
  239.     error_with_decl (decl, "data type of `%s' isn't suitable for a register");
  240.       /* Now handle properly declared static register variables.  */
  241.       else if (TREE_REGDECL (decl))
  242.     {
  243.       int nregs;
  244.       if (pedantic)
  245.         warning ("ANSI C forbids global register variables");
  246.       if (DECL_INITIAL (decl) != 0)
  247.         {
  248.           DECL_INITIAL (decl) = 0;
  249.           error ("global register variable has initial value");
  250.         }
  251.       if (fixed_regs[reg_number] == 0
  252.           && function_defined && top_level)
  253.         error ("global register variable follows a function definition");
  254.       DECL_RTL (decl) = gen_rtx (REG, DECL_MODE (decl), reg_number);
  255.       if (top_level)
  256.         {
  257.           /* Make this register fixed, so not usable for anything else.  */
  258.           nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
  259.           while (nregs > 0)
  260.         global_regs[reg_number + --nregs] = 1;
  261.           init_reg_sets_1 ();
  262.         }
  263.     }
  264.  
  265.       /* Now handle ordinary static variables and functions (in memory).
  266.      Also handle vars declared register invalidly.  */
  267.       if (DECL_RTL (decl) == 0)
  268.     {
  269.       /* Can't use just the variable's own name for a variable
  270.          whose scope is less than the whole file.
  271.          Concatenate a distinguishing number.  */
  272.       if (!top_level && !TREE_EXTERNAL (decl) && asmspec == 0)
  273.         {
  274.           char *label;
  275.  
  276.           ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
  277.           name = obstack_copy0 (saveable_obstack, label, strlen (label));
  278.           var_labelno++;
  279.         }
  280.  
  281. #ifdef APPLE_C
  282.       /* Transform a pascal name to all-upper-case. */
  283.       if (TREE_PASCAL (decl) && !TARGET_GAS)
  284.         string_upcase (name);
  285.       /* Replace direct function name with its definition (!) */
  286.       if (TREE_DIRECT (decl) && DECL_INITIAL (decl))
  287.         name = build_direct_defn (name, DECL_INITIAL (decl));
  288. #endif /* APPLE_C */
  289. #ifdef APPLE_HAX
  290.       /* Maybe identify data vs code names with a leading character. */
  291. #ifdef ASM_FUNCTIONIFY_NAME
  292.       if (TREE_CODE (decl) == FUNCTION_DECL)
  293.         ASM_FUNCTIONIFY_NAME (name);
  294. #endif
  295. #ifdef ASM_DATIFY_NAME
  296.       if (TREE_CODE (decl) == VAR_DECL)
  297.         ASM_DATIFY_NAME (name);
  298. #endif
  299. #endif /* APPLE_HAX */
  300.  
  301.       DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl),
  302.                      gen_rtx (SYMBOL_REF, Pmode, name));
  303.       if (TREE_VOLATILE (decl))
  304.         MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
  305.       if (TREE_READONLY (decl))
  306.         RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
  307.       MEM_IN_STRUCT_P (DECL_RTL (decl))
  308.         = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
  309.            || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
  310.            || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
  311.     }
  312.     }
  313. }
  314.  
  315. /* Output a string of literal assembler code
  316.    for an `asm' keyword used between functions.  */
  317.  
  318. void
  319. assemble_asm (string)
  320.      tree string;
  321. {
  322.   app_enable ();
  323.  
  324.   fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));
  325. }
  326.  
  327. /* Output assembler code associated with defining the name of a function
  328.    as described by DECL.  */
  329.  
  330. void
  331. assemble_function (decl)
  332.      tree decl;
  333. {
  334.   rtx x, n;
  335.   char *fnname;
  336.   int align;
  337.  
  338.   /* Get the function's name, as described by its RTL.
  339.      This may be different from the DECL_NAME name used in the source file.  */
  340.  
  341.   x = DECL_RTL (decl);
  342.   if (GET_CODE (x) != MEM)
  343.     abort ();
  344.   n = XEXP (x, 0);
  345.   if (GET_CODE (n) != SYMBOL_REF)
  346.     abort ();
  347.   fnname = XSTR (n, 0);
  348.  
  349. #ifdef APPLE_HAX
  350.   define_a_function (fnname);
  351.   /* Do any machine/system dependent processing of the function name that
  352.      must be done before anything else is output. */
  353. #ifdef ASM_PREDECLARE_FUNCTION_NAME
  354.   ASM_PREDECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
  355. #endif
  356. #endif /* APPLE_HAX */
  357.  
  358.   /* The following code does not need preprocessing in the assembler.  */
  359.  
  360.   app_disable ();
  361.  
  362.   text_section ();
  363.  
  364. #ifdef SDB_DEBUGGING_INFO
  365.   /* Make sure types are defined for debugger before fcn name is defined.  */
  366.   if (write_symbols == SDB_DEBUG)
  367.     sdbout_tags (gettags ());
  368. #endif
  369.  
  370.   /* Tell assembler to move to target machine's alignment for functions.  */
  371.  
  372.   align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
  373.   if (align > 0)
  374.     ASM_OUTPUT_ALIGN (asm_out_file, align);
  375.  
  376. #ifdef SDB_DEBUGGING_INFO
  377.   /* Output SDB definition of the function.  */
  378.   if (write_symbols == SDB_DEBUG)
  379.     sdbout_mark_begin_function ();
  380. #endif
  381.  
  382.   /* Make function name accessible from other files, if appropriate.  */
  383.  
  384.   if (TREE_PUBLIC (decl))
  385.     ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
  386.  
  387.   /* Do any machine/system dependent processing of the function name */
  388. #ifdef ASM_DECLARE_FUNCTION_NAME
  389.   ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
  390. #else
  391.   /* Standard thing is just output label for the function.  */
  392.   ASM_OUTPUT_LABEL (asm_out_file, fnname);
  393. #endif /* ASM_DECLARE_FUNCTION_NAME */
  394. }
  395.  
  396. /* Assemble " .int 0\n" or whatever this assembler wants.  */
  397.  
  398. void
  399. assemble_integer_zero ()
  400. {
  401.   ASM_OUTPUT_INT (asm_out_file, const0_rtx);
  402. }
  403.  
  404. /* Assemble a string constant with the specified C string as contents.  */
  405.  
  406. void
  407. assemble_string (p, size)
  408.      unsigned char *p;
  409.      int size;
  410. {
  411.   register int i;
  412.   int excess = 0;
  413.   int pos = 0;
  414.   int maximum = 2000;
  415.  
  416.   /* If the string is very long, split it up.  */
  417.  
  418.   while (pos < size)
  419.     {
  420.       int thissize = size - pos;
  421.       if (thissize > maximum)
  422.     thissize = maximum;
  423.  
  424. #ifdef ASM_OUTPUT_ASCII
  425.       ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
  426. #else
  427.       fprintf (asm_out_file, "\t.ascii \"");
  428.  
  429.       for (i = 0; i < thissize; i++)
  430.     {
  431.       register int c = p[i];
  432.       if (c == '\"' || c == '\\')
  433.         putc ('\\', asm_out_file);
  434.       if (c >= ' ' && c < 0177)
  435.         putc (c, asm_out_file);
  436.       else
  437.         {
  438.           fprintf (asm_out_file, "\\%o", c);
  439.           /* After an octal-escape, if a digit follows,
  440.          terminate one string constant and start another.
  441.          The Vax assembler fails to stop reading the escape
  442.          after three digits, so this is the only way we
  443.          can get it to parse the data properly.  */
  444.           if (i < thissize - 1
  445.           && p[i + 1] >= '0' && p[i + 1] <= '9')
  446.         fprintf (asm_out_file, "\"\n\t.ascii \"");
  447.         }
  448.     }
  449.       fprintf (asm_out_file, "\"\n");
  450. #endif /* no ASM_OUTPUT_ASCII */
  451.  
  452.       pos += thissize;
  453.       p += thissize;
  454.     }
  455. }
  456.  
  457. /* Assemble everything that is needed for a variable or function declaration.
  458.    Not used for automatic variables, and not used for function definitions.
  459.    Should not be called for variables of incomplete structure type.
  460.  
  461.    TOP_LEVEL is nonzero if this variable has file scope.
  462.    WRITE_SYMBOLS is DBX_DEBUG if writing dbx symbol output.
  463.    The dbx data for a file-scope variable is written here.
  464.    AT_END is nonzero if this is the special handling, at end of compilation,
  465.    to define things that have had only tentative definitions.  */
  466.  
  467. void
  468. assemble_variable (decl, top_level, write_symbols, at_end)
  469.      tree decl;
  470.      int top_level;
  471.      enum debugger write_symbols;
  472.      int at_end;
  473. {
  474.   register char *name;
  475.   register int i;
  476.  
  477.   /* Do nothing for global register variables.  */
  478.  
  479.   if (GET_CODE (DECL_RTL (decl)) == REG)
  480.     return;
  481.  
  482.   /* Normally no need to say anything for external references,
  483.      since assembler considers all undefined symbols external.  */
  484.  
  485.   if (TREE_EXTERNAL (decl))
  486.     return;
  487.  
  488.   /* Output no assembler code for a function declaration.
  489.      Only definitions of functions output anything.  */
  490.  
  491.   if (TREE_CODE (decl) == FUNCTION_DECL)
  492.     return;
  493.  
  494.   /* If type was incomplete when the variable was declared,
  495.      see if it is complete now.  */
  496.  
  497.   if (DECL_SIZE (decl) == 0)
  498.     layout_decl (decl, 0);
  499.  
  500.   /* Still incomplete => don't allocate it; treat the tentative defn
  501.      (which is what it must have been) as an `extern' reference.  */
  502.  
  503.   if (DECL_SIZE (decl) == 0)
  504.     {
  505.       error_with_file_and_line (DECL_SOURCE_FILE (decl),
  506.                 DECL_SOURCE_LINE (decl),
  507.                 "storage size of static var `%s' isn't known",
  508.                 IDENTIFIER_POINTER (DECL_NAME (decl)));
  509.       return;
  510.     }
  511.  
  512.   /* The first declaration of a variable that comes through this function
  513.      decides whether it is global (in C, has external linkage)
  514.      or local (in C, has internal linkage).  So do nothing more
  515.      if this function has already run.  */
  516.  
  517.   if (TREE_ASM_WRITTEN (decl))
  518.     return;
  519.  
  520.   TREE_ASM_WRITTEN (decl) = 1;
  521.  
  522. #ifdef DBX_DEBUGGING_INFO
  523.   /* File-scope global variables are output here.  */
  524.   if (write_symbols == DBX_DEBUG && top_level)
  525.     dbxout_symbol (decl, 0);
  526. #endif
  527. #ifdef SDB_DEBUGGING_INFO
  528.   if (write_symbols == SDB_DEBUG && top_level)
  529.     sdbout_symbol (decl, 0);
  530. #endif
  531.   if (write_symbols == GDB_DEBUG)
  532.     /* Make sure the file is known to GDB even if it has no functions.  */
  533.     set_current_gdbfile (DECL_SOURCE_FILE (decl));
  534.  
  535.   /* If storage size is erroneously variable, just continue.
  536.      Error message was already made.  */
  537.  
  538.   if (! TREE_LITERAL (DECL_SIZE (decl)))
  539.     return;
  540.  
  541.   app_disable ();
  542.  
  543.   name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
  544.  
  545.   /* Handle uninitialized definitions.  */
  546.  
  547.   if (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)
  548.     {
  549.       int size = (TREE_INT_CST_LOW (DECL_SIZE (decl))
  550.           * DECL_SIZE_UNIT (decl)
  551.           / BITS_PER_UNIT);
  552.       int rounded = size;
  553.       /* Don't allocate zero bytes of common,
  554.      since that means "undefined external" in the linker.  */
  555.       if (size == 0) rounded = 1;
  556.       /* Round size up to multiple of BIGGEST_ALIGNMENT bits
  557.      so that each uninitialized object starts on such a boundary.  */
  558.       rounded = ((rounded + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
  559.          / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
  560.          * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
  561.       if (flag_shared_data)
  562.     data_section ();
  563.       if (TREE_PUBLIC (decl))
  564.     ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
  565.       else
  566.     ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
  567.       return;
  568.     }
  569.  
  570.   /* Handle initialized definitions.  */
  571.  
  572.   /* First make the assembler name(s) global if appropriate.  */
  573.   if (TREE_PUBLIC (decl) && DECL_NAME (decl))
  574.     ASM_GLOBALIZE_LABEL (asm_out_file, name);
  575. #if 0
  576.   for (d = equivalents; d; d = TREE_CHAIN (d))
  577.     {
  578.       tree e = TREE_VALUE (d);
  579.       if (TREE_PUBLIC (e) && DECL_NAME (e))
  580.     ASM_GLOBALIZE_LABEL (asm_out_file,
  581.                  XSTR (XEXP (DECL_RTL (e), 0), 0));
  582.     }
  583. #endif
  584.  
  585.   /* Output any data that we will need to use the address of.  */
  586.   if (DECL_INITIAL (decl))
  587.     output_addressed_constants (DECL_INITIAL (decl));
  588.  
  589. #ifdef APPLE_HAX
  590.   define_a_variable (name);
  591.   /* Do any machine/system dependent processing of the variable name. */
  592. #ifdef ASM_DECLARE_VARIABLE_NAME
  593. /*  if (!TARGET_GAS)     */
  594.         ASM_DECLARE_VARIABLE_NAME (asm_out_file, name, TREE_PUBLIC (decl));
  595. #endif
  596. #endif /* APPLE_HAX */
  597.  
  598.   /* Switch to the proper section for this data.  */
  599. #ifdef SELECT_SECTION
  600.   SELECT_SECTION (decl);
  601. #else
  602.   if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
  603.     text_section ();
  604.   else
  605.     data_section ();
  606. #endif
  607.  
  608.   /* Output the alignment of this data.  */
  609.   for (i = 0; DECL_ALIGN (decl) >= BITS_PER_UNIT << (i + 1); i++);
  610.   if (i > 0)
  611.     ASM_OUTPUT_ALIGN (asm_out_file, i);
  612.  
  613.   /* Output the name(s) of this data.  */
  614.   ASM_OUTPUT_LABEL (asm_out_file, name);
  615. #if 0
  616.   for (d = equivalents; d; d = TREE_CHAIN (d))
  617.     {
  618.       tree e = TREE_VALUE (d);
  619.       ASM_OUTPUT_LABEL (asm_out_file, XSTR (XEXP (DECL_RTL (e), 0), 0));
  620.     }
  621. #endif
  622.  
  623.   if (DECL_INITIAL (decl))
  624.     /* Output the actual data.  */
  625.     output_constant (DECL_INITIAL (decl), int_size_in_bytes (TREE_TYPE (decl)));
  626.   else
  627.     /* Leave space for it.  */
  628.     ASM_OUTPUT_SKIP (asm_out_file, int_size_in_bytes (TREE_TYPE (decl)));
  629. #ifdef APPLE_HAX
  630.   /* Maybe do something to close out the definition of a variable. */
  631. #ifdef ASM_VARIABLE_END
  632.   ASM_VARIABLE_END (asm_out_file, name);
  633. #endif
  634. #endif /* APPLE_HAX */
  635. }
  636.  
  637. /* Output something to declare an external symbol to the assembler.
  638.    (Most assemblers don't need this, so we normally output nothing.)  */
  639.  
  640. void
  641. assemble_external (decl)
  642.      tree decl;
  643. {
  644.   rtx rtl = DECL_RTL (decl);
  645.  
  646.   if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
  647.     {
  648. #ifdef ASM_OUTPUT_EXTERNAL
  649.       /* Some systems do require some output.  */
  650.       ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
  651. #endif
  652.     }
  653. }
  654.  
  655. /* Output to FILE a reference to the assembler name of a C-level name NAME.
  656.    If NAME starts with a *, the rest of NAME is output verbatim.
  657.    Otherwise NAME is transformed in an implementation-defined way
  658.    (usually by the addition of an underscore).
  659.    Many macros in the tm file are defined to call this function.  */
  660.  
  661. void
  662. assemble_name (file, name)
  663.      FILE *file;
  664.      char *name;
  665. {
  666.   if (name[0] == '*')
  667.     fputs (&name[1], file);
  668.   else
  669.     ASM_OUTPUT_LABELREF (file, name);
  670. }
  671.  
  672. /* Allocate SIZE bytes writable static space with a gensym name
  673.    and return an RTX to refer to its address.  */
  674.  
  675. rtx
  676. assemble_static_space (size)
  677.      int size;
  678. {
  679.   char name[12];
  680.   char *namestring;
  681.   rtx x;
  682.   /* Round size up to multiple of BIGGEST_ALIGNMENT bits
  683.      so that each uninitialized object starts on such a boundary.  */
  684.   int rounded = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
  685.          / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
  686.          * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
  687.  
  688.   if (flag_shared_data)
  689.     data_section ();
  690.   ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
  691.   ++const_labelno;
  692.  
  693.   namestring = (char *) obstack_alloc (saveable_obstack,
  694.                        strlen (name) + 2);
  695.   strcpy (namestring, name);
  696.  
  697.   x = gen_rtx (SYMBOL_REF, Pmode, namestring);
  698.   ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
  699.   return x;
  700. }
  701.  
  702. /* Here we combine duplicate floating constants to make
  703.    CONST_DOUBLE rtx's, and force those out to memory when necessary.  */
  704.  
  705. /* Chain of all CONST_DOUBLE rtx's constructed for the current function.
  706.    They are chained through the CONST_DOUBLE_CHAIN.
  707.    A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
  708.    In that case, CONST_DOUBLE_MEM is either a MEM,
  709.    or const0_rtx if no MEM has been made for this CONST_DOUBLE yet.  */
  710.  
  711. static rtx real_constant_chain;
  712.  
  713. /* Return a CONST_DOUBLE for a value specified as a pair of ints.
  714.    For an integer, I0 is the low-order word and I1 is the high-order word.
  715.    For a real number, I0 is the word with the low address
  716.    and I1 is the word with the high address.  */
  717.  
  718. rtx
  719. immed_double_const (i0, i1, mode)
  720.      int i0, i1;
  721.      enum machine_mode mode;
  722. {
  723.   register rtx r;
  724.  
  725.   if (mode == DImode && i0 == 0 && i1 == 0)
  726.     return const0_rtx;
  727.  
  728.   /* Search the chain for an existing CONST_DOUBLE with the right value.
  729.      If one is found, re(TREE_CODE (exp) != REAL_CST)
  730.     error ("initializer for floating value is not a floating constant");
  731.       else
  732.     {
  733.       REAL_VALUE_TYPE d;
  734.       jmp_buf output_constant_handler;
  735.  
  736.       d = TREE_REAL_CST (exp);
  737.       if (setjmp (output_constant_handler))
  738.         {
  739.           error ("floating point trap outputting a constant");
  740. #ifdef REAL_IS_NOT_DOUBLE
  741.           bzero (&d, sizeof d);
  742.           d = REAL_VALUE_ATOF ("0");
  743. #else
  744.           d = 0;
  745. #endif
  746.         }
  747.       set_float_handler (output_constant_handler);
  748.  
  749.       if (size < 4)
  750.         break;
  751.       else if (size < 8)
  752.         {
  753.           ASM_OUTPUT_FLOAT (asm_out_file, d);
  754.           size -= 4;
  755.         }
  756.       else
  757.         {
  758. #ifdef APPLE_C
  759.           /* Decide about how to dump out double and long double constants.
  760.          Note that the exact amount dumped depends on the size of long
  761.          doubles. */
  762.           if (size < 10)
  763.         {
  764.           ASM_OUTPUT_DOUBLE (asm_out_file, d);
  765.           size -= 8;
  766.         }
  767.           else
  768.         {
  769.           ASM_OUTPUT_LONG_DOUBLE (asm_out_file, d);
  770.           size -= GET_MODE_SIZE (XFmode);
  771.         }
  772. #else
  773.           ASM_OUTPUT_DOUBLE (asm_out_file, d);
  774.           size -= 8;
  775. #endif /* APPLE_C */
  776.         }
  777.       set_float_handler (0);
  778.      }
  779.       break;
  780.  
  781.     case COMPLEX_TYPE:
  782.       output_constant (TREE_REALPART (exp), size / 2);
  783.       output_constant (TREE_IMAGPART (exp), size / 2);
  784.       size -= (size / 2) * 2;
  785.       break;
  786.  
  787.     case ARRAY_TYPE:
  788.       if (TREE_CODE (exp) == CONSTRUCTOR)
  789.     {
  790.       output_constructor (exp, size);
  791.       return;
  792.     }
  793.       else if (TREE_CODE (exp) == STRING_CST)
  794.     {
  795.       int excess = 0;
  796.  
  797.       if (size > TREE_STRING_LENGTH (exp))
  798.         {
  799.           excess = size - TREE_STRING_LENGTH (exp);
  800.           size = TREE_STRING_LENGTH (exp);
  801.         }
  802.  
  803.       assemble_string (TREE_STRING_POINTER (exp), size);
  804.       size = excess;
  805.     }
  806.       else
  807.     abort ();
  808.       break;
  809.  
  810.     case RECORD_TYPE:
  811.     case UNION_TYPE:
  812.       if (TREE_CODE (exp) == CONSTRUCTOR)
  813.     output_constructor (exp, size);
  814.       else
  815.     abort ();
  816.       return;
  817.     }
  818.  
  819.   if (size > 0)
  820.     ASM_OUTPUT_SKIP (asm_out_file, size);
  821. }
  822.  
  823. /* Subroutine of output_constant, used for CONSTRUCTORs
  824.    (aggregate constants).
  825.    Generate at least SIZE bytes, padding if necessary.  */
  826.  
  827. void
  828. output_constructor (exp, size)
  829.      tree exp;
  830.      int size;
  831. {
  832.   register tree link, field = 0;
  833.   /* Number of bytes output or skipped so far.
  834.      In other words, current position within the constructor.  */
  835.   int total_bytes = 0;
  836.   /* Non-zero means BYTE contains part of a byte, to be output.  */
  837.   int byte_buffer_in_use = 0;
  838.   register int byte;
  839.  
  840.   if (HOST_BITS_PER_INT < BITS_PER_UNIT)
  841.     abort ();
  842.  
  843.   if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
  844.       || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
  845.     field = TYPE_FIELDS (TREE_TYPE (exp));
  846.  
  847.   /* As LINK goes through the elements of the constant,
  848.      FIELD goes through the structure fields, if the constant is a structure.
  849.      But the constant could also be an array.  Then FIELD is zero.  */
  850.   for (link = CONSTRUCTOR_ELTS (exp);
  851.        link;
  852.        link = TREE_CHAIN (link),
  853.        field = field ? TREE_CHAIN (field) : 0)
  854.     {
  855.       tree val = TREE_VALUE (link);
  856.  
  857.       /* Eliminate the NOP_EXPR that makes a cast not be an lvalue.  */
  858.       if (TREE_CODE (val) == NOP_EXPR
  859.       && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0)))
  860.     val = TREE_OPERAND (val, 0);
  861.  
  862.       if (field == 0
  863.       || (DECL_MODE (field) != BImode))
  864.     {
  865.       register int fieldsize;
  866.  
  867.       /* An element that is not a bit-field.
  868.          Output any buffered-up bit-fields preceding it.  */
  869.       if (byte_buffer_in_use)
  870.         {
  871.           ASM_OUTPUT_BYTE (asm_out_file, byte);
  872.           total_bytes++;
  873.           byte_buffer_in_use = 0;
  874.         }
  875.  
  876.       /* Advance to offset of this element.
  877.          Note no alignment needed in an array, since that is guaranteed
  878.          if each element has the proper size.  */
  879.       if (field != 0 && DECL_OFFSET (field) / BITS_PER_UNIT != total_bytes)
  880.         {
  881.           ASM_OUTPUT_SKIP (asm_out_file,
  882.                    (DECL_OFFSET (field) / BITS_PER_UNIT
  883.                 - total_bytes));
  884.           total_bytes = DECL_OFFSET (field) / BITS_PER_UNIT;
  885.         }
  886.  
  887.       /* Determine size this element should occupy.  */
  888.       if (field)
  889.         {
  890.           if (! TREE_LITERAL (DECL_SIZE (field)))
  891.         abort ();
  892.           fieldsize = TREE_INT_CST_LOW (DECL_SIZE (field))
  893.         * DECL_SIZE_UNIT (field);
  894.           fieldsize = (fieldsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
  895.         }
  896.       else
  897.         fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
  898.  
  899.       /* Output the element's initial value.  */
  900.       output_constant (val, fieldsize);
  901.  
  902.       /* Count its size.  */
  903.       total_bytes += fieldsize;
  904.     }
  905.       else if (TREE_CODE (val) != INTEGER_CST)
  906.     error ("invalid initial value for member `%s'",
  907.            IDENTIFIER_POINTER (DECL_NAME (field)));
  908.       else
  909.     {
  910.       /* Element that is a bit-field.  */
  911.  
  912.       int next_offset = DECL_OFFSET (field);
  913.       int end_offset
  914.         = (next_offset
  915.            + (TREE_INT_CST_LOW (DECL_SIZE (field))
  916.           * DECL_SIZE_UNIT (field)));
  917.  
  918.       /* If this field does not start in this (or, next) byte,
  919.          skip some bytes.  */
  920.       if (next_offset / BITS_PER_UNIT != total_bytes)
  921.         {
  922.           /* Output remnant of any bit field in previous bytes.  */
  923.           if (byte_buffer_in_use)
  924.         {
  925.           ASM_OUTPUT_BYTE (asm_out_file, byte);
  926.           total_bytes++;
  927.           byte_buffer_in_use = 0;
  928.         }
  929.  
  930.           /* If still not at proper byte, advance to there.  */
  931.           if (next_offset / BITS_PER_UNIT != total_bytes)
  932.         {
  933.           ASM_OUTPUT_SKIP (asm_out_file,
  934.                    next_offset / BITS_PER_UNIT - total_bytes);
  935.           total_bytes = next_offset / BITS_PER_UNIT;
  936.         }
  937.         }
  938.  
  939.       if (! byte_buffer_in_use)
  940.         byte = 0;
  941.  
  942.       /* We must split the element into pieces that fall within
  943.          separate bytes, and combine each byte with previous or
  944.          following bit-fields.  */
  945.  
  946.       /* next_offset is the offset n fbits from the begining of
  947.          the structure to the next bit of this element to be processed.
  948.          end_offset is the offset of the first bit past the end of
  949.          this element.  */
  950.       while (next_offset < end_offset)
  951.         {
  952.           int this_time;
  953.           int next_byte = next_offset / BITS_PER_UNIT;
  954.           int next_bit = next_offset % BITS_PER_UNIT;
  955.  
  956.           /* Advance from byte to byte
  957.          within this element when necessary.  */
  958.           while (next_byte != total_bytes)
  959.         {
  960.           ASM_OUTPUT_BYTE (asm_out_file, byte);
  961.           total_bytes++;
  962.           byte = 0;
  963.         }
  964.  
  965.           /* Number of bits we can process at once
  966.          (all part of the same byte).  */
  967.           this_time = MIN (end_offset - next_offset,
  968.                    BITS_PER_UNIT - next_bit);
  969. #ifdef BYTES_BIG_ENDIAN
  970.           /* On big-endian machine, take the most significant bits
  971.          first (of the bits that are significant)
  972.          and put them into bytes from the most significant end.  */
  973.           byte |= (((TREE_INT_CST_LOW (val)
  974.              >> (end_offset - next_offset - this_time))
  975.             & ((1 << this_time) - 1))
  976.                << (BITS_PER_UNIT - this_time - next_bit));
  977. #else
  978.           /* On little-endian machines,
  979.          take first the least significant bits of the value
  980.          and pack them starting at the least significant
  981.          bits of the bytes.  */
  982.           byte |= ((TREE_INT_CST_LOW (val)
  983.             >> (next_offset - DECL_OFFSET (field)))
  984.                & ((1 << this_time) - 1)) << next_bit;
  985. #endif
  986.           next_offset += this_time;
  987.           byte_buffer_in_use = 1;
  988.         }
  989.     }
  990.     }
  991.   if (byte_buffer_in_use)
  992.     {
  993.       ASM_OUTPUT_BYTE (asm_out_file, byte);
  994.       total_bytes++;
  995.     }
  996.   if (total_bytes < size)
  997.     ASM_OUTPUT_SKIP (asm_out_file, size - total_bytes);
  998. }
  999.  
  1000. #ifdef APPLE_HAX
  1001. /* This is all part of the scheme to produce the appropriate import
  1002.    and export declarations. */
  1003.  
  1004. struct impsym {
  1005.   char *name;
  1006.   char *modulename;
  1007.   struct impsym *next;
  1008. };
  1009.  
  1010. static struct impsym *implist;
  1011.  
  1012. char *mnames[100];
  1013.  
  1014. int mtop;
  1015.  
  1016. /* This particular string copy is pure paranoia. */
  1017.  
  1018. char *
  1019. copy_string(str)
  1020. char *str;
  1021. {
  1022.   char *rslt;
  1023.  
  1024.   rslt = (char *) xmalloc(strlen(str)+4);
  1025.   strcpy(rslt, str);
  1026.   return rslt;
  1027. }
  1028.  
  1029. /* Do the allocations for this file. */
  1030.  
  1031. init_import_for_file()
  1032. {
  1033.   implist = NULL;
  1034.   mtop = 0;
  1035.   mnames[mtop] = "*";
  1036. }
  1037.  
  1038. start_module (name)
  1039. char *name;
  1040. {
  1041.   if (mtop >= 99)
  1042.     abort ();
  1043.   mnames[++mtop] = copy_string (name);
  1044. #ifdef TARGET_B
  1045.   if (TARGET_B)
  1046.     clear_const_hash_table ();
  1047. #endif
  1048. }
  1049.  
  1050. finish_module (name)
  1051. char *name;
  1052. {
  1053.   if (strcmp(mnames[mtop], name) == 0)
  1054.     --mtop;
  1055.   if (mtop < 0)
  1056.     abort ();
  1057. }
  1058.  
  1059. char *
  1060. add_section_mark (str)
  1061. char *str;
  1062. {
  1063.   char *label;
  1064. #if 0
  1065.   /* Ideal */
  1066.   label = (char *) alloca (strlen (str) + 2);
  1067.   sprintf (label, "0%s", str);
  1068.   obstack_copy0 (saveable_obstack, label, strlen (label));
  1069. #else
  1070.   label = (char *) xmalloc (strlen (str) + 10);
  1071.   sprintf (label, "0%s", str);
  1072. #endif
  1073.   return label;
  1074. }
  1075.  
  1076. match_name (name, impentry)
  1077. char *name;
  1078. struct impsym *impentry;
  1079. {
  1080.   return ((strcmp (name, impentry->name) == 0
  1081.        || strcmp (name+1, (impentry->name)+1) == 0)
  1082.       && (*(impentry->modulename) == '*'
  1083.           || strcmp (mnames[mtop], impentry->modulename) == 0));
  1084. }
  1085.  
  1086. /* This function will decide about importation of variables according to
  1087.    whether they are code or data. */
  1088.  
  1089. import_a_declared_name (decl)
  1090.      tree decl;
  1091. {
  1092. #ifdef IMPORT_NAMES
  1093.   rtx rtl = DECL_RTL (decl);
  1094.  
  1095.   if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
  1096.     {
  1097.       if (TREE_CODE (decl) == FUNCTION_DECL)
  1098.         import_a_function(XSTR (XEXP (rtl, 0), 0));
  1099.       else if (TREE_CODE (decl) == VAR_DECL)
  1100.         import_a_variable(XSTR (XEXP (rtl, 0), 0));
  1101.       else abort();
  1102.     }
  1103. #endif
  1104. }
  1105.  
  1106. /* Import a data name.  This just records, actual output doesn't occur
  1107.    until all the names in a module have been seen.  If the name is defined
  1108.    in this module, no import will be issued.  If it has already been seen
  1109.    at all, don't even bother to record it. */
  1110.  
  1111. import_a_variable(name)
  1112. char *name;
  1113. {
  1114. #ifdef IMPORT_NAMES
  1115.   struct impsym *tmp;
  1116.  
  1117.   /* Don't import direct function definitions */
  1118.   if (name[1] == ';') return;
  1119.   for (tmp = implist; tmp != NULL; tmp = tmp->next)
  1120.     if (match_name (name, tmp))
  1121.       return;
  1122.   tmp = (struct impsym *) xmalloc (sizeof (struct impsym));
  1123.   tmp->name = copy_string(name);
  1124.   tmp->modulename = mnames[mtop];
  1125.   tmp->next = implist;
  1126.   implist = tmp;
  1127. #endif
  1128. }
  1129.  
  1130. /* Import a code name, but ignore if it's already occurred. */
  1131.  
  1132. import_a_function(name)
  1133. char *name;
  1134. {
  1135. #ifdef IMPORT_NAMES
  1136.   struct impsym *tmp;
  1137.  
  1138.   /* Don't import direct function definitions */
  1139.   if (name[1] == ';') return;
  1140.   for (tmp = implist; tmp != NULL; tmp = tmp->next)
  1141.     if (match_name (name, tmp))
  1142.       return;
  1143.   tmp = (struct impsym *) xmalloc (sizeof (struct impsym));
  1144.   tmp->name = copy_string(name);
  1145.   tmp->modulename = mnames[mtop];
  1146.   tmp->next = implist;
  1147.   implist = tmp;
  1148. #endif
  1149. }
  1150.  
  1151. /* Define or export a data name, or more accurately erase its importation. */
  1152.  
  1153. define_a_variable (name)
  1154. char *name;
  1155. {
  1156. #ifdef IMPORT_NAMES
  1157.   struct impsym *tmp;
  1158.  
  1159.   for (tmp = implist; tmp; tmp = tmp->next)
  1160.     if (match_name (name, tmp))
  1161.       {
  1162.     tmp->name = "";
  1163.     return;
  1164.       }
  1165. #endif
  1166. }
  1167.  
  1168. define_a_function (name)
  1169. char *name;
  1170. {
  1171. #ifdef IMPORT_NAMES
  1172.   struct impsym *tmp;
  1173.  
  1174.   for (tmp = implist; tmp; tmp = tmp->next)
  1175.     if (match_name (name, tmp))
  1176.       {
  1177.     tmp->name = "";
  1178.     return;
  1179.       }
  1180. #endif
  1181. }
  1182.  
  1183. /* Import every symbol in the named module into the current module. */
  1184.  
  1185. add_inline_imports (inlined)
  1186. char *inlined;
  1187. {
  1188. #ifdef IMPORT_NAMES
  1189.   struct impsym *tmp;
  1190.  
  1191.   for (tmp = implist; tmp; tmp = tmp->next)
  1192.     if (strcmp(inlined, tmp->modulename) == 0)
  1193.       {
  1194.     import_a_function (tmp->name);
  1195.       }
  1196. #endif
  1197. }
  1198.  
  1199. /* Any symbol undefined by a function must be imported (this makes for lots
  1200.    of imports sometimes).  Must be careful about code vs data symbols.
  1201.    To save some asm instructions, all the data symbols are dumped first.
  1202.    (Note that the loops are written such that the output is correct even
  1203.    if the repn changes.)  */
  1204.  
  1205. import_undefined(file)
  1206. FILE *file;
  1207. {
  1208. #ifdef IMPORT_NAMES
  1209.   struct impsym *tmp;
  1210.  
  1211.   for (tmp = implist; tmp; tmp = tmp->next)
  1212.     {
  1213.       if (strlen (tmp->name) > 0
  1214.       && (strcmp(mnames[mtop], tmp->modulename) == 0
  1215.           || (*(tmp->modulename) == '*' && (tmp->name)[1] == 'L'))
  1216.       && *(tmp->name) == '2')
  1217.     {
  1218. #ifdef ASM_IMPORT_NAME
  1219.       ASM_IMPORT_NAME (file, tmp->name);
  1220. #endif
  1221.     }
  1222.     }
  1223.   for (tmp = implist; tmp; tmp = tmp->next)
  1224.     {
  1225.       if (strlen (tmp->name) > 0
  1226.       && (strcmp(mnames[mtop], tmp->modulename) == 0
  1227.           || (*(tmp->modulename) == '*' && (tmp->name)[1] == 'L'))
  1228.       && *(tmp->name) != '2')
  1229.     {
  1230. #ifdef ASM_IMPORT_NAME
  1231.       ASM_IMPORT_NAME (file, tmp->name);
  1232. #endif
  1233.     }
  1234.     }
  1235. #endif
  1236. }
  1237. #endif /* APPLE_HAX */
  1238.  
  1239. #ifdef APPLE_C
  1240. /* This transforms a string into all-upper-case, just the way MPW Pascal
  1241.    likes it. */
  1242.  
  1243. #include <ctype.h>
  1244.  
  1245. string_upcase(str)
  1246. char *str;
  1247. {
  1248.   int i;
  1249.  
  1250.   for (i = 0; str[i] != '\0'; ++i)
  1251.     {
  1252.       if (islower(str[i])) str[i] = toupper(str[i]);
  1253.     }
  1254. }
  1255.  
  1256. /* This is a rather strange way to build a direct definition, but seems to
  1257.    work - make a comma-separated list of numbers, followed by semicolon,
  1258.    followed by the original name.  This form is correct for MPW Asm, but
  1259.    might have to be modified by an aux-output.c routine to be used with
  1260.    any other assembler. */
  1261.  
  1262. /* (Should check that defn is a list of 16-bit numbers.) */
  1263.  
  1264. char *
  1265. build_direct_defn(name, init)
  1266.      char *name;
  1267.      tree init;
  1268. {
  1269.     tree tail;
  1270.     char *tmpbuf;
  1271.     char tmp2[20];
  1272.     int tmpsize = 20 + strlen (name);
  1273.  
  1274.     /* Calculate how much buffer we'll need (could be done with obstack?) */
  1275.     if (TREE_CODE (init) == INTEGER_CST)
  1276.       tmpsize += 20;
  1277.     else
  1278.       {
  1279.     tail = CONSTRUCTOR_ELTS (init);
  1280.     while (tail != 0)
  1281.       {
  1282.         tmpsize += 20;
  1283.         tail = TREE_CHAIN (tail);
  1284.       }
  1285.       }
  1286.     tmpbuf = (char *) xmalloc (tmpsize);
  1287.     /* Leave extra hole for code/data id, plus semicolon as direct fn flag,
  1288.         plus a blank to fool assemble_name. */
  1289.     sprintf (tmpbuf, "0; ");
  1290.     if (TREE_CODE (init) == INTEGER_CST)
  1291.       {
  1292.     sprintf(tmp2, "%d", TREE_INT_CST_LOW (init));
  1293.     strcat (tmpbuf, tmp2);
  1294.       }
  1295.     else
  1296.       {
  1297.     tail = CONSTRUCTOR_ELTS (init);
  1298.     /* Go through list getting numbers. */
  1299.     while (tail != 0)
  1300.       {
  1301.         sprintf(tmp2, "%d", TREE_INT_CST_LOW (TREE_VALUE (tail)));
  1302.         strcat (tmpbuf, tmp2);
  1303.         tail = TREE_CHAIN (tail);
  1304.         if (tail != 0)
  1305.           strcat (tmpbuf, ", ");
  1306.       }
  1307.       }
  1308.     /* Optional but useful - append the original name. */
  1309.     strcat (tmpbuf, "  ;  ");
  1310.     strcat (tmpbuf, name+1);  /* add one because of name mod */
  1311.     return tmpbuf;
  1312. }
  1313. #endif /* APPLE_C */
  1314.  
  1315. init_varasm()
  1316. {
  1317. #define INIT_VARASM
  1318. #include "init.c"
  1319. }
  1320.