diff mbox

[SPARC] Fix PR target/44707

Message ID 201007252347.16520.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou July 25, 2010, 9:47 p.m. UTC
We need the same treatment on the SPARC as on the PowerPC, see
  http://gcc.gnu.org/ml/gcc-patches/2010-07/msg00082.html

Tested on SPARC/Solaris and SPARC64/Solaris, applied on the mainline.


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.
diff mbox

Patch

Index: config/sparc/sparc-protos.h
===================================================================
--- config/sparc/sparc-protos.h	(revision 162502)
+++ config/sparc/sparc-protos.h	(working copy)
@@ -63,6 +63,8 @@  extern void emit_tfmode_cvt (enum rtx_co
 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: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 162502)
+++ config/sparc/sparc.c	(working copy)
@@ -51,6 +51,7 @@  along with GCC; see the file COPYING3.
 #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 mod
       && 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 mod
   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 mod
 
       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 re
       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 re
 	}
 
       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 old
     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 old
   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
 	  /* 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: config/sparc/sparc.h
===================================================================
--- config/sparc/sparc.h	(revision 162502)
+++ config/sparc/sparc.h	(working copy)
@@ -1801,36 +1801,14 @@  do {									\
 
 /* 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)
 
 /* Specify the machine mode that this machine uses