Annotation of gcc/varasm.c, revision 1.1.1.8

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.