Annotation of gcc/varasm.c, revision 1.1.1.7

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

unix.superglobalmegacorp.com

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