This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed, 5/7] MIPS -mcode-readable support


This is the fifth patch in the -mcode-readable series.

Life used to be simple for mips_split_symbol: when generating MIPS16 code,
the high part of a symbol was a copy of the $gp constant; when generating
non-MIPS16 code, the high part of a symbol was a HIGH expression.
However, we now need to use HIGH for MIPS16 too.  mips_split_symbol must
therefore choose the high part based on the symbol type rather than the
MIPS16 mode.

mips_split_symbol is currently defined in such a way that the caller
checks whether a split is needed.  This check involves determining the
symbol type, so rather than pass the type down to mips_split_symbol,
it seemed better to move the "is a split needed?" check to
mips_split_symbol itself.  The patch below does that.

Tested in the same way as the first patch.  Applied.

Richard


gcc/
	* config/mips/mips-protos.h (mips_split_symbol): Add a mode and
	an "rtx *" argument.  Return a bool.
	* config/mips/mips.c (mips_split_symbol): Accept arbitrary source
	values and return true if they can be split.  Take the same kind of
	mode argument as mips_symbol_insns.  Add a "lo_sum_out" parameter
	and store the lo_sum there if nonnull.  Use the symbol type to
	determine whether a $gp or HIGH is needed.
	(mips_legitimize_address): Update call to mips_split_symbol and
	simplify accordingly.
	(mips_legitimize_const_move): Likewise.
	* config/mips/mips.md: In the combine define_split,
	check mips_split_symbol instead of splittable_symbolic_operand.
	Update use of mips_split_symbol in the generator code.
	* config/mips/predicates.md (splittable_symbolic_operand): Delete.

Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h	2007-07-28 12:41:01.000000000 -0700
+++ gcc/config/mips/mips-protos.h	2007-07-31 02:57:35.000000000 -0700
@@ -172,7 +172,7 @@ extern int mips_idiv_insns (void);
 extern int fp_register_operand (rtx, enum machine_mode);
 extern int lo_operand (rtx, enum machine_mode);
 extern bool mips_legitimate_address_p (enum machine_mode, rtx, int);
-extern rtx mips_split_symbol (rtx, rtx);
+extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *);
 extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
 extern bool mips_legitimize_address (rtx *, enum machine_mode);
 extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT);
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2007-07-28 12:41:02.000000000 -0700
+++ gcc/config/mips/mips.c	2007-07-31 02:58:08.000000000 -0700
@@ -2114,24 +2114,50 @@ mips_force_temporary (rtx dest, rtx valu
 }
 
 
-/* Return a LO_SUM expression for ADDR.  TEMP is as for mips_force_temporary
-   and is used to load the high part into a register.  */
+/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
+   it appears in a MEM of that mode.  Return true if ADDR is a legitimate
+   constant in that context and can be split into a high part and a LO_SUM.
+   If so, and if LO_SUM_OUT is nonnull, emit the high part and return
+   the LO_SUM in *LO_SUM_OUT.  Leave *LO_SUM_OUT unchanged otherwise.
 
-rtx
-mips_split_symbol (rtx temp, rtx addr)
+   TEMP is as for mips_force_temporary and is used to load the high
+   part into a register.  */
+
+bool
+mips_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *lo_sum_out)
 {
+  enum mips_symbol_context context;
+  enum mips_symbol_type symbol_type;
   rtx high;
 
-  if (!TARGET_MIPS16)
-    high = mips_force_temporary (temp, gen_rtx_HIGH (Pmode, copy_rtx (addr)));
-  else if (!can_create_pseudo_p ())
+  context = (mode == MAX_MACHINE_MODE
+	     ? SYMBOL_CONTEXT_LEA
+	     : SYMBOL_CONTEXT_MEM);
+  if (!mips_symbolic_constant_p (addr, context, &symbol_type)
+      || mips_symbol_insns (symbol_type, mode) == 0
+      || !mips_split_p[symbol_type])
+    return false;
+
+  if (lo_sum_out)
     {
-      emit_insn (gen_load_const_gp (copy_rtx (temp)));
-      high = temp;
+      if (symbol_type == SYMBOL_GP_RELATIVE)
+	{
+	  if (!can_create_pseudo_p ())
+	    {
+	      emit_insn (gen_load_const_gp (copy_rtx (temp)));
+	      high = temp;
+	    }
+	  else
+	    high = mips16_gp_pseudo_reg ();
+	}
+      else
+	{
+	  high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
+	  high = mips_force_temporary (temp, high);
+	}
+      *lo_sum_out = gen_rtx_LO_SUM (Pmode, high, addr);
     }
-  else
-    high = mips16_gp_pseudo_reg ();
-  return gen_rtx_LO_SUM (Pmode, high, addr);
+  return true;
 }
 
 
