OSDN Git Service

PR target/44707
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Jul 2010 21:46:32 +0000 (21:46 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Jul 2010 21:46:32 +0000 (21:46 +0000)
* config/sparc/sparc-protos.h (sparc_legitimize_reload_address): New.
* config/sparc/sparc.c: Include reload.h.
(legitimize_tls_address): Rename into...
(sparc_legitimize_tls_address): ...this.
(legitimize_pic_address): Rename into...
(sparc_legitimize_pic_address): ...this.
(sparc_expand_move): Adjust to above renaming.
(sparc_tls_referenced_p): Likewise.
(sparc_legitimize_tls_address): Likewise.
(sparc_legitimize_pic_address): Likewise.
(sparc_legitimize_address): Likewise.
(sparc_output_mi_thunk): Likewise.
(sparc_legitimize_reload_address): New global function.  Recognize
(lo_sum (high ...) ...) patterns generated by earlier passes.
* config/sparc/sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Use above function.

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

gcc/ChangeLog
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h

index bd55715..8fc9c97 100644 (file)
@@ -1,5 +1,24 @@
 2010-07-25  Eric Botcazou  <ebotcazou@adacore.com>
 
+       PR target/44707
+       * config/sparc/sparc-protos.h (sparc_legitimize_reload_address): New.
+       * config/sparc/sparc.c: Include reload.h.
+       (legitimize_tls_address): Rename into...
+       (sparc_legitimize_tls_address): ...this.
+       (legitimize_pic_address): Rename into...
+       (sparc_legitimize_pic_address): ...this.
+       (sparc_expand_move): Adjust to above renaming.
+       (sparc_tls_referenced_p): Likewise.
+       (sparc_legitimize_tls_address): Likewise.
+       (sparc_legitimize_pic_address): Likewise.
+       (sparc_legitimize_address): Likewise.
+       (sparc_output_mi_thunk): Likewise.
+       (sparc_legitimize_reload_address): New global function.  Recognize
+       (lo_sum (high ...) ...) patterns generated by earlier passes.
+       * config/sparc/sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Use above function.
+
+2010-07-25  Eric Botcazou  <ebotcazou@adacore.com>
+
        PR target/44484
        * config/sparc/predicates.md (memory_reg_operand): Delete.
        * config/sparc/sync.md (sync_compare_and_swap): Minor tweaks.
index 35c99b9..f5efcb9 100644 (file)
@@ -63,6 +63,8 @@ extern void emit_tfmode_cvt (enum rtx_code, rtx *);
 extern bool legitimate_constant_p (rtx);
 extern bool constant_address_p (rtx);
 extern bool legitimate_pic_operand_p (rtx);
+extern rtx sparc_legitimize_reload_address (rtx, enum machine_mode, int, int,
+                                           int, int *win);
 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 *);
index d476955..48cf00e 100644 (file)
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfglayout.h"
 #include "gimple.h"
 #include "langhooks.h"
+#include "reload.h"
 #include "params.h"
 #include "df.h"
 #include "dwarf2out.h"
@@ -416,8 +417,8 @@ static void sparc_va_start (tree, rtx);
 static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
 static bool sparc_vector_mode_supported_p (enum machine_mode);
 static bool sparc_tls_referenced_p (rtx);
-static rtx legitimize_tls_address (rtx);
-static rtx legitimize_pic_address (rtx, rtx);
+static rtx sparc_legitimize_tls_address (rtx);
+static rtx sparc_legitimize_pic_address (rtx, rtx);
 static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode);
 static bool sparc_mode_dependent_address_p (const_rtx);
 static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
@@ -1006,7 +1007,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
       && CONSTANT_P (operands[1])
       && sparc_tls_referenced_p (operands [1]))
     {
-      operands[1] = legitimize_tls_address (operands[1]);
+      operands[1] = sparc_legitimize_tls_address (operands[1]);
       return false;
     }
 
@@ -1014,7 +1015,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
   if (flag_pic && CONSTANT_P (operands[1]))
     {
       if (pic_address_needs_scratch (operands[1]))
-       operands[1] = legitimize_pic_address (operands[1], NULL_RTX);
+       operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX);
 
       /* 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
@@ -1041,9 +1042,10 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
 
       if (symbolic_operand (operands[1], mode))
        {
-         operands[1] = legitimize_pic_address (operands[1],
-                                               reload_in_progress
-                                               ? operands[0] : NULL_RTX);
+         operands[1]
+           = sparc_legitimize_pic_address (operands[1],
+                                           reload_in_progress
+                                           ? operands[0] : NULL_RTX);
          return false;
        }
     }
@@ -3217,7 +3219,7 @@ sparc_tls_referenced_p (rtx x)
   if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
     return true;
 
-  /* That's all we handle in legitimize_tls_address for now.  */
+  /* That's all we handle in sparc_legitimize_tls_address for now.  */
   return false;
 }
 
@@ -3225,7 +3227,7 @@ sparc_tls_referenced_p (rtx x)
    this (thread-local) address.  */
 
 static rtx
-legitimize_tls_address (rtx addr)
+sparc_legitimize_tls_address (rtx addr)
 {
   rtx temp1, temp2, temp3, ret, o0, got, insn;
 
@@ -3354,7 +3356,7 @@ legitimize_tls_address (rtx addr)
 
       gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS);
 
-      base = legitimize_tls_address (XEXP (XEXP (addr, 0), 0));
+      base = sparc_legitimize_tls_address (XEXP (XEXP (addr, 0), 0));
       offset = XEXP (XEXP (addr, 0), 1);
 
       base = force_operand (base, NULL_RTX);
@@ -3375,7 +3377,7 @@ legitimize_tls_address (rtx addr)
    necessary.  */
 
 static rtx
