OSDN Git Service

Thu Jul 7 16:58:35 1994 Jason Merrill (jason@deneb.cygnus.com)
[pf3gnuchains/gcc-fork.git] / gcc / varasm.c
1 /* Output variables, constants and external declarations, for GNU compiler.
2    Copyright (C) 1987, 88, 89, 92, 93, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 /* This file handles generation of all the assembler code
22    *except* the instructions of a function.
23    This includes declarations of variables and their initial values.
24
25    We also output the assembler code for constants stored in memory
26    and are responsible for combining constants with the same value.  */
27
28 #include <stdio.h>
29 #include <setjmp.h>
30 /* #include <stab.h> */
31 #include "config.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "flags.h"
35 #include "function.h"
36 #include "expr.h"
37 #include "hard-reg-set.h"
38 #include "regs.h"
39 #include "defaults.h"
40 #include "real.h"
41 #include "bytecode.h"
42
43 #include "obstack.h"
44
45 #ifdef XCOFF_DEBUGGING_INFO
46 #include "xcoffout.h"
47 #endif
48
49 #include <ctype.h>
50
51 #ifndef ASM_STABS_OP
52 #define ASM_STABS_OP ".stabs"
53 #endif
54
55 /* This macro gets just the user-specified name
56    out of the string in a SYMBOL_REF.  On most machines,
57    we discard the * if any and that's all.  */
58 #ifndef STRIP_NAME_ENCODING
59 #define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
60   (VAR) = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*'))
61 #endif
62
63 /* File in which assembler code is being written.  */
64
65 extern FILE *asm_out_file;
66
67 /* The (assembler) name of the first globally-visible object output.  */
68 char *first_global_object_name;
69
70 extern struct obstack *current_obstack;
71 extern struct obstack *saveable_obstack;
72 extern struct obstack permanent_obstack;
73 #define obstack_chunk_alloc xmalloc
74
75 /* Number for making the label on the next
76    constant that is stored in memory.  */
77
78 int const_labelno;
79
80 /* Number for making the label on the next
81    static variable internal to a function.  */
82
83 int var_labelno;
84
85 /* Carry information from ASM_DECLARE_OBJECT_NAME
86    to ASM_FINISH_DECLARE_OBJECT.  */
87
88 int size_directive_output;
89
90 /* The last decl for which assemble_variable was called,
91    if it did ASM_DECLARE_OBJECT_NAME.
92    If the last call to assemble_variable didn't do that,
93    this holds 0.  */
94
95 tree last_assemble_variable_decl;
96
97 /* Nonzero if at least one function definition has been seen.  */
98 static int function_defined;
99
100 extern FILE *asm_out_file;
101
102 static char *compare_constant_1 ();
103 static void record_constant_1 ();
104 static void output_constant_def_contents ();
105 static int contains_pointers_p ();
106 static void bc_output_ascii ();
107
108 void output_constant_pool ();
109 void assemble_name ();
110 int output_addressed_constants ();
111 void output_constant ();
112 void output_constructor ();
113 void output_byte_asm ();
114 void text_section ();
115 void readonly_data_section ();
116 void data_section ();
117 void named_section ();
118 static void bc_assemble_integer ();
119 \f
120 #ifdef EXTRA_SECTIONS
121 static enum in_section {no_section, in_text, in_data, in_named, EXTRA_SECTIONS} in_section
122   = no_section;
123 #else
124 static enum in_section {no_section, in_text, in_data, in_named} in_section
125   = no_section;
126 #endif
127
128 /* Return a non-zero value if DECL has a section attribute.  */
129 #define IN_NAMED_SECTION(DECL) \
130   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
131    && DECL_SECTION_NAME (DECL) != NULL_TREE)
132
133 /* Text of section name when in_section == in_named.  */
134 static char *in_named_name;
135
136 /* Define functions like text_section for any extra sections.  */
137 #ifdef EXTRA_SECTION_FUNCTIONS
138 EXTRA_SECTION_FUNCTIONS
139 #endif
140
141 /* Tell assembler to switch to text section.  */
142
143 void
144 text_section ()
145 {
146   if (in_section != in_text)
147     {
148       if (output_bytecode)
149         bc_text ();
150       else
151         fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
152
153       in_section = in_text;
154     }
155 }
156
157 /* Tell assembler to switch to data section.  */
158
159 void
160 data_section ()
161 {
162   if (in_section != in_data)
163     {
164       if (output_bytecode)
165         bc_data ();
166       else
167         {
168           if (flag_shared_data)
169             {
170 #ifdef SHARED_SECTION_ASM_OP
171               fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
172 #else
173               fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
174 #endif
175             }
176           else
177             fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
178         }
179
180       in_section = in_data;
181     }
182 }
183
184 /* Tell assembler to switch to read-only data section.  This is normally
185    the text section.  */
186
187 void
188 readonly_data_section ()
189 {
190 #ifdef READONLY_DATA_SECTION
191   READONLY_DATA_SECTION ();  /* Note this can call data_section.  */
192 #else
193   text_section ();
194 #endif
195 }
196
197 /* Determine if we're in the text section. */
198
199 int
200 in_text_section ()
201 {
202   return in_section == in_text;
203 }
204
205 /* Tell assembler to change to named section.  */
206
207 void
208 named_section (name)
209      char *name;
210 {
211   if (in_section != in_named || strcmp (name, in_named_name))
212     {
213       in_named_name = name;
214       in_section = in_named;
215     
216 #ifdef ASM_OUTPUT_SECTION_NAME
217       ASM_OUTPUT_SECTION_NAME (asm_out_file, name);
218 #else
219       /* Section attributes are not supported if this macro isn't provided -
220          some host formats don't support them at all.  The front-end should
221          already have flagged this as an error.  */
222       abort ();
223 #endif
224     }
225 }
226 \f
227 /* Create the rtl to represent a function, for a function definition.
228    DECL is a FUNCTION_DECL node which describes which function.
229    The rtl is stored into DECL.  */
230
231 void
232 make_function_rtl (decl)
233      tree decl;
234 {
235   char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
236
237   if (output_bytecode)
238     {
239       if (DECL_RTL (decl) == 0)
240         DECL_RTL (decl) = bc_gen_rtx (name, 0, (struct bc_label *) 0);
241       
242       /* Record that at least one function has been defined.  */
243       function_defined = 1;
244       return;
245     }
246
247   /* Rename a nested function to avoid conflicts.  */
248   if (decl_function_context (decl) != 0
249       && DECL_INITIAL (decl) != 0
250       && DECL_RTL (decl) == 0)
251     {
252       char *label;
253
254       name = IDENTIFIER_POINTER (DECL_NAME (decl));
255       ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
256       name = obstack_copy0 (saveable_obstack, label, strlen (label));
257       var_labelno++;
258     }
259
260   if (DECL_RTL (decl) == 0)
261     {
262       DECL_RTL (decl)
263         = gen_rtx (MEM, DECL_MODE (decl),
264                    gen_rtx (SYMBOL_REF, Pmode, name));
265
266       /* Optionally set flags or add text to the name to record information
267          such as that it is a function name.  If the name is changed, the macro
268          ASM_OUTPUT_LABELREF will have to know how to strip this information.  */
269 #ifdef ENCODE_SECTION_INFO
270       ENCODE_SECTION_INFO (decl);
271 #endif
272     }
273
274   /* Record at least one function has been defined.  */
275   function_defined = 1;
276 }
277
278 /* Create the DECL_RTL for a declaration for a static or external
279    variable or static or external function.
280    ASMSPEC, if not 0, is the string which the user specified
281    as the assembler symbol name.
282    TOP_LEVEL is nonzero if this is a file-scope variable.
283    This is never called for PARM_DECLs.  */
284 void
285 bc_make_decl_rtl (decl, asmspec, top_level)
286      tree decl;
287      char *asmspec;
288      int top_level;
289 {
290   register char *name = TREE_STRING_POINTER (DECL_ASSEMBLER_NAME (decl));
291
292   if (DECL_RTL (decl) == 0)
293     {
294       /* Print an error message for register variables.  */
295       if (DECL_REGISTER (decl) && TREE_CODE (decl) == FUNCTION_DECL)
296         error ("function declared `register'");
297       else if (DECL_REGISTER (decl))
298         error ("global register variables not supported in the interpreter");
299
300       /* Handle ordinary static variables and functions.  */
301       if (DECL_RTL (decl) == 0)
302         {
303           /* Can't use just the variable's own name for a variable
304              whose scope is less than the whole file.
305              Concatenate a distinguishing number.  */
306           if (!top_level && !DECL_EXTERNAL (decl) && asmspec == 0)
307             {
308               char *label;
309
310               ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
311               name = obstack_copy0 (saveable_obstack, label, strlen (label));
312               var_labelno++;
313             }
314
315           DECL_RTL (decl) = bc_gen_rtx (name, 0, (struct bc_label *) 0);
316         }
317     }
318 }
319
320 /* Given NAME, a putative register name, discard any customary prefixes.  */
321
322 static char *
323 strip_reg_name (name)
324      char *name;
325 {
326 #ifdef REGISTER_PREFIX
327   if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
328     name += strlen (REGISTER_PREFIX);
329 #endif
330   if (name[0] == '%' || name[0] == '#')
331     name++;
332   return name;
333 }
334 \f
335 /* Decode an `asm' spec for a declaration as a register name.
336    Return the register number, or -1 if nothing specified,
337    or -2 if the ASMSPEC is not `cc' or `memory' and is not recognized,
338    or -3 if ASMSPEC is `cc' and is not recognized,
339    or -4 if ASMSPEC is `memory' and is not recognized.
340    Accept an exact spelling or a decimal number.
341    Prefixes such as % are optional.  */
342
343 int
344 decode_reg_name (asmspec)
345      char *asmspec;
346 {
347   if (asmspec != 0)
348     {
349       int i;
350
351       /* Get rid of confusing prefixes.  */
352       asmspec = strip_reg_name (asmspec);
353         
354       /* Allow a decimal number as a "register name".  */
355       for (i = strlen (asmspec) - 1; i >= 0; i--)
356         if (! (asmspec[i] >= '0' && asmspec[i] <= '9'))
357           break;
358       if (asmspec[0] != 0 && i < 0)
359         {
360           i = atoi (asmspec);
361           if (i < FIRST_PSEUDO_REGISTER && i >= 0)
362             return i;
363           else
364             return -2;
365         }
366
367       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
368         if (reg_names[i][0]
369             && ! strcmp (asmspec, strip_reg_name (reg_names[i])))
370           return i;
371
372 #ifdef ADDITIONAL_REGISTER_NAMES
373       {
374         static struct { char *name; int number; } table[]
375           = ADDITIONAL_REGISTER_NAMES;
376
377         for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
378           if (! strcmp (asmspec, table[i].name))
379             return table[i].number;
380       }
381 #endif /* ADDITIONAL_REGISTER_NAMES */
382
383       if (!strcmp (asmspec, "memory"))
384         return -4;
385
386       if (!strcmp (asmspec, "cc"))
387         return -3;
388
389       return -2;
390     }
391
392   return -1;
393 }
394 \f
395 /* Create the DECL_RTL for a declaration for a static or external variable
396    or static or external function.
397    ASMSPEC, if not 0, is the string which the user specified
398    as the assembler symbol name.
399    TOP_LEVEL is nonzero if this is a file-scope variable.
400
401    This is never called for PARM_DECL nodes.  */
402
403 void
404 make_decl_rtl (decl, asmspec, top_level)
405      tree decl;
406      char *asmspec;
407      int top_level;
408 {
409   register char *name = 0;
410   int reg_number;
411
412   if (output_bytecode)
413     {
414       bc_make_decl_rtl (decl, asmspec, top_level);
415       return;
416     }
417
418   reg_number = decode_reg_name (asmspec);
419
420   if (DECL_ASSEMBLER_NAME (decl) != NULL_TREE)
421     name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
422
423   if (reg_number == -2)
424     {
425       /* ASMSPEC is given, and not the name of a register.  */
426       name = (char *) obstack_alloc (saveable_obstack,
427                                      strlen (asmspec) + 2);
428       name[0] = '*';
429       strcpy (&name[1], asmspec);
430     }
431
432   /* For a duplicate declaration, we can be called twice on the
433      same DECL node.  Don't discard the RTL already made.  */
434   if (DECL_RTL (decl) == 0)
435     {
436       DECL_RTL (decl) = 0;
437
438       /* First detect errors in declaring global registers.  */
439       if (DECL_REGISTER (decl) && reg_number == -1)
440         error_with_decl (decl,
441                          "register name not specified for `%s'");
442       else if (DECL_REGISTER (decl) && reg_number < 0)
443         error_with_decl (decl,
444                          "invalid register name for `%s'");
445       else if ((reg_number >= 0 || reg_number == -3) && ! DECL_REGISTER (decl))
446         error_with_decl (decl,
447                          "register name given for non-register variable `%s'");
448       else if (DECL_REGISTER (decl) && TREE_CODE (decl) == FUNCTION_DECL)
449         error ("function declared `register'");
450       else if (DECL_REGISTER (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
451         error_with_decl (decl, "data type of `%s' isn't suitable for a register");
452       else if (DECL_REGISTER (decl)
453                && ! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
454         error_with_decl (decl, "register number for `%s' isn't suitable for the data type");
455       /* Now handle properly declared static register variables.  */
456       else if (DECL_REGISTER (decl))
457         {
458           int nregs;
459 #if 0 /* yylex should print the warning for this */
460           if (pedantic)
461             pedwarn ("ANSI C forbids global register variables");
462 #endif
463           if (DECL_INITIAL (decl) != 0 && top_level)
464             {
465               DECL_INITIAL (decl) = 0;
466               error ("global register variable has initial value");
467             }
468           if (fixed_regs[reg_number] == 0
469               && function_defined && top_level)
470             error ("global register variable follows a function definition");
471           if (TREE_THIS_VOLATILE (decl))
472             warning ("volatile register variables don't work as you might wish");
473
474           /* If the user specified one of the eliminables registers here,
475              e.g., FRAME_POINTER_REGNUM, we don't want to get this variable
476              confused with that register and be eliminated.  Although this
477              usage is somewhat suspect, we nevertheless use the following
478              kludge to avoid setting DECL_RTL to frame_pointer_rtx.  */
479
480           DECL_RTL (decl)
481             = gen_rtx (REG, DECL_MODE (decl), FIRST_PSEUDO_REGISTER);
482           REGNO (DECL_RTL (decl)) = reg_number;
483           REG_USERVAR_P (DECL_RTL (decl)) = 1;
484
485           if (top_level)
486             {
487               /* Make this register global, so not usable for anything
488                  else.  */
489               nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
490               while (nregs > 0)
491                 globalize_reg (reg_number + --nregs);
492             }
493         }
494       /* Specifying a section attribute on an uninitialized variable does not
495          (and cannot) cause it to be put in the given section.  The linker
496          can only put initialized objects in specific sections, everything
497          else goes in bss for the linker to sort out later (otherwise the
498          linker would give a duplicate definition error for each compilation
499          unit that behaved thusly).  So warn the user.  */
500       else if (TREE_CODE (decl) == VAR_DECL
501                && DECL_SECTION_NAME (decl) != NULL_TREE
502                && DECL_INITIAL (decl) == NULL_TREE)
503         {
504           warning_with_decl (decl,
505                              "section attribute ignored for uninitialized variable `%s'");
506           /* Remove the section name so subsequent declarations won't see it.
507              We are ignoring it, remember.  */
508           DECL_SECTION_NAME (decl) = NULL_TREE;
509         }
510
511       /* Now handle ordinary static variables and functions (in memory).
512          Also handle vars declared register invalidly.  */
513       if (DECL_RTL (decl) == 0)
514         {
515           /* Can't use just the variable's own name for a variable
516              whose scope is less than the whole file.
517              Concatenate a distinguishing number.  */
518           if (!top_level && !DECL_EXTERNAL (decl) && asmspec == 0)
519             {
520               char *label;
521
522               ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
523               name = obstack_copy0 (saveable_obstack, label, strlen (label));
524               var_labelno++;
525             }
526
527           if (name == 0)
528             abort ();
529
530           DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl),
531                                      gen_rtx (SYMBOL_REF, Pmode, name));
532
533           /* If this variable is to be treated as volatile, show its
534              tree node has side effects.  If it has side effects, either
535              because of this test or from TREE_THIS_VOLATILE also
536              being set, show the MEM is volatile.  */
537           if (flag_volatile_global && TREE_CODE (decl) == VAR_DECL
538               && TREE_PUBLIC (decl))
539             TREE_SIDE_EFFECTS (decl) = 1;
540           if (TREE_SIDE_EFFECTS (decl))
541             MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
542
543           if (TREE_READONLY (decl))
544             RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
545           MEM_IN_STRUCT_P (DECL_RTL (decl))
546             = AGGREGATE_TYPE_P (TREE_TYPE (decl));
547
548           /* Optionally set flags or add text to the name to record information
549              such as that it is a function name.
550              If the name is changed, the macro ASM_OUTPUT_LABELREF
551              will have to know how to strip this information.  */
552 #ifdef ENCODE_SECTION_INFO
553           ENCODE_SECTION_INFO (decl);
554 #endif
555         }
556     }
557   /* If the old RTL had the wrong mode, fix the mode.  */
558   else if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
559     {
560       rtx rtl = DECL_RTL (decl);
561       PUT_MODE (rtl, DECL_MODE (decl));
562     }
563 }
564
565 /* Make the rtl for variable VAR be volatile.
566    Use this only for static variables.  */
567
568 void
569 make_var_volatile (var)
570      tree var;
571 {
572   if (GET_CODE (DECL_RTL (var)) != MEM)
573     abort ();
574
575   MEM_VOLATILE_P (DECL_RTL (var)) = 1;
576 }
577 \f
578 /* Output alignment directive to align for constant expression EXP.  */
579
580 void
581 assemble_constant_align (exp)
582      tree exp;
583 {
584   int align;
585
586   /* Align the location counter as required by EXP's data type.  */
587   align = TYPE_ALIGN (TREE_TYPE (exp));
588 #ifdef CONSTANT_ALIGNMENT
589   align = CONSTANT_ALIGNMENT (exp, align);
590 #endif
591
592   if (align > BITS_PER_UNIT)
593     ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
594 }
595
596 /* Output a string of literal assembler code
597    for an `asm' keyword used between functions.  */
598
599 void
600 assemble_asm (string)
601      tree string;
602 {
603   if (output_bytecode)
604     {
605       error ("asm statements not allowed in interpreter");
606       return;
607     }
608
609   app_enable ();
610
611   if (TREE_CODE (string) == ADDR_EXPR)
612     string = TREE_OPERAND (string, 0);
613
614   fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));
615 }
616
617 #if 0 /* This should no longer be needed, because
618          flag_gnu_linker should be 0 on these systems,
619          which should prevent any output
620          if ASM_OUTPUT_CONSTRUCTOR and ASM_OUTPUT_DESTRUCTOR are absent.  */
621 #if !(defined(DBX_DEBUGGING_INFO) && !defined(FASCIST_ASSEMBLER))
622 #ifndef ASM_OUTPUT_CONSTRUCTOR
623 #define ASM_OUTPUT_CONSTRUCTOR(file, name)
624 #endif
625 #ifndef ASM_OUTPUT_DESTRUCTOR
626 #define ASM_OUTPUT_DESTRUCTOR(file, name)
627 #endif
628 #endif
629 #endif /* 0 */
630
631 /* Record an element in the table of global destructors.
632    How this is done depends on what sort of assembler and linker
633    are in use.
634
635    NAME should be the name of a global function to be called
636    at exit time.  This name is output using assemble_name.  */
637
638 void
639 assemble_destructor (name)
640      char *name;
641 {
642 #ifdef ASM_OUTPUT_DESTRUCTOR
643   ASM_OUTPUT_DESTRUCTOR (asm_out_file, name);
644 #else
645   if (flag_gnu_linker)
646     {
647       /* Now tell GNU LD that this is part of the static destructor set.  */
648       /* This code works for any machine provided you use GNU as/ld.  */
649       fprintf (asm_out_file, "%s \"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP);
650       assemble_name (asm_out_file, name);
651       fputc ('\n', asm_out_file);
652     }
653 #endif
654 }
655
656 /* Likewise for global constructors.  */
657
658 void
659 assemble_constructor (name)
660      char *name;
661 {
662 #ifdef ASM_OUTPUT_CONSTRUCTOR
663   ASM_OUTPUT_CONSTRUCTOR (asm_out_file, name);
664 #else
665   if (flag_gnu_linker)
666     {
667       /* Now tell GNU LD that this is part of the static constructor set.  */
668       /* This code works for any machine provided you use GNU as/ld.  */
669       fprintf (asm_out_file, "%s \"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP);
670       assemble_name (asm_out_file, name);
671       fputc ('\n', asm_out_file);
672     }
673 #endif
674 }
675
676 /* Likewise for entries we want to record for garbage collection.
677    Garbage collection is still under development.  */
678
679 void
680 assemble_gc_entry (name)
681      char *name;
682 {
683 #ifdef ASM_OUTPUT_GC_ENTRY
684   ASM_OUTPUT_GC_ENTRY (asm_out_file, name);
685 #else
686   if (flag_gnu_linker)
687     {
688       /* Now tell GNU LD that this is part of the static constructor set.  */
689       fprintf (asm_out_file, "%s \"___PTR_LIST__\",22,0,0,", ASM_STABS_OP);
690       assemble_name (asm_out_file, name);
691       fputc ('\n', asm_out_file);
692     }
693 #endif
694 }
695 \f
696 /* Output assembler code for the constant pool of a function and associated
697    with defining the name of the function.  DECL describes the function.
698    NAME is the function's name.  For the constant pool, we use the current
699    constant pool data.  */
700
701 void
702 assemble_start_function (decl, fnname)
703      tree decl;
704      char *fnname;
705 {
706   int align;
707
708   /* The following code does not need preprocessing in the assembler.  */
709
710   app_disable ();
711
712   output_constant_pool (fnname, decl);
713
714   if (IN_NAMED_SECTION (decl))
715     named_section (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)));
716   else
717     text_section ();
718
719   /* Tell assembler to move to target machine's alignment for functions.  */
720   align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
721   if (align > 0)
722     {
723       if (output_bytecode)
724         BC_OUTPUT_ALIGN (asm_out_file, align);
725       else
726         ASM_OUTPUT_ALIGN (asm_out_file, align);
727     }
728
729 #ifdef ASM_OUTPUT_FUNCTION_PREFIX
730   ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
731 #endif
732
733 #ifdef SDB_DEBUGGING_INFO
734   /* Output SDB definition of the function.  */
735   if (write_symbols == SDB_DEBUG)
736     sdbout_mark_begin_function ();
737 #endif
738
739 #ifdef DBX_DEBUGGING_INFO
740   /* Output DBX definition of the function.  */
741   if (write_symbols == DBX_DEBUG)
742     dbxout_begin_function (decl);
743 #endif
744
745   /* Make function name accessible from other files, if appropriate.  */
746
747   if (TREE_PUBLIC (decl))
748     {
749       if (!first_global_object_name)
750         STRIP_NAME_ENCODING (first_global_object_name, fnname);
751       if (output_bytecode)
752         BC_GLOBALIZE_LABEL (asm_out_file, fnname);
753       else
754         ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
755     }
756
757   /* Do any machine/system dependent processing of the function name */
758 #ifdef ASM_DECLARE_FUNCTION_NAME
759   ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
760 #else
761   /* Standard thing is just output label for the function.  */
762   if (output_bytecode)
763     BC_OUTPUT_LABEL (asm_out_file, fnname);
764   else
765     ASM_OUTPUT_LABEL (asm_out_file, fnname);
766 #endif /* ASM_DECLARE_FUNCTION_NAME */
767 }
768
769 /* Output assembler code associated with defining the size of the
770    function.  DECL describes the function.  NAME is the function's name.  */
771
772 void
773 assemble_end_function (decl, fnname)
774      tree decl;
775      char *fnname;
776 {
777 #ifdef ASM_DECLARE_FUNCTION_SIZE
778   ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl);
779 #endif
780 }
781 \f
782 /* Assemble code to leave SIZE bytes of zeros.  */
783
784 void
785 assemble_zeros (size)
786      int size;
787 {
788   if (output_bytecode)
789     {
790       bc_emit_const_skip (size);
791       return;
792     }
793
794 #ifdef ASM_NO_SKIP_IN_TEXT
795   /* The `space' pseudo in the text section outputs nop insns rather than 0s,
796      so we must output 0s explicitly in the text section.  */
797   if (ASM_NO_SKIP_IN_TEXT && in_text_section ())
798     {
799       int i;
800
801       for (i = 0; i < size - 20; i += 20)
802         {
803 #ifdef ASM_BYTE_OP
804           fprintf (asm_out_file,
805                    "%s 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n", ASM_BYTE_OP);
806 #else
807           fprintf (asm_out_file,
808                    "\tbyte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n");
809 #endif
810         }
811       if (i < size)
812         {
813 #ifdef ASM_BYTE_OP
814           fprintf (asm_out_file, "%s 0", ASM_BYTE_OP);
815 #else
816           fprintf (asm_out_file, "\tbyte 0");
817 #endif
818           i++;
819           for (; i < size; i++)
820             fprintf (asm_out_file, ",0");
821           fprintf (asm_out_file, "\n");
822         }
823     }
824   else
825 #endif
826     if (size > 0)
827       {
828         if (output_bytecode)
829           BC_OUTPUT_SKIP (asm_out_file, size);
830         else
831           ASM_OUTPUT_SKIP (asm_out_file, size);
832       }
833 }
834
835 /* Assemble an alignment pseudo op for an ALIGN-bit boundary.  */
836
837 void
838 assemble_align (align)
839      int align;
840 {
841   if (align > BITS_PER_UNIT)
842     ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
843 }
844
845 /* Assemble a string constant with the specified C string as contents.  */
846
847 void
848 assemble_string (p, size)
849      char *p;
850      int size;
851 {
852   register int i;
853   int pos = 0;
854   int maximum = 2000;
855
856   if (output_bytecode)
857     {
858       bc_emit (p, size);
859       return;
860     }
861
862   /* If the string is very long, split it up.  */
863
864   while (pos < size)
865     {
866       int thissize = size - pos;
867       if (thissize > maximum)
868         thissize = maximum;
869
870       if (output_bytecode)
871         bc_output_ascii (asm_out_file, p, thissize);
872       else
873         {
874           ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
875         }
876
877       pos += thissize;
878       p += thissize;
879     }
880 }
881
882 static void
883 bc_output_ascii (file, p, size)
884      FILE *file;
885      char *p;
886      int size;
887 {
888   BC_OUTPUT_ASCII (file, p, size);
889 }
890 \f
891 /* Assemble everything that is needed for a variable or function declaration.
892    Not used for automatic variables, and not used for function definitions.
893    Should not be called for variables of incomplete structure type.
894
895    TOP_LEVEL is nonzero if this variable has file scope.
896    AT_END is nonzero if this is the special handling, at end of compilation,
897    to define things that have had only tentative definitions.
898    DONT_OUTPUT_DATA if nonzero means don't actually output the
899    initial value (that will be done by the caller).  */
900
901 void
902 assemble_variable (decl, top_level, at_end, dont_output_data)
903      tree decl;
904      int top_level;
905      int at_end;
906 {
907   register char *name;
908   int align;
909   tree size_tree;
910   int reloc = 0;
911   enum in_section saved_in_section;
912
913   last_assemble_variable_decl = 0;
914
915   if (output_bytecode)
916     return;
917
918   if (GET_CODE (DECL_RTL (decl)) == REG)
919     {
920       /* Do output symbol info for global register variables, but do nothing
921          else for them.  */
922
923       if (TREE_ASM_WRITTEN (decl))
924         return;
925       TREE_ASM_WRITTEN (decl) = 1;
926
927       if (!output_bytecode)
928         {
929 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
930           /* File-scope global variables are output here.  */
931           if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
932               && top_level)
933             dbxout_symbol (decl, 0);
934 #endif
935 #ifdef SDB_DEBUGGING_INFO
936           if (write_symbols == SDB_DEBUG && top_level
937               /* Leave initialized global vars for end of compilation;
938                  see comment in compile_file.  */
939               && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
940             sdbout_symbol (decl, 0);
941 #endif
942         }
943
944       /* Don't output any DWARF debugging information for variables here.
945          In the case of local variables, the information for them is output
946          when we do our recursive traversal of the tree representation for
947          the entire containing function.  In the case of file-scope variables,
948          we output information for all of them at the very end of compilation
949          while we are doing our final traversal of the chain of file-scope
950          declarations.  */
951
952       return;
953     }
954
955   /* Normally no need to say anything here for external references,
956      since assemble_external is called by the langauge-specific code
957      when a declaration is first seen.  */
958
959   if (DECL_EXTERNAL (decl))
960     return;
961
962   /* Output no assembler code for a function declaration.
963      Only definitions of functions output anything.  */
964
965   if (TREE_CODE (decl) == FUNCTION_DECL)
966     return;
967
968   /* If type was incomplete when the variable was declared,
969      see if it is complete now.  */
970
971   if (DECL_SIZE (decl) == 0)
972     layout_decl (decl, 0);
973
974   /* Still incomplete => don't allocate it; treat the tentative defn
975      (which is what it must have been) as an `extern' reference.  */
976
977   if (!dont_output_data && DECL_SIZE (decl) == 0)
978     {
979       error_with_file_and_line (DECL_SOURCE_FILE (decl),
980                                 DECL_SOURCE_LINE (decl),
981                                 "storage size of `%s' isn't known",
982                                 IDENTIFIER_POINTER (DECL_NAME (decl)));
983       TREE_ASM_WRITTEN (decl) = 1;
984       return;
985     }
986
987   /* The first declaration of a variable that comes through this function
988      decides whether it is global (in C, has external linkage)
989      or local (in C, has internal linkage).  So do nothing more
990      if this function has already run.  */
991
992   if (TREE_ASM_WRITTEN (decl))
993     return;
994
995   TREE_ASM_WRITTEN (decl) = 1;
996
997   /* If storage size is erroneously variable, just continue.
998      Error message was already made.  */
999
1000   if (DECL_SIZE (decl))
1001     {
1002       if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1003         goto finish;
1004
1005       app_disable ();
1006
1007       /* This is better than explicit arithmetic, since it avoids overflow.  */
1008       size_tree = size_binop (CEIL_DIV_EXPR,
1009                               DECL_SIZE (decl), size_int (BITS_PER_UNIT));
1010
1011       if (TREE_INT_CST_HIGH (size_tree) != 0)
1012         {
1013           error_with_decl (decl, "size of variable `%s' is too large");
1014           goto finish;
1015         }
1016     }
1017
1018   name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
1019
1020   /* Handle uninitialized definitions.  */
1021
1022   /* ANSI specifies that a tentative definition which is not merged with
1023      a non-tentative definition behaves exactly like a definition with an
1024      initializer equal to zero.  (Section 3.7.2)
1025      -fno-common gives strict ANSI behavior.  Usually you don't want it.
1026      This matters only for variables with external linkage.  */
1027   if ((! flag_no_common || ! TREE_PUBLIC (decl))
1028       && DECL_COMMON (decl)
1029       && ! dont_output_data
1030       && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
1031     {
1032       int size = TREE_INT_CST_LOW (size_tree);
1033       int rounded = size;
1034
1035       if (TREE_INT_CST_HIGH (size_tree) != 0)
1036         error_with_decl (decl, "size of variable `%s' is too large");
1037       /* Don't allocate zero bytes of common,
1038          since that means "undefined external" in the linker.  */
1039       if (size == 0) rounded = 1;
1040       /* Round size up to multiple of BIGGEST_ALIGNMENT bits
1041          so that each uninitialized object starts on such a boundary.  */
1042       rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
1043       rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1044                  * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
1045
1046 #ifdef DBX_DEBUGGING_INFO
1047       /* File-scope global variables are output here.  */
1048       if (write_symbols == DBX_DEBUG && top_level)
1049         dbxout_symbol (decl, 0);
1050 #endif
1051 #ifdef SDB_DEBUGGING_INFO
1052       if (write_symbols == SDB_DEBUG && top_level
1053           /* Leave initialized global vars for end of compilation;
1054              see comment in compile_file.  */
1055           && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
1056         sdbout_symbol (decl, 0);
1057 #endif
1058
1059       /* Don't output any DWARF debugging information for variables here.
1060          In the case of local variables, the information for them is output
1061          when we do our recursive traversal of the tree representation for
1062          the entire containing function.  In the case of file-scope variables,
1063          we output information for all of them at the very end of compilation
1064          while we are doing our final traversal of the chain of file-scope
1065          declarations.  */
1066
1067 #if 0
1068       if (flag_shared_data)
1069         data_section ();
1070 #endif
1071       if (TREE_PUBLIC (decl))
1072         {
1073 #ifdef ASM_OUTPUT_SHARED_COMMON
1074           if (flag_shared_data)
1075             ASM_OUTPUT_SHARED_COMMON (asm_out_file, name, size, rounded);
1076           else
1077 #endif
1078             if (output_bytecode)
1079               {
1080                 BC_OUTPUT_COMMON (asm_out_file, name, size, rounded);
1081               }
1082             else
1083               {
1084 #ifdef ASM_OUTPUT_ALIGNED_COMMON
1085                 ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
1086                                            DECL_ALIGN (decl));
1087 #else
1088                 ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
1089 #endif
1090               }
1091         }
1092       else
1093         {
1094 #ifdef ASM_OUTPUT_SHARED_LOCAL
1095           if (flag_shared_data)
1096             ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
1097           else
1098 #endif
1099             if (output_bytecode)
1100               {
1101                 BC_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1102               }
1103             else
1104               {
1105 #ifdef ASM_OUTPUT_ALIGNED_LOCAL
1106                 ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
1107                                           DECL_ALIGN (decl));
1108 #else
1109                 ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1110 #endif
1111               }
1112         }
1113       goto finish;
1114     }
1115
1116   /* Handle initialized definitions.  */
1117
1118   /* First make the assembler name(s) global if appropriate.  */
1119   if (TREE_PUBLIC (decl) && DECL_NAME (decl))
1120     {
1121       if (!first_global_object_name)
1122         STRIP_NAME_ENCODING(first_global_object_name, name);
1123       ASM_GLOBALIZE_LABEL (asm_out_file, name);
1124     }
1125 #if 0
1126   for (d = equivalents; d; d = TREE_CHAIN (d))
1127     {
1128       tree e = TREE_VALUE (d);
1129       if (TREE_PUBLIC (e) && DECL_NAME (e))
1130         ASM_GLOBALIZE_LABEL (asm_out_file,
1131                              XSTR (XEXP (DECL_RTL (e), 0), 0));
1132     }
1133 #endif
1134
1135   /* Output any data that we will need to use the address of.  */
1136   if (DECL_INITIAL (decl) == error_mark_node)
1137     reloc = contains_pointers_p (TREE_TYPE (decl));
1138   else if (DECL_INITIAL (decl))
1139     reloc = output_addressed_constants (DECL_INITIAL (decl));
1140
1141   /* Switch to the proper section for this data.  */
1142   if (IN_NAMED_SECTION (decl))
1143     named_section (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)));
1144   else
1145     {
1146       /* C++ can have const variables that get initialized from constructors,
1147          and thus can not be in a readonly section.  We prevent this by
1148          verifying that the initial value is constant for objects put in a
1149          readonly section.
1150
1151          error_mark_node is used by the C front end to indicate that the
1152          initializer has not been seen yet.  In this case, we assume that
1153          the initializer must be constant.  */
1154 #ifdef SELECT_SECTION
1155       SELECT_SECTION (decl, reloc);
1156 #else
1157       if (TREE_READONLY (decl)
1158           && ! TREE_THIS_VOLATILE (decl)
1159           && DECL_INITIAL (decl)
1160           && (DECL_INITIAL (decl) == error_mark_node
1161               || TREE_CONSTANT (DECL_INITIAL (decl)))
1162           && ! (flag_pic && reloc))
1163         readonly_data_section ();
1164       else
1165         data_section ();
1166 #endif
1167     }
1168
1169   /* dbxout.c needs to know this.  */
1170   if (in_text_section ())
1171     DECL_IN_TEXT_SECTION (decl) = 1;
1172
1173   /* Record current section so we can restore it if dbxout.c clobbers it.  */
1174   saved_in_section = in_section;
1175
1176   /* Output the dbx info now that we have chosen the section.  */
1177
1178 #ifdef DBX_DEBUGGING_INFO
1179   /* File-scope global variables are output here.  */
1180   if (write_symbols == DBX_DEBUG && top_level)
1181     dbxout_symbol (decl, 0);
1182 #endif
1183 #ifdef SDB_DEBUGGING_INFO
1184   if (write_symbols == SDB_DEBUG && top_level
1185       /* Leave initialized global vars for end of compilation;
1186          see comment in compile_file.  */
1187       && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
1188     sdbout_symbol (decl, 0);
1189 #endif
1190
1191   /* Don't output any DWARF debugging information for variables here.
1192      In the case of local variables, the information for them is output
1193      when we do our recursive traversal of the tree representation for
1194      the entire containing function.  In the case of file-scope variables,
1195      we output information for all of them at the very end of compilation
1196      while we are doing our final traversal of the chain of file-scope
1197      declarations.  */
1198
1199   /* If the debugging output changed sections, reselect the section
1200      that's supposed to be selected.  */
1201   if (in_section != saved_in_section)
1202     {
1203       /* Switch to the proper section for this data.  */
1204 #ifdef SELECT_SECTION
1205       SELECT_SECTION (decl, reloc);
1206 #else
1207       if (TREE_READONLY (decl)
1208           && ! TREE_THIS_VOLATILE (decl)
1209           && DECL_INITIAL (decl)
1210           && (DECL_INITIAL (decl) == error_mark_node
1211               || TREE_CONSTANT (DECL_INITIAL (decl)))
1212           && ! (flag_pic && reloc))
1213         readonly_data_section ();
1214       else
1215         data_section ();
1216 #endif
1217     }
1218
1219   /* Compute and output the alignment of this data.  */
1220
1221   align = DECL_ALIGN (decl);
1222   /* In the case for initialing an array whose length isn't specified,
1223      where we have not yet been able to do the layout,
1224      figure out the proper alignment now.  */
1225   if (dont_output_data && DECL_SIZE (decl) == 0
1226       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1227     align = MAX (align, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
1228
1229   /* Some object file formats have a maximum alignment which they support.
1230      In particular, a.out format supports a maximum alignment of 4.  */
1231 #ifndef MAX_OFILE_ALIGNMENT
1232 #define MAX_OFILE_ALIGNMENT BIGGEST_ALIGNMENT
1233 #endif
1234   if (align > MAX_OFILE_ALIGNMENT)
1235     {
1236       warning_with_decl (decl,
1237           "alignment of `%s' is greater than maximum object file alignment");
1238       align = MAX_OFILE_ALIGNMENT;
1239     }
1240 #ifdef DATA_ALIGNMENT
1241   /* On some machines, it is good to increase alignment sometimes.  */
1242   align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
1243 #endif
1244 #ifdef CONSTANT_ALIGNMENT
1245   if (DECL_INITIAL (decl))
1246     align = CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align);
1247 #endif
1248
1249   /* Reset the alignment in case we have made it tighter, so we can benefit
1250      from it in get_pointer_alignment.  */
1251   DECL_ALIGN (decl) = align;
1252
1253   if (align > BITS_PER_UNIT)
1254     {
1255       if (output_bytecode)
1256         BC_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
1257       else
1258         ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
1259     }
1260
1261   /* Do any machine/system dependent processing of the object.  */
1262 #ifdef ASM_DECLARE_OBJECT_NAME
1263   last_assemble_variable_decl = decl;
1264   ASM_DECLARE_OBJECT_NAME (asm_out_file, name, decl);
1265 #else
1266   /* Standard thing is just output label for the object.  */
1267   if (output_bytecode)
1268     BC_OUTPUT_LABEL (asm_out_file, name);
1269   else
1270     ASM_OUTPUT_LABEL (asm_out_file, name);
1271 #endif /* ASM_DECLARE_OBJECT_NAME */
1272
1273   if (!dont_output_data)
1274     {
1275       if (DECL_INITIAL (decl))
1276         /* Output the actual data.  */
1277         output_constant (DECL_INITIAL (decl),
1278                          int_size_in_bytes (TREE_TYPE (decl)));
1279       else
1280         /* Leave space for it.  */
1281         assemble_zeros (int_size_in_bytes (TREE_TYPE (decl)));
1282     }
1283
1284  finish:
1285 #ifdef XCOFF_DEBUGGING_INFO
1286   /* Unfortunately, the IBM assembler cannot handle stabx before the actual
1287      declaration.  When something like ".stabx  "aa:S-2",aa,133,0" is emitted 
1288      and `aa' hasn't been output yet, the assembler generates a stab entry with
1289      a value of zero, in addition to creating an unnecessary external entry
1290      for `aa'.  Hence, we must postpone dbxout_symbol to here at the end.  */
1291
1292   /* File-scope global variables are output here.  */
1293   if (write_symbols == XCOFF_DEBUG && top_level)
1294     {
1295       saved_in_section = in_section;
1296
1297       dbxout_symbol (decl, 0);
1298
1299       if (in_section != saved_in_section)
1300         {
1301           /* Switch to the proper section for this data.  */
1302 #ifdef SELECT_SECTION
1303           SELECT_SECTION (decl, reloc);
1304 #else
1305           if (TREE_READONLY (decl)
1306               && ! TREE_THIS_VOLATILE (decl)
1307               && DECL_INITIAL (decl)
1308               && (DECL_INITIAL (decl) == error_mark_node
1309                   || TREE_CONSTANT (DECL_INITIAL (decl)))
1310               && ! (flag_pic && reloc))
1311             readonly_data_section ();
1312           else
1313             data_section ();
1314 #endif
1315         }
1316     }
1317 #else
1318   /* There must be a statement after a label.  */
1319   ;
1320 #endif
1321 }
1322
1323 /* Return 1 if type TYPE contains any pointers.  */
1324
1325 static int
1326 contains_pointers_p (type)
1327      tree type;
1328 {
1329   switch (TREE_CODE (type))
1330     {
1331     case POINTER_TYPE:
1332     case REFERENCE_TYPE:
1333       /* I'm not sure whether OFFSET_TYPE needs this treatment,
1334          so I'll play safe and return 1.  */
1335     case OFFSET_TYPE:
1336       return 1;
1337
1338     case RECORD_TYPE:
1339     case UNION_TYPE:
1340     case QUAL_UNION_TYPE:
1341       {
1342         tree fields;
1343         /* For a type that has fields, see if the fields have pointers.  */
1344         for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
1345           if (TREE_CODE (fields) == FIELD_DECL
1346               && contains_pointers_p (TREE_TYPE (fields)))
1347             return 1;
1348         return 0;
1349       }
1350
1351     case ARRAY_TYPE:
1352       /* An array type contains pointers if its element type does.  */
1353       return contains_pointers_p (TREE_TYPE (type));
1354
1355     default:
1356       return 0;
1357     }
1358 }
1359
1360 /* Output text storage for constructor CONSTR.  Returns rtx of
1361    storage. */
1362
1363 rtx
1364 bc_output_constructor (constr)
1365   tree constr;
1366 {
1367   int i;
1368
1369   /* Must always be a literal; non-literal constructors are handled
1370      differently. */
1371
1372   if (!TREE_CONSTANT (constr))
1373     abort ();
1374
1375   /* Always const */
1376   text_section ();
1377
1378   /* Align */
1379   for (i = 0; TYPE_ALIGN (constr) >= BITS_PER_UNIT << (i + 1); i++);
1380   if (i > 0)
1381     BC_OUTPUT_ALIGN (asm_out_file, i);
1382
1383   /* Output data */
1384   output_constant (constr, int_size_in_bytes (TREE_TYPE (constr)));
1385 }
1386
1387
1388 /* Create storage for constructor CONSTR. */
1389
1390 void
1391 bc_output_data_constructor (constr)
1392     tree constr;
1393 {
1394   int i;
1395
1396   /* Put in data section */
1397   data_section ();
1398
1399   /* Align */
1400   for (i = 0; TYPE_ALIGN (constr) >= BITS_PER_UNIT << (i + 1); i++);
1401   if (i > 0)
1402     BC_OUTPUT_ALIGN (asm_out_file, i);
1403
1404   /* The constructor is filled in at runtime. */
1405   BC_OUTPUT_SKIP (asm_out_file, int_size_in_bytes (TREE_TYPE (constr)));
1406 }
1407
1408
1409 /* Output something to declare an external symbol to the assembler.
1410    (Most assemblers don't need this, so we normally output nothing.)
1411    Do nothing if DECL is not external.  */
1412
1413 void
1414 assemble_external (decl)
1415      tree decl;
1416 {
1417   if (output_bytecode)
1418     return;
1419
1420 #ifdef ASM_OUTPUT_EXTERNAL
1421   if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
1422       && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
1423     {
1424       rtx rtl = DECL_RTL (decl);
1425
1426       if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
1427           && ! SYMBOL_REF_USED (XEXP (rtl, 0)))
1428         {
1429           /* Some systems do require some output.  */
1430           SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
1431           ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
1432         }
1433     }
1434 #endif
1435 }
1436
1437 /* Similar, for calling a library function FUN.  */
1438
1439 void
1440 assemble_external_libcall (fun)
1441      rtx fun;
1442 {
1443 #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
1444   if (!output_bytecode)
1445     {
1446       /* Declare library function name external when first used, if nec.  */
1447       if (! SYMBOL_REF_USED (fun))
1448         {
1449           SYMBOL_REF_USED (fun) = 1;
1450           ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
1451         }
1452     }
1453 #endif
1454 }
1455
1456 /* Declare the label NAME global.  */
1457
1458 void
1459 assemble_global (name)
1460      char *name;
1461 {
1462   ASM_GLOBALIZE_LABEL (asm_out_file, name);
1463 }
1464
1465 /* Assemble a label named NAME.  */
1466
1467 void
1468 assemble_label (name)
1469      char *name;
1470 {
1471   if (output_bytecode)
1472     BC_OUTPUT_LABEL (asm_out_file, name);
1473   else
1474     ASM_OUTPUT_LABEL (asm_out_file, name);
1475 }
1476
1477 /* Output to FILE a reference to the assembler name of a C-level name NAME.
1478    If NAME starts with a *, the rest of NAME is output verbatim.
1479    Otherwise NAME is transformed in an implementation-defined way
1480    (usually by the addition of an underscore).
1481    Many macros in the tm file are defined to call this function.  */
1482
1483 void
1484 assemble_name (file, name)
1485      FILE *file;
1486      char *name;
1487 {
1488   char *real_name;
1489
1490   STRIP_NAME_ENCODING (real_name, name);
1491   TREE_SYMBOL_REFERENCED (get_identifier (real_name)) = 1;
1492
1493   if (name[0] == '*')
1494     {
1495       if (output_bytecode)
1496         bc_emit_labelref (name);
1497       else
1498         fputs (&name[1], file);
1499     }
1500   else
1501     {
1502       if (output_bytecode)
1503         BC_OUTPUT_LABELREF (file, name);
1504       else
1505         ASM_OUTPUT_LABELREF (file, name);
1506     }
1507 }
1508
1509 /* Allocate SIZE bytes writable static space with a gensym name
1510    and return an RTX to refer to its address.  */
1511
1512 rtx
1513 assemble_static_space (size)
1514      int size;
1515 {
1516   char name[12];
1517   char *namestring;
1518   rtx x;
1519   /* Round size up to multiple of BIGGEST_ALIGNMENT bits
1520      so that each uninitialized object starts on such a boundary.  */
1521   int rounded = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
1522                  / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
1523                  * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
1524
1525 #if 0
1526   if (flag_shared_data)
1527     data_section ();
1528 #endif
1529
1530   ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
1531   ++const_labelno;
1532
1533   namestring = (char *) obstack_alloc (saveable_obstack,
1534                                        strlen (name) + 2);
1535   strcpy (namestring, name);
1536
1537   if (output_bytecode)
1538     x = bc_gen_rtx (namestring, 0, (struct bc_label *) 0);
1539   else
1540     x = gen_rtx (SYMBOL_REF, Pmode, namestring);
1541
1542   if (output_bytecode)
1543     {
1544       BC_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1545     }
1546   else
1547     {
1548 #ifdef ASM_OUTPUT_ALIGNED_LOCAL
1549       ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT);
1550 #else
1551       ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
1552 #endif
1553     }
1554   return x;
1555 }
1556
1557 /* Assemble the static constant template for function entry trampolines.
1558    This is done at most once per compilation.
1559    Returns an RTX for the address of the template.  */
1560
1561 rtx
1562 assemble_trampoline_template ()
1563 {
1564   char label[256];
1565   char *name;
1566   int align;
1567
1568   /* Shouldn't get here */
1569   if (output_bytecode)
1570     abort ();
1571
1572   /* By default, put trampoline templates in read-only data section.  */
1573
1574 #ifdef TRAMPOLINE_SECTION
1575   TRAMPOLINE_SECTION ();
1576 #else
1577   readonly_data_section ();
1578 #endif
1579
1580   /* Write the assembler code to define one.  */
1581   align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
1582   if (align > 0)
1583     ASM_OUTPUT_ALIGN (asm_out_file, align);
1584
1585   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LTRAMP", 0);
1586   TRAMPOLINE_TEMPLATE (asm_out_file);
1587
1588   /* Record the rtl to refer to it.  */
1589   ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);
1590   name
1591     = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
1592   return gen_rtx (SYMBOL_REF, Pmode, name);
1593 }
1594 \f
1595 /* Assemble the integer constant X into an object of SIZE bytes.
1596    X must be either a CONST_INT or CONST_DOUBLE.
1597
1598    Return 1 if we were able to output the constant, otherwise 0.  If FORCE is
1599    non-zero, abort if we can't output the constant.  */
1600
1601 int
1602 assemble_integer (x, size, force)
1603      rtx x;
1604      int size;
1605      int force;
1606 {
1607   /* First try to use the standard 1, 2, 4, 8, and 16 byte
1608      ASM_OUTPUT... macros. */
1609
1610   switch (size)
1611     {
1612 #ifdef ASM_OUTPUT_CHAR
1613     case 1:
1614       ASM_OUTPUT_CHAR (asm_out_file, x);
1615       return 1;
1616 #endif
1617
1618 #ifdef ASM_OUTPUT_SHORT
1619     case 2:
1620       ASM_OUTPUT_SHORT (asm_out_file, x);
1621       return 1;
1622 #endif
1623
1624 #ifdef ASM_OUTPUT_INT
1625     case 4:
1626       ASM_OUTPUT_INT (asm_out_file, x);
1627       return 1;
1628 #endif
1629
1630 #ifdef ASM_OUTPUT_DOUBLE_INT
1631     case 8:
1632       ASM_OUTPUT_DOUBLE_INT (asm_out_file, x);
1633       return 1;
1634 #endif
1635
1636 #ifdef ASM_OUTPUT_QUADRUPLE_INT
1637     case 16:
1638       ASM_OUTPUT_QUADRUPLE_INT (asm_out_file, x);
1639       return 1;
1640 #endif
1641     }
1642
1643   /* If we couldn't do it that way, there are two other possibilities: First,
1644      if the machine can output an explicit byte and this is a 1 byte constant,
1645      we can use ASM_OUTPUT_BYTE.  */
1646
1647 #ifdef ASM_OUTPUT_BYTE
1648   if (size == 1 && GET_CODE (x) == CONST_INT)
1649     {
1650       ASM_OUTPUT_BYTE (asm_out_file, INTVAL (x));
1651       return 1;
1652     }
1653 #endif
1654
1655   /* Finally, if SIZE is larger than a single word, try to output the constant
1656      one word at a time.  */
1657
1658   if (size > UNITS_PER_WORD)
1659     {
1660       int i;
1661       enum machine_mode mode
1662         = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
1663       rtx word;
1664
1665       for (i = 0; i < size / UNITS_PER_WORD; i++)
1666         {
1667           word = operand_subword (x, i, 0, mode);
1668
1669           if (word == 0)
1670             break;
1671
1672           if (! assemble_integer (word, UNITS_PER_WORD, 0))
1673             break;
1674         }
1675
1676       if (i == size / UNITS_PER_WORD)
1677         return 1;
1678       /* If we output at least one word and then could not finish,
1679          there is no valid way to continue.  */
1680       if (i > 0)
1681         abort ();
1682     }
1683
1684   if (force)
1685     abort ();
1686
1687   return 0;
1688 }
1689 \f
1690 /* Assemble the floating-point constant D into an object of size MODE.  */
1691
1692 void
1693 assemble_real (d, mode)
1694      REAL_VALUE_TYPE d;
1695      enum machine_mode mode;
1696 {
1697   jmp_buf output_constant_handler;
1698
1699   if (setjmp (output_constant_handler))
1700     {
1701       error ("floating point trap outputting a constant");
1702 #ifdef REAL_IS_NOT_DOUBLE
1703       bzero ((char *) &d, sizeof d);
1704       d = dconst0;
1705 #else
1706       d = 0;
1707 #endif
1708     }
1709
1710   set_float_handler (output_constant_handler);
1711
1712   switch (mode)
1713     {
1714 #ifdef ASM_OUTPUT_BYTE_FLOAT
1715     case QFmode:
1716       ASM_OUTPUT_BYTE_FLOAT (asm_out_file, d);
1717       break;
1718 #endif
1719 #ifdef ASM_OUTPUT_SHORT_FLOAT
1720     case HFmode:
1721       ASM_OUTPUT_SHORT_FLOAT (asm_out_file, d);
1722       break;
1723 #endif
1724 #ifdef ASM_OUTPUT_FLOAT
1725     case SFmode:
1726       ASM_OUTPUT_FLOAT (asm_out_file, d);
1727       break;
1728 #endif
1729
1730 #ifdef ASM_OUTPUT_DOUBLE
1731     case DFmode:
1732       ASM_OUTPUT_DOUBLE (asm_out_file, d);
1733       break;
1734 #endif
1735
1736 #ifdef ASM_OUTPUT_LONG_DOUBLE
1737     case XFmode:
1738     case TFmode:
1739       ASM_OUTPUT_LONG_DOUBLE (asm_out_file, d);
1740       break;
1741 #endif
1742
1743     default:
1744       abort ();
1745     }
1746
1747   set_float_handler (NULL_PTR);
1748 }
1749 \f
1750 /* Here we combine duplicate floating constants to make
1751    CONST_DOUBLE rtx's, and force those out to memory when necessary.  */
1752
1753 /* Chain of all CONST_DOUBLE rtx's constructed for the current function.
1754    They are chained through the CONST_DOUBLE_CHAIN.
1755    A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
1756    In that case, CONST_DOUBLE_MEM is either a MEM,
1757    or const0_rtx if no MEM has been made for this CONST_DOUBLE yet.
1758
1759    (CONST_DOUBLE_MEM is used only for top-level functions.
1760    See force_const_mem for explanation.)  */
1761
1762 static rtx const_double_chain;
1763
1764 /* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair of ints.
1765    For an integer, I0 is the low-order word and I1 is the high-order word.
1766    For a real number, I0 is the word with the low address
1767    and I1 is the word with the high address.  */
1768
1769 rtx
1770 immed_double_const (i0, i1, mode)
1771      HOST_WIDE_INT i0, i1;
1772      enum machine_mode mode;
1773 {
1774   register rtx r;
1775   int in_current_obstack;
1776
1777   if (GET_MODE_CLASS (mode) == MODE_INT
1778       || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1779     {
1780       /* We clear out all bits that don't belong in MODE, unless they and our
1781          sign bit are all one.  So we get either a reasonable negative value
1782          or a reasonable unsigned value for this mode.  */
1783       int width = GET_MODE_BITSIZE (mode);
1784       if (width < HOST_BITS_PER_WIDE_INT
1785           && ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1)))
1786               != ((HOST_WIDE_INT) (-1) << (width - 1))))
1787         i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0;
1788       else if (width == HOST_BITS_PER_WIDE_INT
1789                && ! (i1 == ~0 && i0 < 0))
1790         i1 = 0;
1791       else if (width > 2 * HOST_BITS_PER_WIDE_INT)
1792         /* We cannot represent this value as a constant.  */
1793         abort ();
1794
1795       /* If this would be an entire word for the target, but is not for
1796          the host, then sign-extend on the host so that the number will look
1797          the same way on the host that it would on the target.
1798
1799          For example, when building a 64 bit alpha hosted 32 bit sparc
1800          targeted compiler, then we want the 32 bit unsigned value -1 to be
1801          represented as a 64 bit value -1, and not as 0x00000000ffffffff.
1802          The later confuses the sparc backend.  */
1803
1804       if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
1805           && (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
1806         i0 |= ((HOST_WIDE_INT) (-1) << width);
1807
1808       /* If MODE fits within HOST_BITS_PER_WIDE_INT, always use a CONST_INT.
1809
1810          ??? Strictly speaking, this is wrong if we create a CONST_INT
1811          for a large unsigned constant with the size of MODE being
1812          HOST_BITS_PER_WIDE_INT and later try to interpret that constant in a
1813          wider mode.  In that case we will mis-interpret it as a negative
1814          number.
1815
1816          Unfortunately, the only alternative is to make a CONST_DOUBLE
1817          for any constant in any mode if it is an unsigned constant larger
1818          than the maximum signed integer in an int on the host.  However,
1819          doing this will break everyone that always expects to see a CONST_INT
1820          for SImode and smaller.
1821
1822          We have always been making CONST_INTs in this case, so nothing new
1823          is being broken.  */
1824
1825       if (width <= HOST_BITS_PER_WIDE_INT)
1826         i1 = (i0 < 0) ? ~0 : 0;
1827
1828       /* If this integer fits in one word, return a CONST_INT.  */
1829       if ((i1 == 0 && i0 >= 0)
1830           || (i1 == ~0 && i0 < 0))
1831         return GEN_INT (i0);
1832
1833       /* We use VOIDmode for integers.  */
1834       mode = VOIDmode;
1835     }
1836
1837   /* Search the chain for an existing CONST_DOUBLE with the right value.
1838      If one is found, return it.  */
1839
1840   for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
1841     if (CONST_DOUBLE_LOW (r) == i0 && CONST_DOUBLE_HIGH (r) == i1
1842         && GET_MODE (r) == mode)
1843       return r;
1844
1845   /* No; make a new one and add it to the chain.
1846
1847      We may be called by an optimizer which may be discarding any memory
1848      allocated during its processing (such as combine and loop).  However,
1849      we will be leaving this constant on the chain, so we cannot tolerate
1850      freed memory.  So switch to saveable_obstack for this allocation
1851      and then switch back if we were in current_obstack.  */
1852
1853   push_obstacks_nochange ();
1854   rtl_in_saveable_obstack ();
1855   r = gen_rtx (CONST_DOUBLE, mode, 0, i0, i1);
1856   pop_obstacks ();
1857
1858   /* Don't touch const_double_chain in nested function; see force_const_mem.
1859      Also, don't touch it if not inside any function.  */
1860   if (outer_function_chain == 0 && current_function_decl != 0)
1861     {
1862       CONST_DOUBLE_CHAIN (r) = const_double_chain;
1863       const_double_chain = r;
1864     }
1865
1866   /* Store const0_rtx in mem-slot since this CONST_DOUBLE is on the chain.
1867      Actual use of mem-slot is only through force_const_mem.  */
1868
1869   CONST_DOUBLE_MEM (r) = const0_rtx;
1870
1871   return r;
1872 }
1873
1874 /* Return a CONST_DOUBLE for a specified `double' value
1875    and machine mode.  */
1876
1877 rtx
1878 immed_real_const_1 (d, mode)
1879      REAL_VALUE_TYPE d;
1880      enum machine_mode mode;
1881 {
1882   union real_extract u;
1883   register rtx r;
1884   int in_current_obstack;
1885
1886   /* Get the desired `double' value as a sequence of ints
1887      since that is how they are stored in a CONST_DOUBLE.  */
1888
1889   u.d = d;
1890
1891   /* Detect special cases.  */
1892
1893   /* Avoid REAL_VALUES_EQUAL here in order to distinguish minus zero.  */
1894   if (!bcmp ((char *) &dconst0, (char *) &d, sizeof d))
1895     return CONST0_RTX (mode);
1896   /* Check for NaN first, because some ports (specifically the i386) do not
1897      emit correct ieee-fp code by default, and thus will generate a core
1898      dump here if we pass a NaN to REAL_VALUES_EQUAL and if REAL_VALUES_EQUAL
1899      does a floating point comparison.  */
1900   else if (! REAL_VALUE_ISNAN (d) && REAL_VALUES_EQUAL (dconst1, d))
1901     return CONST1_RTX (mode);
1902
1903   if (sizeof u == 2 * sizeof (HOST_WIDE_INT))
1904     return immed_double_const (u.i[0], u.i[1], mode);
1905
1906   /* The rest of this function handles the case where
1907      a float value requires more than 2 ints of space.
1908      It will be deleted as dead code on machines that don't need it.  */
1909
1910   /* Search the chain for an existing CONST_DOUBLE with the right value.
1911      If one is found, return it.  */
1912
1913   for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
1914     if (! bcmp ((char *) &CONST_DOUBLE_LOW (r), (char *) &u, sizeof u)
1915         && GET_MODE (r) == mode)
1916       return r;
1917
1918   /* No; make a new one and add it to the chain.
1919
1920      We may be called by an optimizer which may be discarding any memory
1921      allocated during its processing (such as combine and loop).  However,
1922      we will be leaving this constant on the chain, so we cannot tolerate
1923      freed memory.  So switch to saveable_obstack for this allocation
1924      and then switch back if we were in current_obstack.  */
1925
1926   push_obstacks_nochange ();
1927   rtl_in_saveable_obstack ();
1928   r = rtx_alloc (CONST_DOUBLE);
1929   PUT_MODE (r, mode);
1930   bcopy ((char *) &u, (char *) &CONST_DOUBLE_LOW (r), sizeof u);
1931   pop_obstacks ();
1932
1933   /* Don't touch const_double_chain in nested function; see force_const_mem.
1934      Also, don't touch it if not inside any function.  */
1935   if (outer_function_chain == 0 && current_function_decl != 0)
1936     {
1937       CONST_DOUBLE_CHAIN (r) = const_double_chain;
1938       const_double_chain = r;
1939     }
1940
1941   /* Store const0_rtx in CONST_DOUBLE_MEM since this CONST_DOUBLE is on the
1942      chain, but has not been allocated memory.  Actual use of CONST_DOUBLE_MEM
1943      is only through force_const_mem.  */
1944
1945   CONST_DOUBLE_MEM (r) = const0_rtx;
1946
1947   return r;
1948 }
1949
1950 /* Return a CONST_DOUBLE rtx for a value specified by EXP,
1951    which must be a REAL_CST tree node.  */
1952
1953 rtx
1954 immed_real_const (exp)
1955      tree exp;
1956 {
1957   return immed_real_const_1 (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)));
1958 }
1959
1960 /* At the end of a function, forget the memory-constants
1961    previously made for CONST_DOUBLEs.  Mark them as not on real_constant_chain.
1962    Also clear out real_constant_chain and clear out all the chain-pointers.  */
1963
1964 void
1965 clear_const_double_mem ()
1966 {
1967   register rtx r, next;
1968
1969   /* Don't touch CONST_DOUBLE_MEM for nested functions.
1970      See force_const_mem for explanation.  */
1971   if (outer_function_chain != 0)
1972     return;
1973
1974   for (r = const_double_chain; r; r = next)
1975     {
1976       next = CONST_DOUBLE_CHAIN (r);
1977       CONST_DOUBLE_CHAIN (r) = 0;
1978       CONST_DOUBLE_MEM (r) = cc0_rtx;
1979     }
1980   const_double_chain = 0;
1981 }
1982 \f
1983 /* Given an expression EXP with a constant value,
1984    reduce it to the sum of an assembler symbol and an integer.
1985    Store them both in the structure *VALUE.
1986    Abort if EXP does not reduce.  */
1987
1988 struct addr_const
1989 {
1990   rtx base;
1991   HOST_WIDE_INT offset;
1992 };
1993
1994 static void
1995 decode_addr_const (exp, value)
1996      tree exp;
1997      struct addr_const *value;
1998 {
1999   register tree target = TREE_OPERAND (exp, 0);
2000   register int offset = 0;
2001   register rtx x;
2002
2003   while (1)
2004     {
2005       if (TREE_CODE (target) == COMPONENT_REF
2006           && (TREE_CODE (DECL_FIELD_BITPOS (TREE_OPERAND (target, 1)))
2007               == INTEGER_CST))
2008         {
2009           offset += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (TREE_OPERAND (target, 1))) / BITS_PER_UNIT;
2010           target = TREE_OPERAND (target, 0);
2011         }
2012       else if (TREE_CODE (target) == ARRAY_REF)
2013         {
2014           if (TREE_CODE (TREE_OPERAND (target, 1)) != INTEGER_CST
2015               || TREE_CODE (TYPE_SIZE (TREE_TYPE (target))) != INTEGER_CST)
2016             abort ();
2017           offset += ((TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (target)))
2018                       * TREE_INT_CST_LOW (TREE_OPERAND (target, 1)))
2019                      / BITS_PER_UNIT);
2020           target = TREE_OPERAND (target, 0);
2021         }
2022       else
2023         break;
2024     }
2025
2026   switch (TREE_CODE (target))
2027     {
2028     case VAR_DECL:
2029     case FUNCTION_DECL:
2030       x = DECL_RTL (target);
2031       break;
2032
2033     case LABEL_DECL:
2034       if (output_bytecode)
2035         /* FIXME: this may not be correct, check it */
2036         x = bc_gen_rtx (TREE_STRING_POINTER (target), 0, (struct bc_label *) 0);
2037       else
2038         x = gen_rtx (MEM, FUNCTION_MODE,
2039                      gen_rtx (LABEL_REF, VOIDmode,
2040                               label_rtx (TREE_OPERAND (exp, 0))));
2041       break;
2042
2043     case REAL_CST:
2044     case STRING_CST:
2045     case COMPLEX_CST:
2046     case CONSTRUCTOR:
2047       x = TREE_CST_RTL (target);
2048       break;
2049
2050     default:
2051       abort ();
2052     }
2053
2054   if (!output_bytecode)
2055     {
2056       if (GET_CODE (x) != MEM)
2057         abort ();
2058       x = XEXP (x, 0);
2059     }
2060
2061   value->base = x;
2062   value->offset = offset;
2063 }
2064 \f
2065 /* Uniquize all constants that appear in memory.
2066    Each constant in memory thus far output is recorded
2067    in `const_hash_table' with a `struct constant_descriptor'
2068    that contains a polish representation of the value of
2069    the constant.
2070
2071    We cannot store the trees in the hash table
2072    because the trees may be temporary.  */
2073
2074 struct constant_descriptor
2075 {
2076   struct constant_descriptor *next;
2077   char *label;
2078   char contents[1];
2079 };
2080
2081 #define HASHBITS 30
2082 #define MAX_HASH_TABLE 1009
2083 static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE];
2084
2085 /* Compute a hash code for a constant expression.  */
2086
2087 int
2088 const_hash (exp)
2089      tree exp;
2090 {
2091   register char *p;
2092   register int len, hi, i;
2093   register enum tree_code code = TREE_CODE (exp);
2094
2095   if (code == INTEGER_CST)
2096     {
2097       p = (char *) &TREE_INT_CST_LOW (exp);
2098       len = 2 * sizeof TREE_INT_CST_LOW (exp);
2099     }
2100   else if (code == REAL_CST)
2101     {
2102       p = (char *) &TREE_REAL_CST (exp);
2103       len = sizeof TREE_REAL_CST (exp);
2104     }
2105   else if (code == STRING_CST)
2106     p = TREE_STRING_POINTER (exp), len = TREE_STRING_LENGTH (exp);
2107   else if (code == COMPLEX_CST)
2108     return const_hash (TREE_REALPART (exp)) * 5
2109       + const_hash (TREE_IMAGPART (exp));
2110   else if (code == CONSTRUCTOR)
2111     {
2112       register tree link;
2113
2114       /* For record type, include the type in the hashing.
2115          We do not do so for array types
2116          because (1) the sizes of the elements are sufficient
2117          and (2) distinct array types can have the same constructor.
2118          Instead, we include the array size because the constructor could
2119          be shorter.  */
2120       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
2121         hi = ((HOST_WIDE_INT) TREE_TYPE (exp) & ((1 << HASHBITS) - 1))
2122           % MAX_HASH_TABLE;
2123       else
2124         hi = ((5 + int_size_in_bytes (TREE_TYPE (exp)))
2125                & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
2126
2127       for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
2128         if (TREE_VALUE (link))
2129           hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
2130
2131       return hi;
2132     }
2133   else if (code == ADDR_EXPR)
2134     {
2135       struct addr_const value;
2136       decode_addr_const (exp, &value);
2137       if (GET_CODE (value.base) == SYMBOL_REF)
2138         {
2139           /* Don't hash the address of the SYMBOL_REF;
2140              only use the offset and the symbol name.  */
2141           hi = value.offset;
2142           p = XSTR (value.base, 0);
2143           for (i = 0; p[i] != 0; i++)
2144             hi = ((hi * 613) + (unsigned)(p[i]));
2145         }
2146       else if (GET_CODE (value.base) == LABEL_REF)
2147         hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13;
2148
2149       hi &= (1 << HASHBITS) - 1;
2150       hi %= MAX_HASH_TABLE;
2151       return hi;
2152     }
2153   else if (code == PLUS_EXPR || code == MINUS_EXPR)
2154     return const_hash (TREE_OPERAND (exp, 0)) * 9
2155       +  const_hash (TREE_OPERAND (exp, 1));
2156   else if (code == NOP_EXPR || code == CONVERT_EXPR)
2157     return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
2158
2159   /* Compute hashing function */
2160   hi = len;
2161   for (i = 0; i < len; i++)
2162     hi = ((hi * 613) + (unsigned)(p[i]));
2163
2164   hi &= (1 << HASHBITS) - 1;
2165   hi %= MAX_HASH_TABLE;
2166   return hi;
2167 }
2168 \f
2169 /* Compare a constant expression EXP with a constant-descriptor DESC.
2170    Return 1 if DESC describes a constant with the same value as EXP.  */
2171
2172 static int
2173 compare_constant (exp, desc)
2174      tree exp;
2175      struct constant_descriptor *desc;
2176 {
2177   return 0 != compare_constant_1 (exp, desc->contents);
2178 }
2179
2180 /* Compare constant expression EXP with a substring P of a constant descriptor.
2181    If they match, return a pointer to the end of the substring matched.
2182    If they do not match, return 0.
2183
2184    Since descriptors are written in polish prefix notation,
2185    this function can be used recursively to test one operand of EXP
2186    against a subdescriptor, and if it succeeds it returns the
2187    address of the subdescriptor for the next operand.  */
2188
2189 static char *
2190 compare_constant_1 (exp, p)
2191      tree exp;
2192      char *p;
2193 {
2194   register char *strp;
2195   register int len;
2196   register enum tree_code code = TREE_CODE (exp);
2197
2198   if (code != (enum tree_code) *p++)
2199     return 0;
2200
2201   if (code == INTEGER_CST)
2202     {
2203       /* Integer constants are the same only if the same width of type.  */
2204       if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
2205         return 0;
2206       strp = (char *) &TREE_INT_CST_LOW (exp);
2207       len = 2 * sizeof TREE_INT_CST_LOW (exp);
2208     }
2209   else if (code == REAL_CST)
2210     {
2211       /* Real constants are the same only if the same width of type.  */
2212       if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
2213         return 0;
2214       strp = (char *) &TREE_REAL_CST (exp);
2215       len = sizeof TREE_REAL_CST (exp);
2216     }
2217   else if (code == STRING_CST)
2218     {
2219       if (flag_writable_strings)
2220         return 0;
2221       strp = TREE_STRING_POINTER (exp);
2222       len = TREE_STRING_LENGTH (exp);
2223       if (bcmp ((char *) &TREE_STRING_LENGTH (exp), p,
2224                 sizeof TREE_STRING_LENGTH (exp)))
2225         return 0;
2226       p += sizeof TREE_STRING_LENGTH (exp);
2227     }
2228   else if (code == COMPLEX_CST)
2229     {
2230       p = compare_constant_1 (TREE_REALPART (exp), p);
2231       if (p == 0) return 0;
2232       p = compare_constant_1 (TREE_IMAGPART (exp), p);
2233       return p;
2234     }
2235   else if (code == CONSTRUCTOR)
2236     {
2237       register tree link;
2238       int length = list_length (CONSTRUCTOR_ELTS (exp));
2239       tree type;
2240
2241       if (bcmp ((char *) &length, p, sizeof length))
2242         return 0;
2243       p += sizeof length;
2244
2245       /* For record constructors, insist that the types match.
2246          For arrays, just verify both constructors are for arrays.  */
2247       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
2248         type = TREE_TYPE (exp);
2249       else
2250         type = 0;
2251       if (bcmp ((char *) &type, p, sizeof type))
2252         return 0;
2253       p += sizeof type;
2254
2255       /* For arrays, insist that the size in bytes match.  */
2256       if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
2257         {
2258           int size = int_size_in_bytes (TREE_TYPE (exp));
2259           if (bcmp ((char *) &size, p, sizeof size))
2260             return 0;
2261           p += sizeof size;
2262         }
2263
2264       for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
2265         {
2266           if (TREE_VALUE (link))
2267             {
2268               if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
2269                 return 0;
2270             }
2271           else
2272             {
2273               tree zero = 0;
2274
2275               if (bcmp ((char *) &zero, p, sizeof zero))
2276                 return 0;
2277               p += sizeof zero;
2278             }
2279         }
2280
2281       return p;
2282     }
2283   else if (code == ADDR_EXPR)
2284     {
2285       struct addr_const value;
2286       decode_addr_const (exp, &value);
2287       strp = (char *) &value.offset;
2288       len = sizeof value.offset;
2289       /* Compare the offset.  */
2290       while (--len >= 0)
2291         if (*p++ != *strp++)
2292           return 0;
2293       /* Compare symbol name.  */
2294       strp = XSTR (value.base, 0);
2295       len = strlen (strp) + 1;
2296     }
2297   else if (code == PLUS_EXPR || code == MINUS_EXPR)
2298     {
2299       p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
2300       if (p == 0) return 0;
2301       p = compare_constant_1 (TREE_OPERAND (exp, 1), p);
2302       return p;
2303     }
2304   else if (code == NOP_EXPR || code == CONVERT_EXPR)
2305     {
2306       p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
2307       return p;
2308     }
2309
2310   /* Compare constant contents.  */
2311   while (--len >= 0)
2312     if (*p++ != *strp++)
2313       return 0;
2314
2315   return p;
2316 }
2317 \f
2318 /* Construct a constant descriptor for the expression EXP.
2319    It is up to the caller to enter the descriptor in the hash table.  */
2320
2321 static struct constant_descriptor *
2322 record_constant (exp)
2323      tree exp;
2324 {
2325   struct constant_descriptor *next = 0;
2326   char *label = 0;
2327
2328   /* Make a struct constant_descriptor.  The first two pointers will
2329      be filled in later.  Here we just leave space for them.  */
2330
2331   obstack_grow (&permanent_obstack, (char *) &next, sizeof next);
2332   obstack_grow (&permanent_obstack, (char *) &label, sizeof label);
2333   record_constant_1 (exp);
2334   return (struct constant_descriptor *) obstack_finish (&permanent_obstack);
2335 }
2336
2337 /* Add a description of constant expression EXP
2338    to the object growing in `permanent_obstack'.
2339    No need to return its address; the caller will get that
2340    from the obstack when the object is complete.  */
2341
2342 static void
2343 record_constant_1 (exp)
2344      tree exp;
2345 {
2346   register char *strp;
2347   register int len;
2348   register enum tree_code code = TREE_CODE (exp);
2349
2350   obstack_1grow (&permanent_obstack, (unsigned int) code);
2351
2352   if (code == INTEGER_CST)
2353     {
2354       obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
2355       strp = (char *) &TREE_INT_CST_LOW (exp);
2356       len = 2 * sizeof TREE_INT_CST_LOW (exp);
2357     }
2358   else if (code == REAL_CST)
2359     {
2360       obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
2361       strp = (char *) &TREE_REAL_CST (exp);
2362       len = sizeof TREE_REAL_CST (exp);
2363     }
2364   else if (code == STRING_CST)
2365     {
2366       if (flag_writable_strings)
2367         return;
2368       strp = TREE_STRING_POINTER (exp);
2369       len = TREE_STRING_LENGTH (exp);
2370       obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
2371                     sizeof TREE_STRING_LENGTH (exp));
2372     }
2373   else if (code == COMPLEX_CST)
2374     {
2375       record_constant_1 (TREE_REALPART (exp));
2376       record_constant_1 (TREE_IMAGPART (exp));
2377       return;
2378     }
2379   else if (code == CONSTRUCTOR)
2380     {
2381       register tree link;
2382       int length = list_length (CONSTRUCTOR_ELTS (exp));
2383       tree type;
2384
2385       obstack_grow (&permanent_obstack, (char *) &length, sizeof length);
2386
2387       /* For record constructors, insist that the types match.
2388          For arrays, just verify both constructors are for arrays.  */
2389       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
2390         type = TREE_TYPE (exp);
2391       else
2392         type = 0;
2393       obstack_grow (&permanent_obstack, (char *) &type, sizeof type);
2394
2395       /* For arrays, insist that the size in bytes match.  */
2396       if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
2397         {
2398           int size = int_size_in_bytes (TREE_TYPE (exp));
2399           obstack_grow (&permanent_obstack, (char *) &size, sizeof size);
2400         }
2401
2402       for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
2403         {
2404           if (TREE_VALUE (link))
2405             record_constant_1 (TREE_VALUE (link));
2406           else
2407             {
2408               tree zero = 0;
2409
2410               obstack_grow (&permanent_obstack, (char *) &zero, sizeof zero);
2411             }
2412         }
2413
2414       return;
2415     }
2416   else if (code == ADDR_EXPR)
2417     {
2418       struct addr_const value;
2419       decode_addr_const (exp, &value);
2420       /* Record the offset.  */
2421       obstack_grow (&permanent_obstack,
2422                     (char *) &value.offset, sizeof value.offset);
2423       /* Record the symbol name.  */
2424       obstack_grow (&permanent_obstack, XSTR (value.base, 0),
2425                     strlen (XSTR (value.base, 0)) + 1);
2426       return;
2427     }
2428   else if (code == PLUS_EXPR || code == MINUS_EXPR)
2429     {
2430       record_constant_1 (TREE_OPERAND (exp, 0));
2431       record_constant_1 (TREE_OPERAND (exp, 1));
2432       return;
2433     }
2434   else if (code == NOP_EXPR || code == CONVERT_EXPR)
2435     {
2436       record_constant_1 (TREE_OPERAND (exp, 0));
2437       return;
2438     }
2439
2440   /* Record constant contents.  */
2441   obstack_grow (&permanent_obstack, strp, len);
2442 }
2443 \f
2444 /* Record a list of constant expressions that were passed to
2445    output_constant_def but that could not be output right away.  */
2446
2447 struct deferred_constant
2448 {
2449   struct deferred_constant *next;
2450   tree exp;
2451   int reloc;
2452   int labelno;
2453 };
2454
2455 static struct deferred_constant *deferred_constants;
2456
2457 /* Nonzero means defer output of addressed subconstants
2458    (i.e., those for which output_constant_def is called.)  */
2459 static int defer_addressed_constants_flag;
2460
2461 /* Start deferring output of subconstants.  */
2462
2463 void
2464 defer_addressed_constants ()
2465 {
2466   defer_addressed_constants_flag++;
2467 }
2468
2469 /* Stop deferring output of subconstants,
2470    and output now all those that have been deferred.  */
2471
2472 void
2473 output_deferred_addressed_constants ()
2474 {
2475   struct deferred_constant *p, *next;
2476
2477   defer_addressed_constants_flag--;
2478
2479   if (defer_addressed_constants_flag > 0)
2480     return;
2481
2482   for (p = deferred_constants; p; p = next)
2483     {
2484       output_constant_def_contents (p->exp, p->reloc, p->labelno);
2485       next = p->next;
2486       free (p);
2487     }
2488
2489   deferred_constants = 0;
2490 }
2491
2492 /* Make a copy of the whole tree structure for a constant.
2493    This handles the same types of nodes that compare_constant
2494    and record_constant handle.  */
2495
2496 static tree
2497 copy_constant (exp)
2498      tree exp;
2499 {
2500   switch (TREE_CODE (exp))
2501     {
2502     case INTEGER_CST:
2503     case REAL_CST:
2504     case STRING_CST:
2505     case ADDR_EXPR:
2506       /* For ADDR_EXPR, we do not want to copy the decl
2507          whose address is requested.  */
2508       return copy_node (exp);
2509
2510     case COMPLEX_CST:
2511       return build_complex (copy_constant (TREE_REALPART (exp)),
2512                             copy_constant (TREE_IMAGPART (exp)));
2513
2514     case PLUS_EXPR:
2515     case MINUS_EXPR:
2516       return build (TREE_CODE (exp), TREE_TYPE (exp),
2517                     copy_constant (TREE_OPERAND (exp, 0)),
2518                     copy_constant (TREE_OPERAND (exp, 1)));
2519
2520     case NOP_EXPR:
2521     case CONVERT_EXPR:
2522       return build1 (TREE_CODE (exp), TREE_TYPE (exp),
2523                      copy_constant (TREE_OPERAND (exp, 0)));
2524
2525     case CONSTRUCTOR:
2526       {
2527         tree copy = copy_node (exp);
2528         tree list = copy_list (CONSTRUCTOR_ELTS (exp));
2529         tree tail;
2530
2531         CONSTRUCTOR_ELTS (copy) = list;
2532         for (tail = list; tail; tail = TREE_CHAIN (tail))
2533           TREE_VALUE (tail) = copy_constant (TREE_VALUE (tail));
2534
2535         return copy;
2536       }
2537
2538     default:
2539       abort ();
2540     }
2541 }
2542 \f
2543 /* Return an rtx representing a reference to constant data in memory
2544    for the constant expression EXP.
2545
2546    If assembler code for such a constant has already been output,
2547    return an rtx to refer to it.
2548    Otherwise, output such a constant in memory (or defer it for later)
2549    and generate an rtx for it.
2550
2551    The TREE_CST_RTL of EXP is set up to point to that rtx.
2552    The const_hash_table records which constants already have label strings.  */
2553
2554 rtx
2555 output_constant_def (exp)
2556      tree exp;
2557 {
2558   register int hash;
2559   register struct constant_descriptor *desc;
2560   char label[256];
2561   char *found = 0;
2562   int reloc;
2563   register rtx def;
2564
2565   if (TREE_CODE (exp) == INTEGER_CST)
2566     abort ();                   /* No TREE_CST_RTL slot in these.  */
2567
2568   if (TREE_CST_RTL (exp))
2569     return TREE_CST_RTL (exp);
2570
2571   /* Make sure any other constants whose addresses appear in EXP
2572      are assigned label numbers.  */
2573
2574   reloc = output_addressed_constants (exp);
2575
2576   /* Compute hash code of EXP.  Search the descriptors for that hash code
2577      to see if any of them describes EXP.  If yes, the descriptor records
2578      the label number already assigned.  */
2579
2580   hash = const_hash (exp) % MAX_HASH_TABLE;
2581       
2582   for (desc = const_hash_table[hash]; desc; desc = desc->next)
2583     if (compare_constant (exp, desc))
2584       {
2585         found = desc->label;
2586         break;
2587       }
2588       
2589   if (found == 0)
2590     {
2591       /* No constant equal to EXP is known to have been output.
2592          Make a constant descriptor to enter EXP in the hash table.
2593          Assign the label number and record it in the descriptor for
2594          future calls to this function to find.  */
2595           
2596       /* Create a string containing the label name, in LABEL.  */
2597       ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
2598
2599       desc = record_constant (exp);
2600       desc->next = const_hash_table[hash];
2601       desc->label
2602         = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
2603       const_hash_table[hash] = desc;
2604     }
2605   else
2606     {
2607       /* Create a string containing the label name, in LABEL.  */
2608       ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
2609     }
2610   
2611   /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
2612
2613   push_obstacks_nochange ();
2614   if (TREE_PERMANENT (exp))
2615     end_temporary_allocation ();
2616
2617   def = gen_rtx (SYMBOL_REF, Pmode, desc->label);
2618       
2619   TREE_CST_RTL (exp)
2620     = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);
2621   RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
2622   if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
2623     MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;
2624
2625   pop_obstacks ();
2626
2627   /* Optionally set flags or add text to the name to record information
2628      such as that it is a function name.  If the name is changed, the macro
2629      ASM_OUTPUT_LABELREF will have to know how to strip this information.  */
2630 #ifdef ENCODE_SECTION_INFO
2631   ENCODE_SECTION_INFO (exp);
2632 #endif
2633
2634   /* If this is the first time we've seen this particular constant,
2635      output it (or defer its output for later).  */
2636   if (found == 0)
2637     {
2638       if (defer_addressed_constants_flag)
2639         {
2640           struct deferred_constant *p;
2641           p = (struct deferred_constant *) xmalloc (sizeof (struct deferred_constant));
2642
2643           push_obstacks_nochange ();
2644           suspend_momentary ();
2645           p->exp = copy_constant (exp);
2646           pop_obstacks ();
2647           p->reloc = reloc;
2648           p->labelno = const_labelno++;
2649           p->next = deferred_constants;
2650           deferred_constants = p;
2651         }
2652       else
2653         output_constant_def_contents (exp, reloc, const_labelno++);
2654     }
2655
2656   return TREE_CST_RTL (exp);
2657 }
2658
2659 /* Now output assembler code to define the label for EXP,
2660    and follow it with the data of EXP.  */
2661
2662 static void
2663 output_constant_def_contents (exp, reloc, labelno)
2664      tree exp;
2665      int reloc;
2666      int labelno;
2667 {
2668   int align;
2669
2670   if (IN_NAMED_SECTION (exp))
2671     named_section (TREE_STRING_POINTER (DECL_SECTION_NAME (exp)));
2672   else
2673     {
2674       /* First switch to text section, except for writable strings.  */
2675 #ifdef SELECT_SECTION
2676       SELECT_SECTION (exp, reloc);
2677 #else
2678       if (((TREE_CODE (exp) == STRING_CST) && flag_writable_strings)
2679           || (flag_pic && reloc))
2680         data_section ();
2681       else
2682         readonly_data_section ();
2683 #endif
2684     }
2685
2686   /* Align the location counter as required by EXP's data type.  */
2687   align = TYPE_ALIGN (TREE_TYPE (exp));
2688 #ifdef CONSTANT_ALIGNMENT
2689   align = CONSTANT_ALIGNMENT (exp, align);
2690 #endif
2691
2692   if (align > BITS_PER_UNIT)
2693     {
2694       if (!output_bytecode)
2695         {
2696           ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
2697         }
2698       else
2699         {
2700           BC_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
2701         }
2702     }
2703
2704   /* Output the label itself.  */
2705   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", labelno);
2706
2707   /* Output the value of EXP.  */
2708   output_constant (exp,
2709                    (TREE_CODE (exp) == STRING_CST
2710                     ? TREE_STRING_LENGTH (exp)
2711                     : int_size_in_bytes (TREE_TYPE (exp))));
2712
2713 }
2714 \f
2715 /* Similar hash facility for making memory-constants
2716    from constant rtl-expressions.  It is used on RISC machines
2717    where immediate integer arguments and constant addresses are restricted
2718    so that such constants must be stored in memory.
2719
2720    This pool of constants is reinitialized for each function
2721    so each function gets its own constants-pool that comes right before it.
2722
2723    All structures allocated here are discarded when functions are saved for
2724    inlining, so they do not need to be allocated permanently.  */
2725
2726 #define MAX_RTX_HASH_TABLE 61
2727 static struct constant_descriptor **const_rtx_hash_table;
2728
2729 /* Structure to represent sufficient information about a constant so that
2730    it can be output when the constant pool is output, so that function
2731    integration can be done, and to simplify handling on machines that reference
2732    constant pool as base+displacement.  */
2733
2734 struct pool_constant
2735 {
2736   struct constant_descriptor *desc;
2737   struct pool_constant *next;
2738   enum machine_mode mode;
2739   rtx constant;
2740   int labelno;
2741   int align;
2742   int offset;
2743 };
2744
2745 /* Pointers to first and last constant in pool.  */
2746
2747 static struct pool_constant *first_pool, *last_pool;
2748
2749 /* Current offset in constant pool (does not include any machine-specific
2750    header.  */
2751
2752 static int pool_offset;
2753
2754 /* Structure used to maintain hash table mapping symbols used to their
2755    corresponding constants.  */
2756
2757 struct pool_sym
2758 {
2759   char *label;
2760   struct pool_constant *pool;
2761   struct pool_sym *next;
2762 };
2763
2764 static struct pool_sym **const_rtx_sym_hash_table;
2765
2766 /* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true.
2767    The argument is XSTR (... , 0)  */
2768
2769 #define SYMHASH(LABEL)  \
2770   ((((HOST_WIDE_INT) (LABEL)) & ((1 << HASHBITS) - 1))  % MAX_RTX_HASH_TABLE)
2771 \f
2772 /* Initialize constant pool hashing for next function.  */
2773
2774 void
2775 init_const_rtx_hash_table ()
2776 {
2777   const_rtx_hash_table
2778     = ((struct constant_descriptor **)
2779        oballoc (MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *)));
2780   const_rtx_sym_hash_table
2781     = ((struct pool_sym **)
2782        oballoc (MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *)));
2783   bzero ((char *) const_rtx_hash_table,
2784          MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *));
2785   bzero ((char *) const_rtx_sym_hash_table,
2786          MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *));
2787
2788   first_pool = last_pool = 0;
2789   pool_offset = 0;
2790 }
2791
2792 /* Save and restore it for a nested function.  */
2793
2794 void
2795 save_varasm_status (p)
2796      struct function *p;
2797 {
2798   p->const_rtx_hash_table = const_rtx_hash_table;
2799   p->const_rtx_sym_hash_table = const_rtx_sym_hash_table;
2800   p->first_pool = first_pool;
2801   p->last_pool = last_pool;
2802   p->pool_offset = pool_offset;
2803 }
2804
2805 void
2806 restore_varasm_status (p)
2807      struct function *p;
2808 {
2809   const_rtx_hash_table = p->const_rtx_hash_table;
2810   const_rtx_sym_hash_table = p->const_rtx_sym_hash_table;
2811   first_pool = p->first_pool;
2812   last_pool = p->last_pool;
2813   pool_offset = p->pool_offset;
2814 }
2815 \f
2816 enum kind { RTX_DOUBLE, RTX_INT };
2817
2818 struct rtx_const
2819 {
2820 #ifdef ONLY_INT_FIELDS
2821   unsigned int kind : 16;
2822   unsigned int mode : 16;
2823 #else
2824   enum kind kind : 16;
2825   enum machine_mode mode : 16;
2826 #endif
2827   union {
2828     union real_extract du;
2829     struct addr_const addr;
2830   } un;
2831 };
2832
2833 /* Express an rtx for a constant integer (perhaps symbolic)
2834    as the sum of a symbol or label plus an explicit integer.
2835    They are stored into VALUE.  */
2836
2837 static void
2838 decode_rtx_const (mode, x, value)
2839      enum machine_mode mode;
2840      rtx x;
2841      struct rtx_const *value;
2842 {
2843   /* Clear the whole structure, including any gaps.  */
2844
2845   {
2846     int *p = (int *) value;
2847     int *end = (int *) (value + 1);
2848     while (p < end)
2849       *p++ = 0;
2850   }
2851
2852   value->kind = RTX_INT;        /* Most usual kind. */
2853   value->mode = mode;
2854
2855   switch (GET_CODE (x))
2856     {
2857     case CONST_DOUBLE:
2858       value->kind = RTX_DOUBLE;
2859       if (GET_MODE (x) != VOIDmode)
2860         value->mode = GET_MODE (x);
2861       bcopy ((char *) &CONST_DOUBLE_LOW (x),
2862              (char *) &value->un.du, sizeof value->un.du);
2863       break;
2864
2865     case CONST_INT:
2866       value->un.addr.offset = INTVAL (x);
2867       break;
2868
2869     case SYMBOL_REF:
2870     case LABEL_REF:
2871     case PC:
2872       value->un.addr.base = x;
2873       break;
2874
2875     case CONST:
2876       x = XEXP (x, 0);
2877       if (GET_CODE (x) == PLUS)
2878         {
2879           value->un.addr.base = XEXP (x, 0);
2880           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2881             abort ();
2882           value->un.addr.offset = INTVAL (XEXP (x, 1));
2883         }
2884       else if (GET_CODE (x) == MINUS)
2885         {
2886           value->un.addr.base = XEXP (x, 0);
2887           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2888             abort ();
2889           value->un.addr.offset = - INTVAL (XEXP (x, 1));
2890         }
2891       else
2892         abort ();
2893       break;
2894
2895     default:
2896       abort ();
2897     }
2898
2899   if (value->kind == RTX_INT && value->un.addr.base != 0)
2900     switch (GET_CODE (value->un.addr.base))
2901       {
2902       case SYMBOL_REF:
2903       case LABEL_REF:
2904         /* Use the string's address, not the SYMBOL_REF's address,
2905            for the sake of addresses of library routines.
2906            For a LABEL_REF, compare labels.  */
2907         value->un.addr.base = XEXP (value->un.addr.base, 0);
2908       }
2909 }
2910
2911 /* Given a MINUS expression, simplify it if both sides
2912    include the same symbol.  */
2913
2914 rtx
2915 simplify_subtraction (x)
2916      rtx x;
2917 {
2918   struct rtx_const val0, val1;
2919
2920   decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0);
2921   decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1);
2922
2923   if (val0.un.addr.base == val1.un.addr.base)
2924     return GEN_INT (val0.un.addr.offset - val1.un.addr.offset);
2925   return x;
2926 }
2927
2928 /* Compute a hash code for a constant RTL expression.  */
2929
2930 int
2931 const_hash_rtx (mode, x)
2932      enum machine_mode mode;
2933      rtx x;
2934 {
2935   register int hi, i;
2936
2937   struct rtx_const value;
2938   decode_rtx_const (mode, x, &value);
2939
2940   /* Compute hashing function */
2941   hi = 0;
2942   for (i = 0; i < sizeof value / sizeof (int); i++)
2943     hi += ((int *) &value)[i];
2944
2945   hi &= (1 << HASHBITS) - 1;
2946   hi %= MAX_RTX_HASH_TABLE;
2947   return hi;
2948 }
2949
2950 /* Compare a constant rtl object X with a constant-descriptor DESC.
2951    Return 1 if DESC describes a constant with the same value as X.  */
2952
2953 static int
2954 compare_constant_rtx (mode, x, desc)
2955      enum machine_mode mode;
2956      rtx x;
2957      struct constant_descriptor *desc;
2958 {
2959   register int *p = (int *) desc->contents;
2960   register int *strp;
2961   register int len;
2962   struct rtx_const value;
2963
2964   decode_rtx_const (mode, x, &value);
2965   strp = (int *) &value;
2966   len = sizeof value / sizeof (int);
2967
2968   /* Compare constant contents.  */
2969   while (--len >= 0)
2970     if (*p++ != *strp++)
2971       return 0;
2972
2973   return 1;
2974 }
2975
2976 /* Construct a constant descriptor for the rtl-expression X.
2977    It is up to the caller to enter the descriptor in the hash table.  */
2978
2979 static struct constant_descriptor *
2980 record_constant_rtx (mode, x)
2981      enum machine_mode mode;
2982      rtx x;
2983 {
2984   struct constant_descriptor *ptr;
2985   char *label;
2986   struct rtx_const value;
2987
2988   decode_rtx_const (mode, x, &value);
2989
2990   obstack_grow (current_obstack, &ptr, sizeof ptr);
2991   obstack_grow (current_obstack, &label, sizeof label);
2992
2993   /* Record constant contents.  */
2994   obstack_grow (current_obstack, &value, sizeof value);
2995
2996   return (struct constant_descriptor *) obstack_finish (current_obstack);
2997 }
2998 \f
2999 /* Given a constant rtx X, make (or find) a memory constant for its value
3000    and return a MEM rtx to refer to it in memory.  */
3001
3002 rtx
3003 force_const_mem (mode, x)
3004      enum machine_mode mode;
3005      rtx x;
3006 {
3007   register int hash;
3008   register struct constant_descriptor *desc;
3009   char label[256];
3010   char *found = 0;
3011   rtx def;
3012
3013   /* If we want this CONST_DOUBLE in the same mode as it is in memory
3014      (this will always be true for floating CONST_DOUBLEs that have been
3015      placed in memory, but not for VOIDmode (integer) CONST_DOUBLEs),
3016      use the previous copy.  Otherwise, make a new one.  Note that in
3017      the unlikely event that this same CONST_DOUBLE is used in two different
3018      modes in an alternating fashion, we will allocate a lot of different
3019      memory locations, but this should be extremely rare.  */
3020
3021   /* Don't use CONST_DOUBLE_MEM in a nested function.
3022      Nested functions have their own constant pools,
3023      so they can't share the same values in CONST_DOUBLE_MEM
3024      with the containing function.  */
3025   if (outer_function_chain == 0)
3026     if (GET_CODE (x) == CONST_DOUBLE
3027         && GET_CODE (CONST_DOUBLE_MEM (x)) == MEM
3028         && GET_MODE (CONST_DOUBLE_MEM (x)) == mode)
3029       return CONST_DOUBLE_MEM (x);
3030
3031   /* Compute hash code of X.  Search the descriptors for that hash code
3032      to see if any of them describes X.  If yes, the descriptor records
3033      the label number already assigned.  */
3034
3035   hash = const_hash_rtx (mode, x);
3036
3037   for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
3038     if (compare_constant_rtx (mode, x, desc))
3039       {
3040         found = desc->label;
3041         break;
3042       }
3043
3044   if (found == 0)
3045     {
3046       register struct pool_constant *pool;
3047       register struct pool_sym *sym;
3048       int align;
3049
3050       /* No constant equal to X is known to have been output.
3051          Make a constant descriptor to enter X in the hash table.
3052          Assign the label number and record it in the descriptor for
3053          future calls to this function to find.  */
3054
3055       desc = record_constant_rtx (mode, x);
3056       desc->next = const_rtx_hash_table[hash];
3057       const_rtx_hash_table[hash] = desc;
3058
3059       /* Align the location counter as required by EXP's data type.  */
3060       align = (mode == VOIDmode) ? UNITS_PER_WORD : GET_MODE_SIZE (mode);
3061       if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
3062         align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
3063
3064       pool_offset += align - 1;
3065       pool_offset &= ~ (align - 1);
3066
3067       /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
3068
3069       pool = (struct pool_constant *) oballoc (sizeof (struct pool_constant));
3070       pool->desc = desc;
3071       pool->constant = x;
3072       pool->mode = mode;
3073       pool->labelno = const_labelno;
3074       pool->align = align;
3075       pool->offset = pool_offset;
3076       pool->next = 0;
3077
3078       if (last_pool == 0)
3079         first_pool = pool;
3080       else
3081         last_pool->next = pool;
3082
3083       last_pool = pool;
3084       pool_offset += GET_MODE_SIZE (mode);
3085
3086       /* Create a string containing the label name, in LABEL.  */
3087       ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
3088
3089       ++const_labelno;
3090
3091       desc->label = found
3092         = (char *) obstack_copy0 (saveable_obstack, label, strlen (label));
3093
3094       /* Add label to symbol hash table.  */
3095       hash = SYMHASH (found);
3096       sym = (struct pool_sym *) oballoc (sizeof (struct pool_sym));
3097       sym->label = found;
3098       sym->pool = pool;
3099       sym->next = const_rtx_sym_hash_table[hash];
3100       const_rtx_sym_hash_table[hash] = sym;
3101     }
3102
3103   /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
3104
3105   def = gen_rtx (MEM, mode, gen_rtx (SYMBOL_REF, Pmode, found));
3106
3107   RTX_UNCHANGING_P (def) = 1;
3108   /* Mark the symbol_ref as belonging to this constants pool.  */
3109   CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
3110   current_function_uses_const_pool = 1;
3111
3112   if (outer_function_chain == 0)
3113     if (GET_CODE (x) == CONST_DOUBLE)
3114       {
3115         if (CONST_DOUBLE_MEM (x) == cc0_rtx)
3116           {
3117             CONST_DOUBLE_CHAIN (x) = const_double_chain;
3118             const_double_chain = x;
3119           }
3120         CONST_DOUBLE_MEM (x) = def;
3121       }
3122
3123   return def;
3124 }
3125 \f
3126 /* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to
3127    the corresponding pool_constant structure.  */
3128
3129 static struct pool_constant *
3130 find_pool_constant (addr)
3131      rtx addr;
3132 {
3133   struct pool_sym *sym;
3134   char *label = XSTR (addr, 0);
3135
3136   for (sym = const_rtx_sym_hash_table[SYMHASH (label)]; sym; sym = sym->next)
3137     if (sym->label == label)
3138       return sym->pool;
3139
3140   abort ();
3141 }
3142
3143 /* Given a constant pool SYMBOL_REF, return the corresponding constant.  */
3144
3145 rtx
3146 get_pool_constant (addr)
3147      rtx addr;
3148 {
3149   return (find_pool_constant (addr))->constant;
3150 }
3151
3152 /* Similar, return the mode.  */
3153
3154 enum machine_mode
3155 get_pool_mode (addr)
3156      rtx addr;
3157 {
3158   return (find_pool_constant (addr))->mode;
3159 }
3160
3161 /* Similar, return the offset in the constant pool.  */
3162
3163 int
3164 get_pool_offset (addr)
3165      rtx addr;
3166 {
3167   return (find_pool_constant (addr))->offset;
3168 }
3169
3170 /* Return the size of the constant pool.  */
3171
3172 int
3173 get_pool_size ()
3174 {
3175   return pool_offset;
3176 }
3177 \f
3178 /* Write all the constants in the constant pool.  */
3179
3180 void
3181 output_constant_pool (fnname, fndecl)
3182      char *fnname;
3183      tree fndecl;
3184 {
3185   struct pool_constant *pool;
3186   rtx x;
3187   union real_extract u;
3188
3189 #ifdef ASM_OUTPUT_POOL_PROLOGUE
3190   ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool_offset);
3191 #endif
3192
3193   for (pool = first_pool; pool; pool = pool->next)
3194     {
3195       x = pool->constant;
3196
3197       /* See if X is a LABEL_REF (or a CONST referring to a LABEL_REF)
3198          whose CODE_LABEL has been deleted.  This can occur if a jump table
3199          is eliminated by optimization.  If so, write a constant of zero
3200          instead.  Note that this can also happen by turning the
3201          CODE_LABEL into a NOTE.  */
3202       if (((GET_CODE (x) == LABEL_REF
3203             && (INSN_DELETED_P (XEXP (x, 0))
3204                 || GET_CODE (XEXP (x, 0)) == NOTE)))
3205           || (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
3206               && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
3207               && (INSN_DELETED_P (XEXP (XEXP (XEXP (x, 0), 0), 0))
3208                   || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == NOTE)))
3209         x = const0_rtx;
3210
3211       /* First switch to correct section.  */
3212 #ifdef SELECT_RTX_SECTION
3213       SELECT_RTX_SECTION (pool->mode, x);
3214 #else
3215       readonly_data_section ();
3216 #endif
3217
3218 #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
3219       ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode,
3220                                      pool->align, pool->labelno, done);
3221 #endif
3222
3223       if (pool->align > 1)
3224         ASM_OUTPUT_ALIGN (asm_out_file, exact_log2 (pool->align));
3225
3226       /* Output the label.  */
3227       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", pool->labelno);
3228
3229       /* Output the value of the constant itself.  */
3230       switch (GET_MODE_CLASS (pool->mode))
3231         {
3232         case MODE_FLOAT:
3233           if (GET_CODE (x) != CONST_DOUBLE)
3234             abort ();
3235
3236           bcopy ((char *) &CONST_DOUBLE_LOW (x), (char *) &u, sizeof u);
3237           assemble_real (u.d, pool->mode);
3238           break;
3239
3240         case MODE_INT:
3241         case MODE_PARTIAL_INT:
3242           assemble_integer (x, GET_MODE_SIZE (pool->mode), 1);
3243           break;
3244
3245         default:
3246           abort ();
3247         }
3248
3249     done: ;
3250     }
3251
3252   /* Done with this pool.  */
3253   first_pool = last_pool = 0;
3254 }
3255 \f
3256 /* Find all the constants whose addresses are referenced inside of EXP,
3257    and make sure assembler code with a label has been output for each one.
3258    Indicate whether an ADDR_EXPR has been encountered.  */
3259
3260 int
3261 output_addressed_constants (exp)
3262      tree exp;
3263 {
3264   int reloc = 0;
3265
3266   switch (TREE_CODE (exp))
3267     {
3268     case ADDR_EXPR:
3269       {
3270         register tree constant = TREE_OPERAND (exp, 0);
3271
3272         while (TREE_CODE (constant) == COMPONENT_REF)
3273           {
3274             constant = TREE_OPERAND (constant, 0);
3275           }
3276
3277         if (TREE_CODE_CLASS (TREE_CODE (constant)) == 'c'
3278             || TREE_CODE (constant) == CONSTRUCTOR)
3279           /* No need to do anything here
3280              for addresses of variables or functions.  */
3281           output_constant_def (constant);
3282       }
3283       reloc = 1;
3284       break;
3285
3286     case PLUS_EXPR:
3287     case MINUS_EXPR:
3288       reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
3289       reloc |= output_addressed_constants (TREE_OPERAND (exp, 1));
3290       break;
3291
3292     case NOP_EXPR:
3293     case CONVERT_EXPR:
3294     case NON_LVALUE_EXPR:
3295       reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
3296       break;
3297
3298     case CONSTRUCTOR:
3299       {
3300         register tree link;
3301         for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
3302           if (TREE_VALUE (link) != 0)
3303             reloc |= output_addressed_constants (TREE_VALUE (link));
3304       }
3305       break;
3306
3307     case ERROR_MARK:
3308       break;
3309     }
3310   return reloc;
3311 }
3312
3313
3314 /* Output assembler for byte constant */
3315 void
3316 output_byte_asm (byte)
3317   int byte;
3318 {
3319   if (output_bytecode)
3320     bc_emit_const ((char *) &byte, sizeof (char));
3321 #ifdef ASM_OUTPUT_BYTE
3322   else
3323     {
3324       ASM_OUTPUT_BYTE (asm_out_file, byte);
3325     }
3326 #endif
3327 }
3328 \f
3329 /* Output assembler code for constant EXP to FILE, with no label.
3330    This includes the pseudo-op such as ".int" or ".byte", and a newline.
3331    Assumes output_addressed_constants has been done on EXP already.
3332
3333    Generate exactly SIZE bytes of assembler data, padding at the end
3334    with zeros if necessary.  SIZE must always be specified.
3335
3336    SIZE is important for structure constructors,
3337    since trailing members may have been omitted from the constructor.
3338    It is also important for initialization of arrays from string constants
3339    since the full length of the string constant might not be wanted.
3340    It is also needed for initialization of unions, where the initializer's
3341    type is just one member, and that may not be as long as the union.
3342
3343    There a case in which we would fail to output exactly SIZE bytes:
3344    for a structure constructor that wants to produce more than SIZE bytes.
3345    But such constructors will never be generated for any possible input.  */
3346
3347 void
3348 output_constant (exp, size)
3349      register tree exp;
3350      register int size;
3351 {
3352   register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
3353   rtx x;
3354
3355   if (size == 0)
3356     return;
3357
3358   /* Eliminate the NON_LVALUE_EXPR_EXPR that makes a cast not be an lvalue.
3359      That way we get the constant (we hope) inside it.  Also, strip
3360      off any NOP_EXPR that converts between two record or union types.  */
3361   while ((TREE_CODE (exp) == NOP_EXPR 
3362           && (TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0))
3363               || TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
3364               || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE
3365               || TREE_CODE (TREE_TYPE (exp)) == QUAL_UNION_TYPE))
3366          || TREE_CODE (exp) == NON_LVALUE_EXPR)
3367     exp = TREE_OPERAND (exp, 0);
3368
3369   /* Allow a constructor with no elements for any data type.
3370      This means to fill the space with zeros.  */
3371   if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0)
3372     {
3373       if (output_bytecode)
3374         bc_emit_const_skip (size);
3375       else
3376         assemble_zeros (size);
3377       return;
3378     }
3379
3380   switch (code)
3381     {
3382     case CHAR_TYPE:
3383     case BOOLEAN_TYPE:
3384     case INTEGER_TYPE:
3385     case ENUMERAL_TYPE:
3386     case POINTER_TYPE:
3387     case REFERENCE_TYPE:
3388       /* ??? What about       (int)((float)(int)&foo + 4)    */
3389       while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
3390              || TREE_CODE (exp) == NON_LVALUE_EXPR)
3391         exp = TREE_OPERAND (exp, 0);
3392
3393       if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
3394                                            EXPAND_INITIALIZER),
3395                               size, 0))
3396         error ("initializer for integer value is too complicated");
3397       size = 0;
3398       break;
3399
3400     case REAL_TYPE:
3401       if (TREE_CODE (exp) != REAL_CST)
3402         error ("initializer for floating value is not a floating constant");
3403
3404       assemble_real (TREE_REAL_CST (exp),
3405                      mode_for_size (size * BITS_PER_UNIT, MODE_FLOAT, 0));
3406       size = 0;
3407       break;
3408
3409     case COMPLEX_TYPE:
3410       output_constant (TREE_REALPART (exp), size / 2);
3411       output_constant (TREE_IMAGPART (exp), size / 2);
3412       size -= (size / 2) * 2;
3413       break;
3414
3415     case ARRAY_TYPE:
3416       if (TREE_CODE (exp) == CONSTRUCTOR)
3417         {
3418           output_constructor (exp, size);
3419           return;
3420         }
3421       else if (TREE_CODE (exp) == STRING_CST)
3422         {
3423           int excess = 0;
3424
3425           if (size > TREE_STRING_LENGTH (exp))
3426             {
3427               excess = size - TREE_STRING_LENGTH (exp);
3428               size = TREE_STRING_LENGTH (exp);
3429             }
3430
3431           assemble_string (TREE_STRING_POINTER (exp), size);
3432           size = excess;
3433         }
3434       else
3435         abort ();
3436       break;
3437
3438     case RECORD_TYPE:
3439     case UNION_TYPE:
3440       if (TREE_CODE (exp) == CONSTRUCTOR)
3441         output_constructor (exp, size);
3442       else
3443         abort ();
3444       return;
3445     }
3446
3447   if (size > 0)
3448     assemble_zeros (size);
3449 }
3450
3451
3452 /* Bytecode specific code to output assembler for integer. */
3453 static void
3454 bc_assemble_integer (exp, size)
3455     tree exp;
3456     int size;
3457 {
3458   tree const_part;
3459   tree addr_part;
3460   tree tmp;
3461
3462   /* FIXME: is this fold() business going to be as good as the
3463      expand_expr() using EXPAND_SUM above in the RTL case?  I
3464      hate RMS.
3465      FIXME: Copied as is from BC-GCC1; may need work. Don't hate. -bson */
3466   
3467   exp = fold (exp);
3468   
3469   while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR)
3470     exp = TREE_OPERAND (exp, 0);
3471   if (TREE_CODE (exp) == INTEGER_CST)
3472     {
3473       const_part = exp;
3474       addr_part = 0;
3475     }
3476   else if (TREE_CODE (exp) == PLUS_EXPR)
3477     {
3478       const_part = TREE_OPERAND (exp, 0);
3479       while (TREE_CODE (const_part) == NOP_EXPR
3480              || TREE_CODE (const_part) == CONVERT_EXPR)
3481         const_part = TREE_OPERAND (const_part, 0);
3482       addr_part = TREE_OPERAND (exp, 1);
3483       while (TREE_CODE (addr_part) == NOP_EXPR
3484              || TREE_CODE (addr_part) == CONVERT_EXPR)
3485         addr_part = TREE_OPERAND (addr_part, 0);
3486       if (TREE_CODE (const_part) != INTEGER_CST)
3487         tmp = const_part, const_part = addr_part, addr_part = tmp;
3488       if (TREE_CODE (const_part) != INTEGER_CST
3489           || TREE_CODE (addr_part) != ADDR_EXPR)
3490         abort ();               /* FIXME: we really haven't considered
3491                                    all the possible cases here.  */
3492     }
3493   else if (TREE_CODE (exp) == ADDR_EXPR)
3494     {
3495       const_part = integer_zero_node;
3496       addr_part = exp;
3497     }
3498   else
3499     abort ();           /* FIXME: ditto previous.  */
3500   
3501   if (addr_part == 0)
3502     {
3503       if (size == 1)
3504         {
3505           char c = TREE_INT_CST_LOW (const_part);
3506           bc_emit (&c, 1);
3507           size -= 1;
3508         }
3509       else if (size == 2)
3510         {
3511           short s = TREE_INT_CST_LOW (const_part);
3512           bc_emit ((char *) &s, 2);
3513           size -= 2;
3514         }
3515       else if (size == 4)
3516         {
3517           int i = TREE_INT_CST_LOW (const_part);
3518           bc_emit ((char *) &i, 4);
3519           size -= 4;
3520         }
3521       else if (size == 8)
3522         {
3523 #if WORDS_BIG_ENDIAN
3524           int i = TREE_INT_CST_HIGH (const_part);
3525           bc_emit ((char *) &i, 4);
3526           i = TREE_INT_CST_LOW (const_part);
3527           bc_emit ((char *) &i, 4);
3528 #else
3529           int i = TREE_INT_CST_LOW (const_part);
3530           bc_emit ((char *) &i, 4);
3531           i = TREE_INT_CST_HIGH (const_part);
3532           bc_emit ((char *) &i, 4);
3533 #endif
3534           size -= 8;
3535         }
3536     }
3537   else
3538     if (size == 4
3539         && TREE_CODE (TREE_OPERAND (addr_part, 0)) == VAR_DECL)
3540       bc_emit_labelref (DECL_ASSEMBLER_NAME (TREE_OPERAND (addr_part, 0)),
3541                         TREE_INT_CST_LOW (const_part));
3542     else
3543       abort ();         /* FIXME: there may be more cases.  */
3544 }
3545 \f
3546 /* Subroutine of output_constant, used for CONSTRUCTORs
3547    (aggregate constants).
3548    Generate at least SIZE bytes, padding if necessary.  */
3549
3550 void
3551 output_constructor (exp, size)
3552      tree exp;
3553      int size;
3554 {
3555   register tree link, field = 0;
3556   HOST_WIDE_INT min_index = 0;
3557   /* Number of bytes output or skipped so far.
3558      In other words, current position within the constructor.  */
3559   int total_bytes = 0;
3560   /* Non-zero means BYTE contains part of a byte, to be output.  */
3561   int byte_buffer_in_use = 0;
3562   register int byte;
3563
3564   if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)
3565     abort ();
3566
3567   if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
3568     field = TYPE_FIELDS (TREE_TYPE (exp));
3569
3570   if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
3571       && TYPE_DOMAIN (TREE_TYPE (exp)) != 0)
3572     min_index
3573       = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (exp))));
3574
3575   /* As LINK goes through the elements of the constant,
3576      FIELD goes through the structure fields, if the constant is a structure.
3577      if the constant is a union, then we override this,
3578      by getting the field from the TREE_LIST element.
3579      But the constant could also be an array.  Then FIELD is zero.  */
3580   for (link = CONSTRUCTOR_ELTS (exp);
3581        link;
3582        link = TREE_CHAIN (link),
3583        field = field ? TREE_CHAIN (field) : 0)
3584     {
3585       tree val = TREE_VALUE (link);
3586       tree index = 0;
3587
3588       /* the element in a union constructor specifies the proper field.  */
3589
3590       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
3591           || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
3592         {
3593           /* if available, use the type given by link */
3594           if (TREE_PURPOSE (link) != 0)
3595             field = TREE_PURPOSE (link);
3596         }
3597
3598       if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
3599         index = TREE_PURPOSE (link);
3600
3601       /* Eliminate the marker that makes a cast not be an lvalue.  */
3602       if (val != 0)
3603         STRIP_NOPS (val);
3604
3605       if (field == 0 || !DECL_BIT_FIELD (field))
3606         {
3607           /* An element that is not a bit-field.  */
3608
3609           register int fieldsize;
3610           /* Since this structure is static,
3611              we know the positions are constant.  */
3612           int bitpos = (field ? (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
3613                                  / BITS_PER_UNIT)
3614                         : 0);
3615           if (index != 0)
3616             bitpos = (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (val)))
3617                       / BITS_PER_UNIT
3618                       * (TREE_INT_CST_LOW (index) - min_index));
3619
3620           /* Output any buffered-up bit-fields preceding this element.  */
3621           if (byte_buffer_in_use)
3622             {
3623               ASM_OUTPUT_BYTE (asm_out_file, byte);
3624               total_bytes++;
3625               byte_buffer_in_use = 0;
3626             }
3627
3628           /* Advance to offset of this element.
3629              Note no alignment needed in an array, since that is guaranteed
3630              if each element has the proper size.  */
3631           if ((field != 0 || index != 0) && bitpos != total_bytes)
3632             {
3633               if (!output_bytecode)
3634                 assemble_zeros (bitpos - total_bytes);
3635               else
3636                 bc_emit_const_skip (bitpos - total_bytes);
3637               total_bytes = bitpos;
3638             }
3639
3640           /* Determine size this element should occupy.  */
3641           if (field)
3642             {
3643               if (TREE_CODE (DECL_SIZE (field)) != INTEGER_CST)
3644                 abort ();
3645               if (TREE_INT_CST_LOW (DECL_SIZE (field)) > 100000)
3646                 {
3647                   /* This avoids overflow trouble.  */
3648                   tree size_tree = size_binop (CEIL_DIV_EXPR,
3649                                                DECL_SIZE (field),
3650                                                size_int (BITS_PER_UNIT));
3651                   fieldsize = TREE_INT_CST_LOW (size_tree);
3652                 }
3653               else
3654                 {
3655                   fieldsize = TREE_INT_CST_LOW (DECL_SIZE (field));
3656                   fieldsize = (fieldsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
3657                 }
3658             }
3659           else
3660             fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
3661
3662           /* Output the element's initial value.  */
3663           if (val == 0)
3664             assemble_zeros (fieldsize);
3665           else
3666             output_constant (val, fieldsize);
3667
3668           /* Count its size.  */
3669           total_bytes += fieldsize;
3670         }
3671       else if (val != 0 && TREE_CODE (val) != INTEGER_CST)
3672         error ("invalid initial value for member `%s'",
3673                IDENTIFIER_POINTER (DECL_NAME (field)));
3674       else
3675         {
3676           /* Element that is a bit-field.  */
3677
3678           int next_offset = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
3679           int end_offset
3680             = (next_offset + TREE_INT_CST_LOW (DECL_SIZE (field)));
3681
3682           if (val == 0)
3683             val = integer_zero_node;
3684
3685           /* If this field does not start in this (or, next) byte,
3686              skip some bytes.  */
3687           if (next_offset / BITS_PER_UNIT != total_bytes)
3688             {
3689               /* Output remnant of any bit field in previous bytes.  */
3690               if (byte_buffer_in_use)
3691                 {
3692                   ASM_OUTPUT_BYTE (asm_out_file, byte);
3693                   total_bytes++;
3694                   byte_buffer_in_use = 0;
3695                 }
3696
3697               /* If still not at proper byte, advance to there.  */
3698               if (next_offset / BITS_PER_UNIT != total_bytes)
3699                 {
3700                   assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);
3701                   total_bytes = next_offset / BITS_PER_UNIT;
3702                 }
3703             }
3704
3705           if (! byte_buffer_in_use)
3706             byte = 0;
3707
3708           /* We must split the element into pieces that fall within
3709              separate bytes, and combine each byte with previous or
3710              following bit-fields.  */
3711
3712           /* next_offset is the offset n fbits from the beginning of
3713              the structure to the next bit of this element to be processed.
3714              end_offset is the offset of the first bit past the end of
3715              this element.  */
3716           while (next_offset < end_offset)
3717             {
3718               int this_time;
3719               int shift, value;
3720               int next_byte = next_offset / BITS_PER_UNIT;
3721               int next_bit = next_offset % BITS_PER_UNIT;
3722
3723               /* Advance from byte to byte
3724                  within this element when necessary.  */
3725               while (next_byte != total_bytes)
3726                 {
3727                   ASM_OUTPUT_BYTE (asm_out_file, byte);
3728                   total_bytes++;
3729                   byte = 0;
3730                 }
3731
3732               /* Number of bits we can process at once
3733                  (all part of the same byte).  */
3734               this_time = MIN (end_offset - next_offset,
3735                                BITS_PER_UNIT - next_bit);
3736 #if BYTES_BIG_ENDIAN
3737               /* On big-endian machine, take the most significant bits
3738                  first (of the bits that are significant)
3739                  and put them into bytes from the most significant end.  */
3740               shift = end_offset - next_offset - this_time;
3741               /* Don't try to take a bunch of bits that cross
3742                  the word boundary in the INTEGER_CST.  */
3743               if (shift < HOST_BITS_PER_WIDE_INT
3744                   && shift + this_time > HOST_BITS_PER_WIDE_INT)
3745                 {
3746                   this_time -= (HOST_BITS_PER_WIDE_INT - shift);
3747                   shift = HOST_BITS_PER_WIDE_INT;
3748                 }
3749
3750               /* Now get the bits from the appropriate constant word.  */
3751               if (shift < HOST_BITS_PER_WIDE_INT)
3752                 {
3753                   value = TREE_INT_CST_LOW (val);
3754                 }
3755               else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
3756                 {
3757                   value = TREE_INT_CST_HIGH (val);
3758                   shift -= HOST_BITS_PER_WIDE_INT;
3759                 }
3760               else
3761                 abort ();
3762               byte |= (((value >> shift)
3763                         & (((HOST_WIDE_INT) 1 << this_time) - 1))
3764                        << (BITS_PER_UNIT - this_time - next_bit));
3765 #else
3766               /* On little-endian machines,
3767                  take first the least significant bits of the value
3768                  and pack them starting at the least significant
3769                  bits of the bytes.  */
3770               shift = (next_offset
3771                        - TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)));
3772               /* Don't try to take a bunch of bits that cross
3773                  the word boundary in the INTEGER_CST.  */
3774               if (shift < HOST_BITS_PER_WIDE_INT
3775                   && shift + this_time > HOST_BITS_PER_WIDE_INT)
3776                 {
3777                   this_time -= (HOST_BITS_PER_WIDE_INT - shift);
3778                   shift = HOST_BITS_PER_WIDE_INT;
3779                 }
3780
3781               /* Now get the bits from the appropriate constant word.  */
3782               if (shift < HOST_BITS_PER_INT)
3783                 value = TREE_INT_CST_LOW (val);
3784               else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
3785                 {
3786                   value = TREE_INT_CST_HIGH (val);
3787                   shift -= HOST_BITS_PER_WIDE_INT;
3788                 }
3789               else
3790                 abort ();
3791               byte |= ((value >> shift)
3792                        & (((HOST_WIDE_INT) 1 << this_time) - 1)) << next_bit;
3793 #endif
3794               next_offset += this_time;
3795               byte_buffer_in_use = 1;
3796             }
3797         }
3798     }
3799   if (byte_buffer_in_use)
3800     {
3801       ASM_OUTPUT_BYTE (asm_out_file, byte);
3802       total_bytes++;
3803     }
3804   if (total_bytes < size)
3805     assemble_zeros (size - total_bytes);
3806 }
3807
3808
3809 #ifdef HANDLE_SYSV_PRAGMA
3810
3811 /* Support #pragma weak by default if WEAK_ASM_OP and ASM_OUTPUT_DEF
3812    are defined.  */
3813 #if defined (WEAK_ASM_OP) && defined (ASM_OUTPUT_DEF)
3814
3815 /* See c-pragma.c for an identical definition.  */
3816 enum pragma_state
3817 {
3818   ps_start,
3819   ps_done,
3820   ps_bad,
3821   ps_weak,
3822   ps_name,
3823   ps_equals,
3824   ps_value,
3825   ps_pack,
3826   ps_left,
3827   ps_align,
3828   ps_right
3829 };
3830
3831 /* Output asm to handle ``#pragma weak'' */
3832 void
3833 handle_pragma_weak (what, asm_out_file, name, value)
3834      enum pragma_state what;
3835      FILE *asm_out_file;
3836      char *name, *value;
3837 {
3838   if (what == ps_name || what == ps_value)
3839     {
3840       fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
3841
3842       if (output_bytecode)
3843         BC_OUTPUT_LABELREF (asm_out_file, name);
3844       else
3845         ASM_OUTPUT_LABELREF (asm_out_file, name);
3846
3847       fputc ('\n', asm_out_file);
3848       if (what == ps_value)
3849         ASM_OUTPUT_DEF (asm_out_file, name, value);
3850     }
3851   else if (! (what == ps_done || what == ps_start))
3852     warning ("malformed `#pragma weak'");
3853 }
3854
3855 #endif /* HANDLE_PRAGMA_WEAK or (WEAK_ASM_OP and SET_ASM_OP) */
3856
3857 #endif /* WEAK_ASM_OP && ASM_OUTPUT_DEF */