Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/gnu/dist/toolchain/gcc/config/vax Add legitimize_pic_address...



details:   https://anonhg.NetBSD.org/src/rev/79869d957957
branches:  trunk
changeset: 501033:79869d957957
user:      matt <matt%NetBSD.org@localhost>
date:      Fri Dec 22 16:48:36 2000 +0000

description:
Add legitimize_pic_address and the netbsd-elf.h for ELF support.

diffstat:

 gnu/dist/toolchain/gcc/config/vax/netbsd-elf.h |  126 +++++++++++++++++++++++++
 gnu/dist/toolchain/gcc/config/vax/vax.c        |  122 +++++++++++++++++++++++-
 2 files changed, 246 insertions(+), 2 deletions(-)

diffs (276 lines):

diff -r 1110dc96aa3b -r 79869d957957 gnu/dist/toolchain/gcc/config/vax/netbsd-elf.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/gnu/dist/toolchain/gcc/config/vax/netbsd-elf.h    Fri Dec 22 16:48:36 2000 +0000
@@ -0,0 +1,126 @@
+/* Definitions of target machine for GNU compiler,
+   for vax NetBSD systems.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+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.
+
+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.
+
+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.  */
+
+/* This is used on vax platforms that use the ELF format.
+   This was taken from the NetBSD/alpha configuration, and modified
+   for NetBSD/vax by Matt Thomas <matt%netbsd.org@localhost> */
+
+/* Get generic NetBSD ELF definitions.  We will override these if necessary. */
+
+#include <elfos.h>
+#define NETBSD_ELF
+#include <netbsd.h>
+#include <vax/netbsd.h>
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "long unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "long int"
+
+/* We always use gas here */
+#undef  TARGET_GAS
+#define TARGET_GAS     (1)
+
+#if 1
+#undef  PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+#endif
+#undef  DWARF_DEBUGGING_INFO
+#undef  DWARF2_DEBUGGING_INFO
+
+/* Function CSE screws up PLT .vs. GOT usage.
+ */
+#define        NO_FUNCTION_CSE
+
+/* Profiling routines */
+
+/* Redefine this to use %eax instead of %edx.  */
+#undef  FUNCTION_PROFILER
+#define FUNCTION_PROFILER(FILE, LABELNO)  \
+  fprintf (FILE, "\tmovab .LP%d,r0\n\tjsb __mcount+2\n", (LABELNO))
+
+/* Put relocations in the constant pool in the writable data section.  */
+#undef  SELECT_RTX_SECTION
+#define SELECT_RTX_SECTION(MODE,RTX)           \
+{                                              \
+  if ((flag_pic || TARGET_HALFPIC)             \
+      && vax_symbolic_operand ((RTX), (MODE))) \
+    data_section ();                           \
+  else                                         \
+    readonly_data_section ();                  \
+}
+
+/* Use sjlj exceptions. */
+#undef DWARF2_UNWIND_INFO              /* just to be safe */
+
+#undef ASM_FINAL_SPEC
+
+/* Names to predefine in the preprocessor for this target machine. */
+
+/* NetBSD Extension to GNU C: __KPRINTF_ATTRIBUTE__ */
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__vax__ -D__NetBSD__ -D__ELF__ \
+-Asystem(unix) -Asystem(NetBSD) -Acpu(vax) -Amachine(vax)"
+
+/* The VAX wants no space between the case instruction and the
+   jump table.  */
+#undef  ASM_OUTPUT_BEFORE_CASE_LABEL
+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE)
+
+/* This makes use of a hook in varasm.c to mark all external functions
+   for us.  We use this to make sure that external functions are correctly
+   referenced from the PLT.  */
+
+#define        NO_EXTERNAL_INDIRECT_ADDRESS
+
+/* Get the udiv/urem calls out of the user's namespace */
+
+#undef  UDIVSI3_LIBCALL
+#define UDIVSI3_LIBCALL "*__udiv"
+#undef  UMODSI3_LIBCALL
+#define UMODSI3_LIBCALL "*__urem"
+
+/* Define this macro if references to a symbol must be treated
+   differently depending on something about the variable or
+   function named by the symbol (such as what section it is in).
+
+   On the VAX, if using PIC, mark a SYMBOL_REF for a non-global
+   symbol so that we may use indirect accesses with it.  */
+
+#define ENCODE_SECTION_INFO(DECL)                              \
+do                                                             \
+  {                                                            \
+    if ((flag_pic | TARGET_HALFPIC))                           \
+      {                                                                \
+       rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd'    \
+                  ? TREE_CST_RTL (DECL) : DECL_RTL (DECL));    \
+                                                               \
+       if (GET_CODE (rtl) == MEM)                              \
+         {                                                     \
+           SYMBOL_REF_FLAG (XEXP (rtl, 0))                     \
+             = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd'      \
+                || ! TREE_PUBLIC (DECL));                      \
+         }                                                     \
+      }                                                                \
+  }                                                            \
+while (0)
diff -r 1110dc96aa3b -r 79869d957957 gnu/dist/toolchain/gcc/config/vax/vax.c
--- a/gnu/dist/toolchain/gcc/config/vax/vax.c   Fri Dec 22 16:37:37 2000 +0000
+++ b/gnu/dist/toolchain/gcc/config/vax/vax.c   Fri Dec 22 16:48:36 2000 +0000
@@ -677,7 +677,7 @@
    || (!INDEXED && GET_CODE (X) == CONST                               \
        && GET_CODE (XEXP ((X), 0)) == PLUS                             \
        && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF             \
-       && ((!INDIRECT && !(flag_pic))                                  \
+       && ((!INDIRECT && !(flag_pic || TARGET_HALFPIC))                        \
            || SYMBOL_REF_FLAG (XEXP (XEXP ((X), 0), 0))))              \
    || GET_CODE (X) == CONST_INT)
 
