]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Oct 2008 08:04:22 +0000 (08:04 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Oct 2008 08:04:22 +0000 (08:04 +0000)
* config/mips/mips.c (mips_canonicalize_move_class): New function.
(mips_move_to_gpr_cost): Likewise.
(mips_move_from_gpr_cost): Likewise.
(mips_register_move_cost): Make more fine-grained.

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

gcc/ChangeLog
gcc/config/mips/mips.c

index 1ade1e74eac2f277de708d076a0f608709d894d8..76d8c014ab286d6765ee8beaa59004667c8a778b 100644 (file)
@@ -1,3 +1,10 @@
+2008-10-24  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/mips/mips.c (mips_canonicalize_move_class): New function.
+       (mips_move_to_gpr_cost): Likewise.
+       (mips_move_from_gpr_cost): Likewise.
+       (mips_register_move_cost): Make more fine-grained.
+
 2008-10-23  Tobias Grosser  <grosser@fim.uni-passau.de>
 
        * graphite.c (graphite_apply_transformations): Check for
index eb76ff4791eef5d9fb3054418766f559e0486923..f566e03155bc3e5d873f3aba54b7bbff67047714 100644 (file)
@@ -9689,62 +9689,142 @@ mips_preferred_reload_class (rtx x, enum reg_class rclass)
   return rclass;
 }
 
-/* Implement REGISTER_MOVE_COST.  */
+/* RCLASS is a class involved in a REGISTER_MOVE_COST calculation.
+   Return a "canonical" class to represent it in later calculations.  */
 
-int
-mips_register_move_cost (enum machine_mode mode,
-                        enum reg_class to, enum reg_class from)
+static enum reg_class
+mips_canonicalize_move_class (enum reg_class rclass)
 {
-  if (TARGET_MIPS16)
+  /* All moves involving accumulator registers have the same cost.  */
+  if (reg_class_subset_p (rclass, ACC_REGS))
+    rclass = ACC_REGS;
+
+  /* Likewise promote subclasses of general registers to the most
+     interesting containing class.  */
+  if (TARGET_MIPS16 && reg_class_subset_p (rclass, M16_REGS))
+    rclass = M16_REGS;
+  else if (reg_class_subset_p (rclass, GENERAL_REGS))
+    rclass = GENERAL_REGS;
+
+  return rclass;
+}
+
+/* Return the cost of moving a value of mode MODE from a register of
+   class FROM to a GPR.  Return 0 for classes that are unions of other
+   classes handled by this function.  */
+
+static int
+mips_move_to_gpr_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
+                      enum reg_class from)
+{
+  switch (from)
     {
-      if (reg_class_subset_p (from, GENERAL_REGS)
-         && reg_class_subset_p (to, GENERAL_REGS))
-       {
-         if (reg_class_subset_p (from, M16_REGS)
-             || reg_class_subset_p (to, M16_REGS))
-           return 2;
-         /* Two MOVEs.  */
-         return 4;
-       }
+    case GENERAL_REGS:
+      /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro.  */
+      return 2;
+
+    case ACC_REGS:
+      /* MFLO and MFHI.  */
+      return 6;
+
+    case FP_REGS:
+      /* MFC1, etc.  */
+      return 4;
+
+    case ST_REGS:
+      /* LUI followed by MOVF.  */
+      return 4;
+
+    case COP0_REGS:
+    case COP2_REGS:
+    case COP3_REGS:
+      /* This choice of value is historical.  */
+      return 5;
+
+    default:
+      return 0;
     }
-  else if (reg_class_subset_p (from, GENERAL_REGS))
+}
+
+/* Return the cost of moving a value of mode MODE from a GPR to a
+   register of class TO.  Return 0 for classes that are unions of
+   other classes handled by this function.  */
+
+static int
+mips_move_from_gpr_cost (enum machine_mode mode, enum reg_class to)
+{
+  switch (to)
     {
-      if (reg_class_subset_p (to, GENERAL_REGS))
-       return 2;
-      if (reg_class_subset_p (to, FP_REGS))
-       return 4;
-      if (reg_class_subset_p (to, COP0_REGS)
-         || reg_class_subset_p (to, COP2_REGS)
-         || reg_class_subset_p (to, COP3_REGS))
-       return 5;
-      if (reg_class_subset_p (to, ACC_REGS))
-       return 6;
+    case GENERAL_REGS:
+      /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro.  */
+      return 2;
+
+    case ACC_REGS:
+      /* MTLO and MTHI.  */
+      return 6;
+
+    case FP_REGS:
+      /* MTC1, etc.  */
+      return 4;
+
+    case ST_REGS:
+      /* A secondary reload through an FPR scratch.  */
+      return (mips_register_move_cost (mode, GENERAL_REGS, FP_REGS)
+             + mips_register_move_cost (mode, FP_REGS, ST_REGS));
+
+    case COP0_REGS:
+    case COP2_REGS:
+    case COP3_REGS:
+      /* This choice of value is historical.  */
+      return 5;
+
+    default:
+      return 0;
     }
-  else if (reg_class_subset_p (to, GENERAL_REGS))
+}
+
+/* Implement REGISTER_MOVE_COST.  Return 0 for classes that are the
+   maximum of the move costs for subclasses; regclass will work out
+   the maximum for us.  */
+
+int
+mips_register_move_cost (enum machine_mode mode,
+                        enum reg_class from, enum reg_class to)
+{
+  enum reg_class dregs;
+  int cost1, cost2;
+
+  from = mips_canonicalize_move_class (from);
+  to = mips_canonicalize_move_class (to);
+
+  /* Handle moves that can be done without using general-purpose registers.  */
+  if (from == FP_REGS)
     {
-      if (reg_class_subset_p (from, FP_REGS))
+      if (to == FP_REGS && mips_mode_ok_for_mov_fmt_p (mode))
+       /* MOV.FMT.  */
        return 4;
-      if (reg_class_subset_p (from, ST_REGS))
-       /* LUI followed by MOVF.  */
-       return 4;
-      if (reg_class_subset_p (from, COP0_REGS)
-         || reg_class_subset_p (from, COP2_REGS)
-         || reg_class_subset_p (from, COP3_REGS))
-       return 5;
-      if (reg_class_subset_p (from, ACC_REGS))
-       return 6;
+      if (to == ST_REGS)
+       /* The sequence generated by mips_expand_fcc_reload.  */
+       return 8;
     }
-  else if (reg_class_subset_p (from, FP_REGS))
+
+  /* Handle cases in which only one class deviates from the ideal.  */
+  dregs = TARGET_MIPS16 ? M16_REGS : GENERAL_REGS;
+  if (from == dregs)
+    return mips_move_from_gpr_cost (mode, to);
+  if (to == dregs)
+    return mips_move_to_gpr_cost (mode, from);
+
+  /* Handles cases that require a GPR temporary.  */
+  cost1 = mips_move_to_gpr_cost (mode, from);
+  if (cost1 != 0)
     {
-      if (reg_class_subset_p (to, FP_REGS)
-         && mips_mode_ok_for_mov_fmt_p (mode))
-       return 4;
-      if (reg_class_subset_p (to, ST_REGS))
-       /* An expensive sequence.  */
-       return 8;
+      cost2 = mips_move_from_gpr_cost (mode, to);
+      if (cost2 != 0)
+       return cost1 + cost2;
     }
 
-  return 12;
+  return 0;
 }
 
 /* Implement TARGET_IRA_COVER_CLASSES.  */