/* OSF/rose half-pic support functions.
- Copyright (C) 1992 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1997, 1998, 1999 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
/* The OSF/rose half-pic model assumes that the non-library code does
not need to have full PIC (position independent code), but rather,
that pointers to external references are put into the data section
- and derefenced as normal pointers. References to static data does
+ and dereferenced as normal pointers. References to static data does
not need to be PIC-ized.
Another optimization is to have the compiler know what symbols are
#ifdef HALF_PIC_INIT
+#include "system.h"
#include "tree.h"
#include "rtl.h"
-#include <stdio.h>
-#include <string.h>
+#include "expr.h"
+#include "output.h"
#include "obstack.h"
+#include "halfpic.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-extern char *xmalloc ();
-extern void free ();
-extern rtx eliminate_constant_term ();
-extern void assemble_name ();
-extern void output_addr_const ();
-
-int flag_half_pic; /* Global half-pic flag. */
-int half_pic_number_ptrs; /* # distinct pointers found */
-int half_pic_number_refs; /* # half-pic references */
+int flag_half_pic = 0; /* Global half-pic flag. */
+int half_pic_number_ptrs = 0; /* # distinct pointers found */
+int half_pic_number_refs = 0; /* # half-pic references */
+int (*ptr_half_pic_address_p) PARAMS ((rtx)) = half_pic_address_p;
/* Obstack to hold generated pic names. */
static struct obstack half_pic_obstack;
struct all_refs *next; /* next name created */
int external_p; /* name is an external reference */
int pointer_p; /* pointer created. */
- char *ref_name; /* reference name to ptr to real_name */
+ const char *ref_name; /* reference name to ptr to real_name */
int ref_len; /* reference name length */
- char *real_name; /* real function/data name */
+ const char *real_name; /* real function/data name */
int real_len; /* strlen (real_name) */
};
static struct all_refs *half_pic_names;
-static char *half_pic_prefix;
+static const char *half_pic_prefix;
static int half_pic_prefix_len;
\f
#define HASHBITS 30
+static struct all_refs *half_pic_hash PARAMS ((const char *, int, int));
+
static struct all_refs *
half_pic_hash (name, len, create_p)
- char *name; /* name to hash */
+ const char *name; /* name to hash */
int len; /* length of the name (or 0 to call strlen) */
int create_p; /* != 0 to create new hash bucket if new */
{
static struct all_refs *hash_table[MAX_HASH_TABLE];
static struct all_refs zero_all_refs;
- unsigned char *uname;
+ const unsigned char *uname;
int hash;
int i;
int ch;
len = strlen (name);
/* Compute hash code */
- uname = (unsigned char *)name;
+ uname = (const unsigned char *)name;
ch = uname[0];
hash = len * 613 + ch;
for (i = 1; i < len; i += 2)
/* name not in hash table. */
if (!create_p)
- return (struct all_refs *)0;
+ return (struct all_refs *) 0;
ptr = (struct all_refs *) obstack_alloc (&half_pic_obstack, sizeof (struct all_refs));
*ptr = zero_all_refs;
ptr->real_len = len;
/* Update circular links. */
- if (first == (struct all_refs *)0)
+ if (first == (struct all_refs *) 0)
ptr->hash_next = ptr;
else
if (p->pointer_p)
{
ASM_OUTPUT_LABEL (stream, p->ref_name);
- ASM_OUTPUT_INT (stream, gen_rtx (SYMBOL_REF, Pmode, p->real_name));
+ assemble_aligned_integer (POINTER_SIZE / BITS_PER_UNIT,
+ gen_rtx_SYMBOL_REF (Pmode, p->real_name));
}
}
}
if (code != VAR_DECL && code != FUNCTION_DECL)
return;
- /* If this is not an external reference, it can't be half-pic. */
- if (!TREE_EXTERNAL (decl))
- return;
-
asm_name = DECL_ASSEMBLER_NAME (decl);
+
if (!asm_name)
return;
+#ifdef HALF_PIC_DEBUG
+ if (HALF_PIC_DEBUG)
+ {
+ fprintf (stderr, "\n========== Half_pic_encode %.*s\n",
+ IDENTIFIER_LENGTH (asm_name),
+ IDENTIFIER_POINTER (asm_name));
+ debug_tree (decl);
+ }
+#endif
+
+ /* If this is not an external reference, it can't be half-pic. */
+ if (!DECL_EXTERNAL (decl) && (code != VAR_DECL || !TREE_PUBLIC (decl)))
+ return;
+
ptr = half_pic_hash (IDENTIFIER_POINTER (asm_name),
IDENTIFIER_LENGTH (asm_name),
TRUE);
#ifdef HALF_PIC_DEBUG
if (HALF_PIC_DEBUG)
- fprintf (stderr, "\n========== Half_pic_encode %.*s\n",
+ fprintf (stderr, "\n%.*s is half-pic\n",
IDENTIFIER_LENGTH (asm_name),
IDENTIFIER_POINTER (asm_name));
#endif
void
half_pic_declare (name)
- char *name;
+ const char *name;
{
struct all_refs *ptr;
}
\f
+/* Mark that an object is explicitly external. */
+
+void
+half_pic_external (name)
+ const char *name;
+{
+ struct all_refs *ptr;
+
+ if (!flag_half_pic)
+ return;
+
+ ptr = half_pic_hash (name, 0, TRUE);
+ if (!ptr)
+ return;
+
+ ptr->external_p = TRUE;
+
+#ifdef HALF_PIC_DEBUG
+ if (HALF_PIC_DEBUG)
+ fprintf (stderr, "\n========== Half_pic_external %s\n", name);
+#endif
+}
+
+\f
/* Return whether an address is half-pic. */
int
half_pic_address_p (addr)
rtx addr;
{
- char *name;
+ const char *name;
int len;
struct all_refs *ptr;
case CONST:
{
rtx offset = const0_rtx;
- addr = eliminate_constant_term (addr, &offset);
+ addr = eliminate_constant_term (XEXP (addr, 0), &offset);
if (GET_CODE (addr) != SYMBOL_REF)
return FALSE;
}
return FALSE;
ptr = half_pic_hash (name, len, FALSE);
- if (ptr == (struct all_refs *)0)
+ if (ptr == (struct all_refs *) 0)
return FALSE;
if (ptr->external_p)
half_pic_ptr (operand)
rtx operand;
{
- char *name;
+ const char *name;
struct all_refs *p;
int len;
name = XSTR (operand, 0);
len = strlen (name);
p = half_pic_hash (name, len, FALSE);
- if (p == (struct all_refs *)0 || !p->external_p)
+ if (p == (struct all_refs *) 0 || !p->external_p)
return operand;
if (!p->pointer_p)
}
half_pic_number_refs++;
- return gen_rtx (SYMBOL_REF, Pmode, p->ref_name);
+ return gen_rtx_SYMBOL_REF (Pmode, p->ref_name);
}
#endif /* HALF_PIC_INIT */