OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 May 2007 11:15:07 +0000 (11:15 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 May 2007 11:15:07 +0000 (11:15 +0000)
* config.gcc (sparc-wrs-vxworks): New target.
* config/sparc/vxworks.h, config/sparc/t-vxworks: New files.
* config/sparc/sparc-protos.h (sparc_emit_call_insn): Declare.
* config/sparc/sparc.h: Include vxworks-dummy.h.
(PRINT_OPERAND_ADDRESS): Extend SYMBOL_REF handling to
include LABEL_REFs too.
* config/sparc/sparc.c (sparc_expand_move): Don't assume that
_GLOBAL_OFFSET_TABLE_ - label_ref is a link-time constant on
VxWorks.
(legitimize_pic_address): Handle LABEL_REFs like SYMBOL_REFs
on VxWorks.
(load_pic_register): Use gen_vxworks_load_got for VxWorks.
(sparc_emit_call_insn): New function.
(sparc_function_ok_for_sibcall): Restrict sibcalls to locally-binding
functions when generating VxWorks PIC.
* config/sparc/sparc.md (vxworks_load_got): New pattern.
(call, call_value): Use sparc_emit_call_insn instead of
emit_call_insn.

libgcc/
* config.host (sparc-wrs-vxworks): New target.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124595 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config.gcc
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md
gcc/config/sparc/t-vxworks [new file with mode: 0644]
gcc/config/sparc/vxworks.h [new file with mode: 0644]
libgcc/ChangeLog
libgcc/config.host

index afae5e2..60c3c9c 100644 (file)
@@ -1,3 +1,24 @@
+2007-05-10  Richard Sandiford  <richard@codesourcery.com>
+
+       * config.gcc (sparc-wrs-vxworks): New target.
+       * config/sparc/vxworks.h, config/sparc/t-vxworks: New files.
+       * config/sparc/sparc-protos.h (sparc_emit_call_insn): Declare.
+       * config/sparc/sparc.h: Include vxworks-dummy.h.
+       (PRINT_OPERAND_ADDRESS): Extend SYMBOL_REF handling to
+       include LABEL_REFs too.
+       * config/sparc/sparc.c (sparc_expand_move): Don't assume that
+       _GLOBAL_OFFSET_TABLE_ - label_ref is a link-time constant on
+       VxWorks.
+       (legitimize_pic_address): Handle LABEL_REFs like SYMBOL_REFs
+       on VxWorks.
+       (load_pic_register): Use gen_vxworks_load_got for VxWorks.
+       (sparc_emit_call_insn): New function.
+       (sparc_function_ok_for_sibcall): Restrict sibcalls to locally-binding
+       functions when generating VxWorks PIC.
+       * config/sparc/sparc.md (vxworks_load_got): New pattern.
+       (call, call_value): Use sparc_emit_call_insn instead of
+       emit_call_insn.
+
 2007-05-09  Bob Wilson  <bob.wilson@acm.org>
        
        * config/xtensa/xtensa.c (xtensa_output_literal): Don't use #if.
index 31b10d4..a26f3dd 100644 (file)
@@ -2370,6 +2370,10 @@ sparc-*-sysv4*)
        extra_parts="crtbegin.o crtend.o"
        use_fixproto=yes
        ;;
+sparc-wrs-vxworks)
+       tm_file="${tm_file} elfos.h svr4.h sparc/sysv4.h vx-common.h vxworks.h sparc/vxworks.h"
+       tmake_file="${tmake_file} sparc/t-vxworks"
+       ;;
 sparc64-*-elf*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sp64-elf.h"
        extra_options="${extra_options} sparc/little-endian.opt"
index 4fb862c..c1b2813 100644 (file)
@@ -73,6 +73,7 @@ extern int legitimate_address_p (enum machine_mode, rtx, int);
 extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
 extern rtx legitimize_tls_address (rtx);
 extern rtx legitimize_address (rtx, rtx, enum machine_mode);
+extern void sparc_emit_call_insn (rtx, rtx);
 extern void sparc_defer_case_vector (rtx, rtx, int);
 extern bool sparc_expand_move (enum machine_mode, rtx *);
 extern void sparc_emit_set_const32 (rtx, rtx);
index be07ce7..f94af2a 100644 (file)
@@ -980,17 +980,27 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
       if (pic_address_needs_scratch (operands[1]))
        operands[1] = legitimize_pic_address (operands[1], mode, 0);
 