@@ -729,7 +729,7 @@
   xfoob = XEXP (X, 0);                                                 \
   if (GET_CODE (X) == MEM                                              \
       && INDIRECTABLE_ADDRESS_P (xfoob, STRICT, INDEXED,               \
-                                (flag_pic)))                           \
+                                (flag_pic || TARGET_HALFPIC)))         \
     goto ADDR;                                                         \
   if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)            \
       && GET_CODE (xfoob) == REG                                       \
@@ -830,6 +830,124 @@
  win:
   return 1;
 }
+
+/* Legitimize PIC addresses.  If the address is already
+   position-independent, we return ORIG.  Newly generated
+   position-independent addresses go to REG.  If we need more
+   than one register, we lose.  
+
+   An address is legitimized by making an indirect reference
+   through the Global Offset Table with the name of the symbol
+   used as an offset.  
+
+   The assembler/loader are responsible for translating a symbol name
+   into a PC-relative displacement.
+
+   A quick example may make things a little clearer:
+
+   When not generating PIC code to store the value 12345 into _foo+4
+   we would generate the following code:
+
+       movl    $12345, _foo+4
+
+   When generating PIC a transformation is made.  First, the compiler
+   loads the address of foo into a register.  So the transformation makes:
+
+       movab   _foo, r0
+       movl    $12345, 4(r0)
+
+   That (in a nutshell) is how *all* symbol references are handled.  */
+
+rtx
+legitimize_pic_address (orig, reg, code)
+     rtx orig;
+     rtx reg;
+     int code;
+{
+  rtx pic_ref = orig;
+
+  if (!(flag_pic || TARGET_HALFPIC))
+    return pic_ref;
+
+  /* fprintf(stderr, "before: "); debug_rtx(orig); */
+  if (GET_CODE (orig) == SYMBOL_REF
+      && code != CODE_FOR_movsi
+      && code != CODE_FOR_addsi3)
+    {
+      if (reg == NULL || !reload_in_progress)
+       reg = gen_reg_rtx (Pmode);
+
+      emit_move_insn (reg, orig);
+      pic_ref = reg;
+    }
+  else if (GET_CODE (orig) == CONST
+          && GET_CODE (XEXP (orig, 0)) == PLUS)
+    {
+      if (GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
+         && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
+       {
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+         if (!SYMBOL_REF_FLAG (XEXP (XEXP (orig, 0), 0)))
+           {
+             if (reg == NULL || !reload_in_progress)
+               reg = gen_reg_rtx (Pmode);
+
+             emit_move_insn (reg, XEXP (XEXP (orig, 0), 0));
+             pic_ref = plus_constant_for_output (reg, INTVAL (XEXP (XEXP (orig, 0), 1)));
+           }
+         else
+#endif
+           if (code != CODE_FOR_movsi)
+             {
+               if (reg == NULL || !reload_in_progress)
+                 reg = gen_reg_rtx (Pmode);
+
+               emit_move_insn (reg, orig);
+               pic_ref = reg;
+             }
+       }
+      else
+       {
+         if (GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
+             || GET_CODE (XEXP (XEXP (orig, 0), 1)) == SYMBOL_REF)
+           {
+             debug_rtx (orig);
+             abort ();
+           }
+       }
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+    }
+  else if (GET_CODE (orig) == PLUS
+          && GET_CODE (XEXP (orig, 0)) == CONST_INT
+          && GET_CODE (XEXP (orig, 1)) == SYMBOL_REF
+          && !SYMBOL_REF_FLAG (XEXP (orig, 1)))
+    {
+      if (reg == NULL || !reload_in_progress)
+        reg = gen_reg_rtx (Pmode);
+
+      emit_move_insn (reg, XEXP (orig, 1));
+      pic_ref = plus_constant_for_output (reg, INTVAL (XEXP (orig, 0)));
+    }
+  else if (GET_CODE (orig) == PLUS
+          && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
+          && !SYMBOL_REF_FLAG (XEXP (orig, 0))
+          && GET_CODE (XEXP (orig, 1)) == CONST_INT)
+    {
+      if (reg == NULL || !reload_in_progress)
+        reg = gen_reg_rtx (Pmode);
+
+      emit_move_insn (reg, XEXP (orig, 0));
+      pic_ref = plus_constant_for_output (reg, INTVAL (XEXP (orig, 1)));
+#endif
+    }
+#if 0
+  if (orig != pic_ref)
+    debug_rtx (orig);
+#endif
+ 
+  /* fprintf(stderr, "after: "); debug_rtx(pic_ref); */
+  return pic_ref;
+}
 
 #ifdef VMS_TARGET
 /* Additional support code for VMS target. */



Home | Main Index | Thread Index | Old Index