OSDN Git Service

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