Annotation of gcc/halfpic.c, revision 1.1.1.3

1.1       root        1: /* OSF/rose half-pic support functions.
                      2:    Copyright (C) 1992 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: /* The OSF/rose half-pic model assumes that the non-library code does
                     21:    not need to have full PIC (position independent code), but rather,
                     22:    that pointers to external references are put into the data section
1.1.1.3 ! root       23:    and dereferenced as normal pointers.  References to static data does
1.1       root       24:    not need to be PIC-ized.
                     25: 
                     26:    Another optimization is to have the compiler know what symbols are
                     27:    in the shared libraries, and to only lay down the pointers to
                     28:    things which in the library proper.  */
                     29: 
                     30: #include "config.h"
                     31: 
                     32: #ifdef HALF_PIC_INIT
                     33: 
                     34: #include "tree.h"
                     35: #include "rtl.h"
                     36: #include <stdio.h>
1.1.1.3 ! root       37: #include <string.h>
        !            38: #include "obstack.h"
1.1       root       39: 
1.1.1.3 ! root       40: #define obstack_chunk_alloc xmalloc
        !            41: #define obstack_chunk_free free
        !            42: 
        !            43: extern char *xmalloc ();
        !            44: extern void  free ();
1.1       root       45: extern rtx eliminate_constant_term ();
1.1.1.3 ! root       46: extern void assemble_name ();
        !            47: extern void output_addr_const ();
1.1       root       48: 
                     49: int flag_half_pic;             /* Global half-pic flag.  */
1.1.1.3 ! root       50: int half_pic_number_ptrs;      /* # distinct pointers found */
        !            51: int half_pic_number_refs;      /* # half-pic references */
        !            52: 
        !            53: /* Obstack to hold generated pic names.  */
        !            54: static struct obstack half_pic_obstack;
        !            55: 
        !            56: /* List of pointers created to pic references.  */
        !            57: 
        !            58: struct all_refs {
        !            59:   struct all_refs *hash_next;  /* next name in hash chain */
        !            60:   struct all_refs *next;       /* next name created */
        !            61:   int             external_p;  /* name is an external reference */
        !            62:   int             pointer_p;   /* pointer created.  */
        !            63:   char           *ref_name;    /* reference name to ptr to real_name */
        !            64:   int             ref_len;     /* reference name length */
        !            65:   char           *real_name;   /* real function/data name */
        !            66:   int             real_len;    /* strlen (real_name) */
        !            67: };
        !            68: 
        !            69: static struct all_refs *half_pic_names;
        !            70: 
        !            71: static char *half_pic_prefix;
        !            72: static int   half_pic_prefix_len;
        !            73: 
        !            74: 
        !            75: /* Return the hash bucket of a name or NULL.  The hash chain is
        !            76:    organized as a self reorganizing circularly linked chain.  It is
        !            77:    assumed that any name passed to use will never be reallocated.  For
        !            78:    names in SYMBOL_REF's this is true, because the names are allocated
        !            79:    on the permanent obstack.  */
        !            80: 
        !            81: #ifndef MAX_HASH_TABLE
        !            82: #define MAX_HASH_TABLE 1009
        !            83: #endif
        !            84: 
        !            85: #define HASHBITS 30
        !            86: 
        !            87: static struct all_refs *
        !            88: half_pic_hash (name, len, create_p)
        !            89:      char *name;               /* name to hash */
        !            90:      int len;                  /* length of the name (or 0 to call strlen) */
        !            91:      int create_p;             /* != 0 to create new hash bucket if new */
        !            92: {
        !            93:   static struct all_refs *hash_table[MAX_HASH_TABLE];
        !            94:   static struct all_refs  zero_all_refs;
        !            95: 
        !            96:   unsigned char *uname;
        !            97:   int hash;
        !            98:   int i;
        !            99:   int ch;
        !           100:   struct all_refs *first;
        !           101:   struct all_refs *ptr;
        !           102: 
        !           103:   if (len == 0)
        !           104:     len = strlen (name);
        !           105: 
        !           106:   /* Compute hash code */
        !           107:   uname = (unsigned char *)name;
        !           108:   ch = uname[0];
        !           109:   hash = len * 613 + ch;
        !           110:   for (i = 1; i < len; i += 2)
        !           111:     hash = (hash * 613) + uname[i];
        !           112: 
        !           113:   hash &= (1 << HASHBITS) - 1;
        !           114:   hash %= MAX_HASH_TABLE;
        !           115: 
        !           116:   /* See if the name is in the hash table.  */
        !           117:   ptr = first = hash_table[hash];
        !           118:   if (ptr)
        !           119:     {
        !           120:       do
        !           121:        {
        !           122:          if (len == ptr->real_len
        !           123:              && ch == *(ptr->real_name)
        !           124:              && !strcmp (name, ptr->real_name))
        !           125:            {
        !           126:              hash_table[hash] = ptr;
        !           127:              return ptr;
        !           128:            }
        !           129: 
        !           130:          ptr = ptr->hash_next;
        !           131:        }
        !           132:       while (ptr != first);
        !           133:     }
        !           134: 
        !           135:   /* name not in hash table.  */
        !           136:   if (!create_p)
        !           137:     return (struct all_refs *)0;
        !           138: 
        !           139:   ptr = (struct all_refs *) obstack_alloc (&half_pic_obstack, sizeof (struct all_refs));
        !           140:   *ptr = zero_all_refs;
        !           141: 
        !           142:   ptr->real_name = name;
        !           143:   ptr->real_len  = len;
        !           144: 
        !           145:   /* Update circular links.  */
        !           146:   if (first == (struct all_refs *)0)
        !           147:     ptr->hash_next = ptr;
        !           148: 
        !           149:   else
        !           150:     {
        !           151:       ptr->hash_next = first->hash_next;
        !           152:       first->hash_next = ptr;
        !           153:     }
        !           154: 
        !           155:   hash_table[hash] = ptr;
        !           156:   return ptr;
        !           157: }
