gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Aug 2007 15:40:26 +0000 (15:40 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Aug 2007 15:40:26 +0000 (15:40 +0000)
* config/mips/mips-protos.h (mips_address_insns): Add a boolean
argument.
(mips_fetch_insns): Delete in favor of...
(mips_load_store_insns): ...this new function.
* config/mips/mips.c (mips_address_insns): Add a boolean argument
to say whether multiword moves _might_ be split.
(mips_fetch_insns): Delete in favor of...
(mips_load_store_insns): ...this new function.
(mips_rtx_costs): Update the call to mips_address_insns.
(mips_address_cost): Likewise.
* config/mips/mips.md (length): Use mips_load_store_insns instead
of mips_fetch_insns.
* config/mips/constraints.md (R): Use mips_address_insns rather
than mips_fetch_insns.  Assume that the move never needs to be split.

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

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

index a62a76c..d514d48 100644 (file)
@@ -1,3 +1,20 @@
+2007-08-10  Richard Sandiford  <richard@codesourcery.com>
+
+       * config/mips/mips-protos.h (mips_address_insns): Add a boolean
+       argument.
+       (mips_fetch_insns): Delete in favor of...
+       (mips_load_store_insns): ...this new function.
+       * config/mips/mips.c (mips_address_insns): Add a boolean argument
+       to say whether multiword moves _might_ be split.
+       (mips_fetch_insns): Delete in favor of...
+       (mips_load_store_insns): ...this new function.
+       (mips_rtx_costs): Update the call to mips_address_insns.
+       (mips_address_cost): Likewise.
+       * config/mips/mips.md (length): Use mips_load_store_insns instead
+       of mips_fetch_insns.
+       * config/mips/constraints.md (R): Use mips_address_insns rather
+       than mips_fetch_insns.  Assume that the move never needs to be split.
+
 2007-08-09  Sandra Loosemore  <sandra@codesourcery.com>
 
        * config/mips/mips.opt (mhard-float, msoft-float):  Make these
index 3a28425..47b3966 100644 (file)
 (define_memory_constraint "R"
   "An address that can be used in a non-macro load or store."
   (and (match_code "mem")
-       (match_test "mips_fetch_insns (op) == 1")))
+       (match_test "mips_address_insns (XEXP (op, 0), mode, false) == 1")))
 
 (define_constraint "S"
   "@internal
index 2fec3ed..0a42ce1 100644 (file)
@@ -168,9 +168,9 @@ extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_context,
                                      enum mips_symbol_type *);
 extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, int);
 extern bool mips_stack_address_p (rtx, enum machine_mode);
-extern int mips_address_insns (rtx, enum machine_mode);
+extern int mips_address_insns (rtx, enum machine_mode, bool);
 extern int mips_const_insns (rtx);
-extern int mips_fetch_insns (rtx);
+extern int mips_load_store_insns (rtx, rtx);
 extern int mips_idiv_insns (void);
 extern int fp_register_operand (rtx, enum machine_mode);
 extern int lo_operand (rtx, enum machine_mode);
index ccd93fb..dce8042 100644 (file)
@@ -1945,22 +1945,26 @@ mips16_unextended_reference_p (enum machine_mode mode, rtx base, rtx offset)
 
 
 /* Return the number of instructions needed to load or store a value
-   of mode MODE at X.  Return 0 if X isn't valid for MODE.
+   of mode MODE at X.  Return 0 if X isn't valid for MODE.  Assume that
+   multiword moves may need to be split into word moves if MIGHT_SPLIT_P,
+   otherwise assume that a single load or store is enough.
 
    For mips16 code, count extended instructions as two instructions.  */
 
 int
-mips_address_insns (rtx x, enum machine_mode mode)
+mips_address_insns (rtx x, enum machine_mode mode, bool might_split_p)
 {
   struct mips_address_info addr;
   int factor;
 
-  if (mode == BLKmode)
-    /* BLKmode is used for single unaligned loads and stores.  */
-    factor = 1;
-  else
-    /* Each word of a multi-word value will be accessed individually.  */
+  /* BLKmode is used for single unaligned loads and stores and should
+     not count as a multiword mode.  (GET_MODE_SIZE (BLKmode) is pretty
+     meaningless, so we have to single it out as a special case one way
+     or the other.)  */
+  if (mode != BLKmode && might_split_p)
     factor = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  else
+    factor = 1;
 
   if (mips_classify_address (&addr, x, mode, false))
     switch (addr.type)
@@ -2059,14 +2063,30 @@ mips_const_insns (rtx x)
 }
 
 
-/* Return the number of instructions needed for memory reference X.
-   Count extended mips16 instructions as two instructions.  */
+/* Return the number of instructions needed to implement INSN,
+   given that it loads from or stores to MEM.  Count extended
+   mips16 instructions as two instructions.  */
 
 int
-mips_fetch_insns (rtx x)
+mips_load_store_insns (rtx mem, rtx insn)
 {
-  gcc_assert (MEM_P (x));
-  return mips_address_insns (XEXP (x, 0), GET_MODE (x));
+  enum machine_mode mode;
+  bool might_split_p;
+  rtx set;
+
+  gcc_assert (MEM_P (mem));
+  mode = GET_MODE (mem);
+
+  /* Try to prove that INSN does not need to be split.  */
+  might_split_p = true;
+  if (GET_MODE_BITSIZE (mode) == 64)
+    {
+      set = single_set (insn);
+      if (set && !mips_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
+       might_split_p = false;
+    }
+
+  return mips_address_insns (XEXP (mem, 0), mode, might_split_p);
 }
 
 
@@ -2857,7 +2877,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
        /* If the address is legitimate, return the number of
           instructions it needs.  */
        rtx addr = XEXP (x, 0);
-       int n = mips_address_insns (addr, GET_MODE (x));
+       int n = mips_address_insns (addr, GET_MODE (x), true);
        if (n > 0)
          {
            *total = COSTS_N_INSNS (n + 1);
@@ -3012,7 +3032,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
 static int
 mips_address_cost (rtx addr)
 {
-  return mips_address_insns (addr, SImode);
+  return mips_address_insns (addr, SImode, false);
 }
 \f
 /* Return one word of double-word value OP, taking into account the fixed
index 6ec2235..bac479f 100644 (file)
          (eq_attr "type" "const")
          (symbol_ref "mips_const_insns (operands[1]) * 4")
          (eq_attr "type" "load,fpload")
-         (symbol_ref "mips_fetch_insns (operands[1]) * 4")
+         (symbol_ref "mips_load_store_insns (operands[1], insn) * 4")
          (eq_attr "type" "store,fpstore")
-         (symbol_ref "mips_fetch_insns (operands[0]) * 4")
+         (symbol_ref "mips_load_store_insns (operands[0], insn) * 4")
 
          ;; In the worst case, a call macro will take 8 instructions:
          ;;