OSDN Git Service

PR target/19680
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Feb 2005 00:30:36 +0000 (00:30 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Feb 2005 00:30:36 +0000 (00:30 +0000)
        * config/i386/i386.h (MODES_TIEABLE_P): Use ix86_modes_tieable_p.
        * config/i386/i386.c (ix86_hard_regno_mode_ok): Change return
        type to bool.
        (ix86_tieable_integer_mode_p, ix86_modes_tieable_p): New.
        * config/i386/i386-protos.h: Update.

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

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h

index ac04aeb..6390a0b 100644 (file)
@@ -1,3 +1,12 @@
+2005-02-01  Richard Henderson  <rth@redhat.com
+
+       PR target/19680
+       * config/i386/i386.h (MODES_TIEABLE_P): Use ix86_modes_tieable_p.
+       * config/i386/i386.c (ix86_hard_regno_mode_ok): Change return
+       type to bool.
+       (ix86_tieable_integer_mode_p, ix86_modes_tieable_p): New.
+       * config/i386/i386-protos.h: Update.
+
 2005-02-01  Steven Bosscher  <stevenb@suse.de>
 
        PR tree-optimization/19217
index feacd2d..53edfd1 100644 (file)
@@ -180,7 +180,8 @@ extern rtx ix86_force_to_memory (enum machine_mode, rtx);
 extern void ix86_free_from_memory (enum machine_mode);
 extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
                                  rtx, rtx, rtx, rtx);
-extern int ix86_hard_regno_mode_ok (int, enum machine_mode);
+extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
+extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode);
 extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
                                    enum reg_class);
 extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
index f72bd3d..bc680c8 100644 (file)
@@ -14997,7 +14997,8 @@ ix86_register_move_cost (enum machine_mode mode, enum reg_class class1,
 }
 
 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE.  */
-int
+
+bool
 ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
 {
   /* Flags and only flags can only hold CCmode values.  */
@@ -15038,6 +15039,67 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
   return reload_in_progress || reload_completed || !TARGET_PARTIAL_REG_STALL;
 }
 
+/* A subroutine of ix86_modes_tieable_p.  Return true if MODE is a 
+   tieable integer mode.  */
+
+static bool
+ix86_tieable_integer_mode_p (enum machine_mode mode)
+{
+  switch (mode)
+    {
+    case HImode:
+    case SImode:
+      return true;
+
+    case QImode:
+      return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
+
+    case DImode:
+      return TARGET_64BIT;
+
+    default:
+      return false;
+    }
+}
+
+/* Return true if MODE1 is accessible in a register that can hold MODE2
+   without copying.  That is, all register classes that can hold MODE2
+   can also hold MODE1.  */
+
+bool
+ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+  if (mode1 == mode2)
+    return true;
+
+  if (ix86_tieable_integer_mode_p (mode1)
+      && ix86_tieable_integer_mode_p (mode2))
+    return true;
+
+  /* MODE2 being XFmode implies fp stack or general regs, which means we
+     can tie any smaller floating point modes to it.  Note that we do not
+     tie this with TFmode.  */
+  if (mode2 == XFmode)
+    return mode1 == SFmode || mode1 == DFmode;
+
+  /* MODE2 being DFmode implies fp stack, general or sse regs, which means
+     that we can tie it with SFmode.  */
+  if (mode2 == DFmode)
+    return mode1 == SFmode;
+
+  /* If MODE2 is only appropriate for an SSE register, then tie with 
+     any other mode acceptable to SSE registers.  */
+  if (SSE_REG_MODE_P (mode2))
+    return ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1);
+
+  /* If MODE2 is appropriate for an MMX (or SSE) register, then tie
+     with any other mode acceptable to MMX registers.  */
+  if (MMX_REG_MODE_P (mode2))
+    return ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1);
+
+  return false;
+}
+
 /* Return the cost of moving data of mode M between a
    register and memory.  A value of 2 is the default; this cost is
    relative to those in `REGISTER_MOVE_COST'.
index e155a4f..5c2046a 100644 (file)
@@ -1122,16 +1122,7 @@ do {                                                                     \
    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
    for any hard reg, then this must be 0 for correct output.  */
 
-#define MODES_TIEABLE_P(MODE1, MODE2)                          \
-  ((MODE1) == (MODE2)                                          \
-   || (((MODE1) == HImode || (MODE1) == SImode                 \
-       || ((MODE1) == QImode                                   \
-           && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL))     \
-        || ((MODE1) == DImode && TARGET_64BIT))                        \
-       && ((MODE2) == HImode || (MODE2) == SImode              \
-          || ((MODE2) == QImode                                \
-              && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL))  \
-          || ((MODE2) == DImode && TARGET_64BIT))))
+#define MODES_TIEABLE_P(MODE1, MODE2)  ix86_modes_tieable_p (MODE1, MODE2)
 
 /* It is possible to write patterns to move flags; but until someone
    does it,  */