1.1       root      158: 
                    159: 
                    160: /* Do any half-pic initializations.  */
                    161: 
                    162: void
                    163: half_pic_init ()
                    164: {
                    165:   flag_half_pic = TRUE;
1.1.1.3 ! root      166:   half_pic_prefix = HALF_PIC_PREFIX;
        !           167:   half_pic_prefix_len = strlen (half_pic_prefix);
        !           168:   obstack_init (&half_pic_obstack);
        !           169: }
        !           170: 
        !           171: 
        !           172: /* Write out all pointers to pic references.  */
        !           173: 
        !           174: void
        !           175: half_pic_finish (stream)
        !           176:      FILE *stream;
        !           177: {
        !           178:   struct all_refs *p = half_pic_names;
        !           179: 
        !           180:   if (!p)
        !           181:     return;
        !           182: 
        !           183:   data_section ();
        !           184:   for (; p != 0; p = p->next)
        !           185:     {
        !           186:       /* Emit the pointer if used.  */
        !           187:       if (p->pointer_p)
        !           188:        {
        !           189:          ASM_OUTPUT_LABEL (stream, p->ref_name);
        !           190:          ASM_OUTPUT_INT (stream, gen_rtx (SYMBOL_REF, Pmode, p->real_name));
        !           191:        }
        !           192:     }
1.1       root      193: }
                    194: 
                    195: 
                    196: /* Encode in a declaration whether or not it is half-pic.  */
                    197: 
                    198: void
                    199: half_pic_encode (decl)
                    200:      tree decl;
                    201: {
1.1.1.3 ! root      202:   enum tree_code code = TREE_CODE (decl);
        !           203:   tree asm_name;
        !           204:   struct all_refs *ptr;
        !           205: 
        !           206:   if (!flag_half_pic)
        !           207:     return;
        !           208: 
        !           209:   if (code != VAR_DECL && code != FUNCTION_DECL)
        !           210:     return;
        !           211: 
        !           212:   /* If this is not an external reference, it can't be half-pic.  */
        !           213:   if (!TREE_EXTERNAL (decl))
        !           214:     return;
        !           215: 
        !           216:   asm_name = DECL_ASSEMBLER_NAME (decl);
        !           217:   if (!asm_name)
        !           218:     return;
        !           219: 
        !           220:   ptr = half_pic_hash (IDENTIFIER_POINTER (asm_name),
        !           221:                       IDENTIFIER_LENGTH (asm_name),
        !           222:                       TRUE);
        !           223: 
        !           224:   ptr->external_p = TRUE;
        !           225: 
        !           226: #ifdef HALF_PIC_DEBUG
        !           227:   if (HALF_PIC_DEBUG)
        !           228:     fprintf (stderr, "\n========== Half_pic_encode %.*s\n",
        !           229:             IDENTIFIER_LENGTH (asm_name),
        !           230:             IDENTIFIER_POINTER (asm_name));
        !           231: #endif
        !           232: }
        !           233: 
        !           234: 
        !           235: /* Mark that an object is now local, and no longer needs half-pic.  */
        !           236: 
        !           237: void
        !           238: half_pic_declare (name)
        !           239:      char *name;
        !           240: {
        !           241:   struct all_refs *ptr;
        !           242: 
        !           243:   if (!flag_half_pic)
        !           244:     return;
        !           245: 
        !           246:   ptr = half_pic_hash (name, 0, FALSE);
        !           247:   if (!ptr)
        !           248:     return;
        !           249: 
        !           250:   ptr->external_p = FALSE;
        !           251: 
        !           252: #ifdef HALF_PIC_DEBUG
        !           253:   if (HALF_PIC_DEBUG)
        !           254:     fprintf (stderr, "\n========== Half_pic_declare %s\n", name);
1.1       root      255: #endif
                    256: }
                    257: 
                    258: 
                    259: /* Return whether an address is half-pic.  */
                    260: 
                    261: int
                    262: half_pic_address_p (addr)
                    263:      rtx addr;
                    264: {
                    265:   char *name;
1.1.1.3 ! root      266:   int len;
        !           267:   struct all_refs *ptr;
        !           268: 
        !           269:   if (!flag_half_pic)
        !           270:     return FALSE;
1.1       root      271: 
                    272:   switch (GET_CODE (addr))
                    273:     {
1.1.1.3 ! root      274:     default:
        !           275:       break;
        !           276: 
1.1       root      277:     case CONST:
1.1.1.2   root      278:       {
                    279:        rtx offset = const0_rtx;
                    280:        addr = eliminate_constant_term (addr, &offset);
                    281:        if (GET_CODE (addr) != SYMBOL_REF)
                    282:          return FALSE;
                    283:       }
1.1       root      284:       /* fall through */
                    285: 
                    286:     case SYMBOL_REF:
                    287:       name = XSTR (addr, 0);
                    288: 
1.1.1.3 ! root      289: #ifdef HALF_PIC_DEBUG
        !           290:       if (HALF_PIC_DEBUG)
        !           291:        fprintf (stderr, "\n========== Half_pic_address_p %s\n", name);
        !           292: #endif
        !           293: 
1.1       root      294:       /* If this is a label, it will have a '*' in front of it.  */
                    295:       if (name[0] == '*')
                    296:        return FALSE;
1.1.1.3 ! root      297: 
        !           298:       /* If this is a reference to the actual half-pic pointer, it
        !           299:         is obviously not half-pic.  */
        !           300: 
        !           301:       len = strlen (name);
        !           302:       if (len > half_pic_prefix_len
        !           303:          && half_pic_prefix[0] == name[0]
        !           304:          && !strncmp (name, half_pic_prefix, half_pic_prefix_len))
        !           305:        return FALSE;
        !           306: 
        !           307:       ptr = half_pic_hash (name, len, FALSE);
        !           308:       if (ptr == (struct all_refs *)0)
        !           309:        return FALSE;
        !           310: 
        !           311:       if (ptr->external_p)
        !           312:        {
        !           313: #ifdef HALF_PIC_DEBUG
        !           314:          if (HALF_PIC_DEBUG)
        !           315:            fprintf (stderr, "%s is half-pic\n", name);
        !           316: #endif
        !           317:          return TRUE;
        !           318:        }
1.1       root      319:     }
                    320: 
                    321:   return FALSE;
                    322: }
                    323: 
