Annotation of gcc/varasm.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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