OSDN Git Service

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