1.1.1.3 ! root      324: 
        !           325: /* Return the name of the pointer to the PIC function, allocating
        !           326:    it if need be.  */
        !           327: 
        !           328: struct rtx_def *
        !           329: half_pic_ptr (operand)
        !           330:      rtx operand;
        !           331: {
        !           332:   char *name;
        !           333:   struct all_refs *p;
        !           334:   int len;
        !           335: 
        !           336:   if (GET_CODE (operand) != SYMBOL_REF)
        !           337:     return operand;
        !           338: 
        !           339:   name = XSTR (operand, 0);
        !           340:   len = strlen (name);
        !           341:   p = half_pic_hash (name, len, FALSE);
        !           342:   if (p == (struct all_refs *)0 || !p->external_p)
        !           343:     return operand;
        !           344: 
        !           345:   if (!p->pointer_p)
        !           346:     {                          /* first time, create pointer */
        !           347:       obstack_grow (&half_pic_obstack, half_pic_prefix, half_pic_prefix_len);
        !           348:       obstack_grow (&half_pic_obstack, name, len+1);
        !           349: 
        !           350:       p->next      = half_pic_names;
        !           351:       p->ref_name  = (char *) obstack_finish (&half_pic_obstack);
        !           352:       p->ref_len   = len + half_pic_prefix_len;
        !           353:       p->pointer_p = TRUE;
        !           354: 
        !           355:       half_pic_names = p;
        !           356:       half_pic_number_ptrs++;
        !           357:     }
        !           358: 
        !           359:   half_pic_number_refs++;
        !           360:   return gen_rtx (SYMBOL_REF, Pmode, p->ref_name);
        !           361: }
        !           362: 
1.1       root      363: #endif /* HALF_PIC_INIT */

unix.superglobalmegacorp.com

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