mips-protos.h (mips_split_symbol): Add a mode and an "rtx *" argument.
authorRichard Sandiford <richard@codesourcery.com>
Wed, 8 Aug 2007 15:40:27 +0000 (15:40 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 8 Aug 2007 15:40:27 +0000 (15:40 +0000)
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.

From-SVN: r127298

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.md
gcc/config/mips/predicates.md

index a2e4f6ae352933353c8049cebca674319ceb4e2f..63d49c35a9d0f261bc29908b6fb462b0f5a8fbca 100644 (file)
@@ -1,3 +1,20 @@
+2007-08-08  Richard Sandiford  <richard@codesourcery.com>
+
+       * 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.
+
 2007-08-08  Richard Sandiford  <richard@codesourcery.com>
 
        * config/mips/mips.c (mips_symbolic_address_p): Delete.
index 13cbfbfc34114a9648b0590928242e8a190829c3..d2f501740f0052eee7c01e5fd3c5cfb945482bde 100644 (file)
@@ -171,7 +171,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 b8e013e984d69d244e9d6c96712b8526a153658f..2b620fbb20ba4606f65fb2556ce92d08772bd371 100644 (file)
@@ -2113,24 +2113,50 @@ mips_force_temporary (rtx dest, rtx value)
 }
 
 
-/* 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;
 }
 
 
@@ -2321,8 +2347,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);
@@ -2330,13 +2354,8 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode)
     }
 
   /* 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)
     {
@@ -2505,9 +2524,9 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
     }
 
   /* 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;
     }
 
@@ -2534,8 +2553,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
 
   /* 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 e522f4e44ec12704df7920dc5aee77e3d168009c..2e3d52243cfc9377c1ff7bb6aa2b143f1a8e6b93 100644 (file)
 ;; 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 1171291f508a603530d0dded00048cb9092c833b..308dd636f57ccd001315dddf6011f0e884ff52b7 100644 (file)
   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")
 {