-      if (GET_CODE (operands[1]) == LABEL_REF && mode == SImode)
-       {
-         emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
-         return true;
-       }
+      /* VxWorks does not impose a fixed gap between segments; the run-time
+        gap can be different from the object-file gap.  We therefore can't
+        assume X - _GLOBAL_OFFSET_TABLE_ is a link-time constant unless we
+        are absolutely sure that X is in the same segment as the GOT.
+        Unfortunately, the flexibility of linker scripts means that we
+        can't be sure of that in general, so assume that _G_O_T_-relative
+        accesses are never valid on VxWorks.  */
+      if (GET_CODE (operands[1]) == LABEL_REF && !TARGET_VXWORKS_RTP)
+       {
+         if (mode == SImode)
+           {
+             emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
+             return true;
+           }
 
-      if (GET_CODE (operands[1]) == LABEL_REF && mode == DImode)
-       {
-         gcc_assert (TARGET_ARCH64);
-         emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
-         return true;
+         if (mode == DImode)
+           {
+             gcc_assert (TARGET_ARCH64);
+             emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
+             return true;
+           }
        }
 
       if (symbolic_operand (operands[1], mode))
@@ -3212,7 +3222,9 @@ rtx
 legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
                        rtx reg)
 {
-  if (GET_CODE (orig) == SYMBOL_REF)
+  if (GET_CODE (orig) == SYMBOL_REF
+      /* See the comment in sparc_expand_move.  */
+      || (TARGET_VXWORKS_RTP && GET_CODE (orig) == LABEL_REF))
     {
       rtx pic_ref, address;
       rtx insn;
@@ -3377,6 +3389,13 @@ load_pic_register (bool delay_pic_helper)
 {
   int orig_flag_pic = flag_pic;
 
+  if (TARGET_VXWORKS_RTP)
+    {
+      emit_insn (gen_vxworks_load_got ());
+      emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
+      return;
+    }
+
   /* If we haven't initialized the special PIC symbols, do so now.  */
   if (!pic_helper_symbol_name[0])
     {
@@ -3405,6 +3424,29 @@ load_pic_register (bool delay_pic_helper)
      since we may not fall out the bottom.  */
   emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
 }
+
+/* Emit a call instruction with the pattern given by PAT.  ADDR is the
+   address of the call target.  */
+
+void
+sparc_emit_call_insn (rtx pat, rtx addr)
+{
+  rtx insn;
+
+  insn = emit_call_insn (pat);
+
+  /* The PIC register is live on entry to VxWorks PIC PLT entries.  */
+  if (TARGET_VXWORKS_RTP
+      && flag_pic
+      && GET_CODE (addr) == SYMBOL_REF
+      && (SYMBOL_REF_DECL (addr)
+         ? !targetm.binds_local_p (SYMBOL_REF_DECL (addr))
+         : !SYMBOL_REF_LOCAL_P (addr)))
+    {
+      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+      current_function_uses_pic_offset_table = 1;
+    }
+}
 \f
 /* Return 1 if RTX is a MEM which is known to be aligned to at
    least a DESIRED byte boundary.  */
@@ -7771,13 +7813,19 @@ sparc_elf_asm_named_section (const char *name, unsigned int flags,
    the sibling call right?  Well, in the C++ case we can end up passing
    the pointer to the struct return area to a constructor (which returns
    void) and then nothing else happens.  Such a sibling call would look
-   valid without the added check here.  */
+   valid without the added check here.
+
+   VxWorks PIC PLT entries require the global pointer to be initialized
+   on entry.  We therefore can't emit sibling calls to them.  */
 static bool
 sparc_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
 {
   return (decl
          && flag_delayed_branch
-         && (TARGET_ARCH64 || ! current_function_returns_struct));
+         && (TARGET_ARCH64 || ! current_function_returns_struct)
+         && !(TARGET_VXWORKS_RTP
+              && flag_pic
+              && !targetm.binds_local_p (decl)));
 }
 \f
 /* libfunc renaming.  */
index db0e34e..1a4805b 100644 (file)
@@ -22,6 +22,8 @@ along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.  */
 
+#include "config/vxworks-dummy.h"
+
 /* Note that some other tm.h files include this one and then override
    whatever definitions are necessary.  */
 
@@ -2409,6 +2411,7 @@ extern int sparc_indent_opcode;
          else if (GET_CODE (index) == REG)                     \
            fprintf (FILE, "+%s", reg_names[REGNO (index)]);    \
          else if (GET_CODE (index) == SYMBOL_REF               \
+                  || GET_CODE (index) == LABEL_REF             \
                   || GET_CODE (index) == CONST)                \
            fputc ('+', FILE), output_addr_const (FILE, index); \
          else gcc_unreachable ();                              \
index 387b340..6d5797d 100644 (file)
   "flag_pic"
   "or\t%1, %%lo(%a3-(%a2-.)), %0")
 
+;; Set up the PIC register for VxWorks.
+
+(define_expand "vxworks_load_got"
+  [(set (match_dup 0)
+       (high:SI (match_dup 1)))
+   (set (match_dup 0)
+       (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
+   (set (match_dup 0)
+       (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
+  "TARGET_VXWORKS_RTP"
+{
+  operands[0] = pic_offset_table_rtx;
+  operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
+  operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
+})
+
 (define_expand "movdi"
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
        (match_operand:DI 1 "general_operand" ""))]
 {
   rtx fn_rtx;
 
-  gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
+  gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
 
   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
 
 
   /* We accept negative sizes for untyped calls.  */
   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
-    emit_call_insn
+    sparc_emit_call_insn
       (gen_rtx_PARALLEL
        (VOIDmode,
        gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
                   operands[3],
-                  gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
+                  gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
+       XEXP (fn_rtx, 0));
   else
-    emit_call_insn
+    sparc_emit_call_insn
       (gen_rtx_PARALLEL
        (VOIDmode,
        gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
-                  gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
+                  gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
+       XEXP (fn_rtx, 0));
 
  finish_call:
 
   rtx fn_rtx;
   rtvec vec;
 
-  gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
+  gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
 
   fn_rtx = operands[1];
 
                                gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
                   gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
 
-  emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
+  sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
 
   DONE;
 })
diff --git a/gcc/config/sparc/t-vxworks b/gcc/config/sparc/t-vxworks
new file mode 100644 (file)
index 0000000..2aabf1a
--- /dev/null
@@ -0,0 +1,5 @@
+# Multilibs for VxWorks.
+
+MULTILIB_OPTIONS = mrtp fPIC
+MULTILIB_MATCHES = fPIC=fpic
+MULTILIB_EXCEPTIONS = fPIC
diff --git a/gcc/config/sparc/vxworks.h b/gcc/config/sparc/vxworks.h
new file mode 100644 (file)
index 0000000..7faacea
--- /dev/null
@@ -0,0 +1,64 @@
+/* Definitions of target machine for GNU compiler,
+   for SPARC targeting the VxWorks run time environment.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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.
+
+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 GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define TARGET_OS_CPP_BUILTINS()               \
+  do                                           \
+    {                                          \
+      builtin_define ("__sparc");              \
+      builtin_define ("CPU=SIMSPARCSOLARIS");  \
+      VXWORKS_OS_CPP_BUILTINS ();              \
+    }                                          \
+  while (0)
+
+#undef OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS                       \
+  do                                           \
+    {                                          \
+      VXWORKS_OVERRIDE_OPTIONS;                        \
+      sparc_override_options ();               \
+    }                                          \
+  while (0)
+
+#undef CPP_SUBTARGET_SPEC
+#define CPP_SUBTARGET_SPEC VXWORKS_ADDITIONAL_CPP_SPEC
+
+#undef LIB_SPEC
+#define LIB_SPEC VXWORKS_LIB_SPEC
+#undef LINK_SPEC
+#define LINK_SPEC VXWORKS_LINK_SPEC
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC VXWORKS_STARTFILE_SPEC
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC VXWORKS_ENDFILE_SPEC
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (SPARC/VxWorks)", stderr);
+
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER
+
+/* Use standard numbered ctors/dtors sections.  */
+#undef CTORS_SECTION_ASM_OP
+#undef DTORS_SECTION_ASM_OP
+
+/* We cannot use PC-relative accesses for VxWorks PIC because there is no
+   fixed gap between segments.  */
+#undef ASM_PREFERRED_EH_DATA_FORMAT
index 7e3afac..8baa49f 100644 (file)
@@ -1,3 +1,7 @@
+2007-05-10  Richard Sandiford  <richard@codesourcery.com>
+
+       * config.host (sparc-wrs-vxworks): New target.
+
 2007-04-14  Kazu Hirata  <kazu@codesourcery.com>
 
        * config.host: Recognize fido.
index f43de44..4de74cf 100644 (file)
@@ -594,6 +594,8 @@ sparc-*-sysv4*)
        ;;
 sparc64-*-elf*)
        ;;
+sparc-wrs-vxworks)
+       ;;
 sparc64-*-freebsd*|ultrasparc-*-freebsd*)
        ;;
 sparc64-*-linux*)              # 64-bit SPARC's running GNU/Linux