-legitimize_pic_address (rtx orig, rtx reg)
+sparc_legitimize_pic_address (rtx orig, rtx reg)
 {
   bool gotdata_op = false;
 
@@ -3424,10 +3426,12 @@ legitimize_pic_address (rtx orig, rtx reg)
       if (gotdata_op)
        {
          if (TARGET_ARCH64)
-           insn = emit_insn (gen_movdi_pic_gotdata_op (reg, pic_offset_table_rtx,
+           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,
+           insn = emit_insn (gen_movsi_pic_gotdata_op (reg,
+                                                       pic_offset_table_rtx,
                                                        address, orig));
        }
       else
@@ -3457,9 +3461,9 @@ legitimize_pic_address (rtx orig, rtx reg)
        }
 
       gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
-      base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
-      offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
-                                      base == reg ? NULL_RTX : reg);
+      base = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
+      offset = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
+                                            base == reg ? NULL_RTX : reg);
 
       if (GET_CODE (offset) == CONST_INT)
        {
@@ -3515,9 +3519,9 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
     return x;
 
   if (sparc_tls_referenced_p (x))
-    x = legitimize_tls_address (x);
+    x = sparc_legitimize_tls_address (x);
   else if (flag_pic)
-    x = legitimize_pic_address (x, NULL_RTX);
+    x = sparc_legitimize_pic_address (x, NULL_RTX);
   else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1)))
     x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
                      copy_to_mode_reg (Pmode, XEXP (x, 1)));
@@ -3532,6 +3536,55 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
   return x;
 }
 
+/* SPARC implementation of LEGITIMIZE_RELOAD_ADDRESS.  Returns a value to
+   replace the input X, or the original X if no replacement is called for.
+   The output parameter *WIN is 1 if the calling macro should goto WIN,
+   0 if it should not.
+
+   For SPARC, we wish to handle addresses by splitting them into
+   HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
+   This cuts the number of extra insns by one.
+
+   Do nothing when generating PIC code and the address is a symbolic
+   operand or requires a scratch register.  */
+
+rtx
+sparc_legitimize_reload_address (rtx x, enum machine_mode mode,
+                                int opnum, int type,
+                                int ind_levels ATTRIBUTE_UNUSED, int *win)
+{
+  /* Decompose SImode constants into HIGH+LO_SUM.  */
+  if (CONSTANT_P (x)
+      && (mode != TFmode || TARGET_ARCH64)
+      && GET_MODE (x) == SImode
+      && GET_CODE (x) != LO_SUM
+      && GET_CODE (x) != HIGH
+      && sparc_cmodel <= CM_MEDLOW
+      && !(flag_pic
+          && (symbolic_operand (x, Pmode) || pic_address_needs_scratch (x))))
+    {
+      x = gen_rtx_LO_SUM (GET_MODE (x), gen_rtx_HIGH (GET_MODE (x), x), x);
+      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+                  BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+                  opnum, (enum reload_type)type);
+      *win = 1;
+      return x;
+    }
+
+  /* We have to recognize what we have already generated above.  */
+  if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == HIGH)
+    {
+      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+                  BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+                  opnum, (enum reload_type)type);
+      *win = 1;
+      return x;
+    }
+
+  *win = 0;
+  return x;
+}
+
 /* Return true if ADDR (a legitimate address expression)
    has an effect that depends on the machine mode it is used for.
 
@@ -9111,7 +9164,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
          /* Delay emitting the PIC helper function because it needs to
             change the section and we are emitting assembly code.  */
          load_pic_register ();  /* clobbers %o7 */
-         scratch = legitimize_pic_address (funexp, scratch);
+         scratch = sparc_legitimize_pic_address (funexp, scratch);
          seq = get_insns ();
          end_sequence ();
          emit_and_preserve (seq, spill_reg, spill_reg2);
index 6f6aec7..eae3959 100644 (file)
@@ -1801,36 +1801,14 @@ do {                                                                    \
 \f
 /* Try a machine-dependent way of reloading an illegitimate address
    operand.  If we find one, push the reload and jump to WIN.  This
-   macro is used in only one place: `find_reloads_address' in reload.c.
-
-   For SPARC 32, we wish to handle addresses by splitting them into
-   HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
-   This cuts the number of extra insns by one.
-
-   Do nothing when generating PIC code and the address is a
-   symbolic operand or requires a scratch register.  */
-
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)     \
-do {                                                                    \
-  /* Decompose SImode constants into hi+lo_sum.  We do have to                 \
-     rerecognize what we produce, so be careful.  */                   \
-  if (CONSTANT_P (X)                                                   \
-      && (MODE != TFmode || TARGET_ARCH64)                             \
-      && GET_MODE (X) == SImode                                                \
-      && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH                        \
-      && ! (flag_pic                                                   \
-           && (symbolic_operand (X, Pmode)                             \
-               || pic_address_needs_scratch (X)))                      \
-      && sparc_cmodel <= CM_MEDLOW)                                    \
-    {                                                                  \
-      X = gen_rtx_LO_SUM (GET_MODE (X),                                        \
-                         gen_rtx_HIGH (GET_MODE (X), X), X);           \
-      push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,          \
-                   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,       \
-                   OPNUM, TYPE);                                       \
-      goto WIN;                                                                \
-    }                                                                  \
-  /* ??? 64-bit reloads.  */                                           \
+   macro is used in only one place: `find_reloads_address' in reload.c.  */
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)       \
+do {                                                                      \
+  int win;                                                                \
+  (X) = sparc_legitimize_reload_address ((X), (MODE), (OPNUM),            \
+                                        (int)(TYPE), (IND_LEVELS), &win); \
+  if (win)                                                                \
+    goto WIN;                                                             \
 } while (0)
 \f
 /* Specify the machine mode that this machine uses