@@ -2322,8 +2348,6 @@ mips_legitimize_tls_address (rtx loc)
 bool
 mips_legitimize_address (rtx *xloc, enum machine_mode mode)
 {
-  enum mips_symbol_type symbol_type;
-
   if (mips_tls_operand_p (*xloc))
     {
       *xloc = mips_legitimize_tls_address (*xloc);
@@ -2331,13 +2355,8 @@ mips_legitimize_address (rtx *xloc, enum
     }
 
   /* See if the address can split into a high part and a LO_SUM.  */
-  if (mips_symbolic_constant_p (*xloc, SYMBOL_CONTEXT_MEM, &symbol_type)
-      && mips_symbol_insns (symbol_type, mode) > 0
-      && mips_split_p[symbol_type])
-    {
-      *xloc = mips_split_symbol (0, *xloc);
-      return true;
-    }
+  if (mips_split_symbol (NULL, *xloc, mode, xloc))
+    return true;
 
   if (GET_CODE (*xloc) == PLUS && GET_CODE (XEXP (*xloc, 1)) == CONST_INT)
     {
@@ -2506,9 +2525,9 @@ mips_legitimize_const_move (enum machine
     }
 
   /* Split moves of symbolic constants into high/low pairs.  */
-  if (splittable_symbolic_operand (src, mode))
+  if (mips_split_symbol (dest, src, MAX_MACHINE_MODE, &src))
     {
-      emit_insn (gen_rtx_SET (VOIDmode, dest, mips_split_symbol (dest, src)));
+      emit_insn (gen_rtx_SET (VOIDmode, dest, src));
       return;
     }
 
@@ -2535,8 +2554,7 @@ mips_legitimize_const_move (enum machine
 
   /* When using explicit relocs, constant pool references are sometimes
      not legitimate addresses.  */
-  if (!memory_operand (src, VOIDmode))
-    src = replace_equiv_address (src, mips_split_symbol (dest, XEXP (src, 0)));
+  mips_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0));
   emit_move_insn (dest, src);
 }
 
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	2007-07-28 12:30:41.000000000 -0700
+++ gcc/config/mips/mips.md	2007-07-31 02:57:56.000000000 -0700
@@ -3300,11 +3300,14 @@ (define_split
 ;; Likewise, for symbolic operands.
 (define_split
   [(set (match_operand:P 0 "register_operand")
-	(match_operand:P 1 "splittable_symbolic_operand"))
+	(match_operand:P 1))
    (clobber (match_operand:P 2 "register_operand"))]
-  ""
-  [(set (match_dup 0) (match_dup 1))]
-  { operands[1] = mips_split_symbol (operands[2], operands[1]); })
+  "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
+  [(set (match_dup 0) (match_dup 3))]
+{
+  mips_split_symbol (operands[2], operands[1],
+		     MAX_MACHINE_MODE, &operands[3]);
+})
 
 ;; 64-bit integer moves
 
Index: gcc/config/mips/predicates.md
===================================================================
--- gcc/config/mips/predicates.md	2007-07-28 12:38:49.000000000 -0700
+++ gcc/config/mips/predicates.md	2007-07-31 02:23:13.000000000 -0700
@@ -155,16 +155,6 @@ (define_predicate "splittable_const_int_
   return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op);
 })
 
-;; A legitimate symbolic operand that takes more than one instruction
-;; to load.
-(define_predicate "splittable_symbolic_operand"
-  (match_code "const,symbol_ref,label_ref")
-{
-  enum mips_symbol_type symbol_type;
-  return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
-	  && mips_split_p[symbol_type]);
-})
-
 (define_predicate "move_operand"
   (match_operand 0 "general_operand")
 {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]