OSDN Git Service

gcc/
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Feb 2010 03:58:51 +0000 (03:58 +0000)
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Feb 2010 03:58:51 +0000 (03:58 +0000)
2010-02-20  David S. Miller  <davem@davemloft.net>

* configure.ac: Test if linker and assembler properly support
GOTDATA_OP relocations.
* configure: Rebuild.
* config.in: Likewise.
* config/sparc/sparc.md (UNSPEC_MOVE_GOTDATA): New.
(movsi_lo_sum_pic): Use %gdop_*() relocs if available.
(movsi_high_pic): Likewise.
(movdi_lo_sum_pic): Likewise.
(movdi_high_pic): Likewise.
(movsi_pic_gotdata_op): New pattern.
(movdi_pic_gotdata_op): Likewise.
* config/sparc/sparc.c (legitimize_pic_address): If flag_pic is 2,
emit gen_mov{si,di}_pic_gotdata_op for the GOT slot load.

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

gcc/ChangeLog
gcc/config.in
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/configure
gcc/configure.ac

index 105023b..8975aea 100644 (file)
@@ -1,3 +1,19 @@
+2010-02-20  David S. Miller  <davem@davemloft.net>
+
+       * configure.ac: Test if linker and assembler properly support
+       GOTDATA_OP relocations.
+       * configure: Rebuild.
+       * config.in: Likewise.
+       * config/sparc/sparc.md (UNSPEC_MOVE_GOTDATA): New.
+       (movsi_lo_sum_pic): Use %gdop_*() relocs if available.
+       (movsi_high_pic): Likewise.
+       (movdi_lo_sum_pic): Likewise.
+       (movdi_high_pic): Likewise.
+       (movsi_pic_gotdata_op): New pattern.
+       (movdi_pic_gotdata_op): Likewise.
+       * config/sparc/sparc.c (legitimize_pic_address): If flag_pic is 2,
+       emit gen_mov{si,di}_pic_gotdata_op for the GOT slot load.
+       
 2010-02-20  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/43067
index a3744f9..98dffa7 100644 (file)
 #endif
 
 
+/* Define if your assembler and linker support GOTDATA_OP relocs. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_SPARC_GOTDATA_OP
+#endif
+
+
 /* Define if your assembler and linker support unaligned PC relative relocs.
    */
 #ifndef USED_FOR_TARGET
index f366f78..c45460d 100644 (file)
@@ -3374,6 +3374,8 @@ legitimize_tls_address (rtx addr)
 static rtx
 legitimize_pic_address (rtx orig, rtx reg)
 {
+  bool gotdata_op = false;
+
   if (GET_CODE (orig) == SYMBOL_REF
       /* See the comment in sparc_expand_move.  */
       || (TARGET_VXWORKS_RTP && GET_CODE (orig) == LABEL_REF))
@@ -3410,15 +3412,28 @@ legitimize_pic_address (rtx orig, rtx reg)
              emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
            }
          address = temp_reg;
+         gotdata_op = true;
        }
       else
        address = orig;
 
-      pic_ref = gen_const_mem (Pmode,
-                              gen_rtx_PLUS (Pmode,
-                                            pic_offset_table_rtx, address));
       crtl->uses_pic_offset_table = 1;
-      insn = emit_move_insn (reg, pic_ref);
+      if (gotdata_op)
+       {
+         if (TARGET_ARCH64)
+           insn = emit_insn (gen_movdi_pic_gotdata_op (reg, pic_offset_table_rtx,
+                                                       address, orig));
+         else
+           insn = emit_insn (gen_movsi_pic_gotdata_op (reg, pic_offset_table_rtx,
+                                                       address, orig));
+       }
+      else
+       {
+         pic_ref = gen_const_mem (Pmode,
+                                  gen_rtx_PLUS (Pmode,
+                                                pic_offset_table_rtx, address));
+         insn = emit_move_insn (reg, pic_ref);
+       }
       /* Put a REG_EQUAL note on this insn, so that it can be optimized
         by loop.  */
       set_unique_reg_note (insn, REG_EQUAL, orig);
index caf8443..586c066 100644 (file)
@@ -38,6 +38,7 @@
    (UNSPEC_EMB_TEXTHI          14)
    (UNSPEC_EMB_TEXTULO         15)
    (UNSPEC_EMB_SETHM           18)
+   (UNSPEC_MOVE_GOTDATA                19)
 
    (UNSPEC_MEMBAR              20)
 
         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
   "flag_pic"
