OSDN Git Service

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