-  "or\t%1, %%lo(%a2), %0")
+{
+#ifdef HAVE_AS_SPARC_GOTDATA_OP
+  return "xor\t%1, %%gdop_lox10(%a2), %0";
+#else
+  return "or\t%1, %%lo(%a2), %0";
+#endif
+})
 
 (define_insn "movsi_high_pic"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
   "flag_pic && check_pic (1)"
-  "sethi\t%%hi(%a1), %0")
+{
+#ifdef HAVE_AS_SPARC_GOTDATA_OP
+  return "sethi\t%%gdop_hix22(%a1), %0";
+#else
+  return "sethi\t%%hi(%a1), %0";
+#endif
+})
+
+(define_insn "movsi_pic_gotdata_op"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:SI 2 "register_operand" "r")
+                   (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
+  "flag_pic && check_pic (1)"
+{
+#ifdef HAVE_AS_SPARC_GOTDATA_OP
+  return "ld\t[%1 + %2], %0, %%gdop(%a3)";
+#else
+  return "ld\t[%1 + %2], %0";
+#endif
+}
+  [(set_attr "type" "load")])
 
 (define_expand "movsi_pic_label_ref"
   [(set (match_dup 3) (high:SI
         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
   "TARGET_ARCH64 && flag_pic"
-  "or\t%1, %%lo(%a2), %0")
+{
+#ifdef HAVE_AS_SPARC_GOTDATA_OP
+  return "xor\t%1, %%gdop_lox10(%a2), %0";
+#else
+  return "or\t%1, %%lo(%a2), %0";
+#endif
+})
 
 (define_insn "movdi_high_pic"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
   "TARGET_ARCH64 && flag_pic && check_pic (1)"
-  "sethi\t%%hi(%a1), %0")
+{
+#ifdef HAVE_AS_SPARC_GOTDATA_OP
+  return "sethi\t%%gdop_hix22(%a1), %0";
+#else
+  return "sethi\t%%hi(%a1), %0";
+#endif
+})
+
+(define_insn "movdi_pic_gotdata_op"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "register_operand" "r")
+                   (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
+  "TARGET_ARCH64 && flag_pic && check_pic (1)"
+{
+#ifdef HAVE_AS_SPARC_GOTDATA_OP
+  return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
+#else
+  return "ldx\t[%1 + %2], %0";
+#endif
+}
+  [(set_attr "type" "load")])
 
 (define_insn "*sethi_di_medlow_embmedany_pic"
   [(set (match_operand:DI 0 "register_operand" "=r")
index a0e15ad..938f5c1 100755 (executable)
@@ -22491,6 +22491,51 @@ $as_echo "#define HAVE_AS_RELAX_OPTION 1" >>confdefs.h
 
 fi
 
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for GOTDATA_OP relocs" >&5
+$as_echo_n "checking assembler for GOTDATA_OP relocs... " >&6; }
+if test "${gcc_cv_as_sparc_gotdata_op+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_sparc_gotdata_op=no
+  if test x$gcc_cv_as != x; then
+    echo '.text
+foo:
+       nop
+bar:
+       sethi %gdop_hix22(foo), %g1
+       xor    %g1, %gdop_lox10(foo), %g1
+       ld    [%l7 + %g1], %g2, %gdop(foo)' > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags -K PIC -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+       if test x$gcc_cv_ld != x \
+       && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
+       && (test x$gnu_ld_flag = xno \
+           || (test x$gcc_cv_objdump != x \
+               && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
+                  | grep ' 03000004 82186004 c405c001'> /dev/null 2>&1)); then
+        gcc_cv_as_sparc_gotdata_op=yes
+       fi
+       rm -f conftest
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_gotdata_op" >&5
+$as_echo "$gcc_cv_as_sparc_gotdata_op" >&6; }
+if test $gcc_cv_as_sparc_gotdata_op = yes; then
+
+$as_echo "#define HAVE_AS_SPARC_GOTDATA_OP 1" >>confdefs.h
+
+fi
+
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for unaligned pcrel relocs" >&5
 $as_echo_n "checking assembler for unaligned pcrel relocs... " >&6; }
 if test "${gcc_cv_as_sparc_ua_pcrel+set}" = set; then :
index cd44af8..fe1ac55 100644 (file)
@@ -2944,6 +2944,28 @@ case "$target" in
       [AC_DEFINE(HAVE_AS_RELAX_OPTION, 1,
                [Define if your assembler supports -relax option.])])
 
+    gcc_GAS_CHECK_FEATURE([GOTDATA_OP relocs],
+      gcc_cv_as_sparc_gotdata_op,,
+      [-K PIC],
+[.text
+foo:
+       nop
+bar:
+       sethi %gdop_hix22(foo), %g1
+       xor    %g1, %gdop_lox10(foo), %g1
+       ld    [[%l7 + %g1]], %g2, %gdop(foo)],
+      [if test x$gcc_cv_ld != x \
+       && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
+       && (test x$gnu_ld_flag = xno \
+           || (test x$gcc_cv_objdump != x \
+               && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
+                  | grep ' 03000004 82186004 c405c001'> /dev/null 2>&1)); then
+        gcc_cv_as_sparc_gotdata_op=yes
+       fi
+       rm -f conftest],
+      [AC_DEFINE(HAVE_AS_SPARC_GOTDATA_OP, 1,
+               [Define if your assembler and linker support GOTDATA_OP relocs.])])
+
     gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs],
       gcc_cv_as_sparc_ua_pcrel,,
       [-K PIC],