i386.h (SSE_CLASS_P, [...]): New macros.
authorJan Hubicka <jh@suse.cz>
Tue, 13 Feb 2001 10:40:40 +0000 (11:40 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 13 Feb 2001 10:40:40 +0000 (10:40 +0000)
* i386.h (SSE_CLASS_P, MMX_CLASS_P, MAYBE_FLOAT_CLASS_P,
MAYBE_SSE_CLASS_P, MAYBE_MMX_CLASS_P): New macros.
(PREFERRED_RELOAD_CLASS, SECONDARY_MEMORY_NEEDED): Move offline.
(REGISTER_MOVE_COST): Likewise.
* i386-protos.h (ix86_secondary_memory_needed,
ix86_preferred_reload_class, ix86_register_move_cost): Declare.
* i386.c (ix86_secondary_memory_needed,
ix86_preferred_reload_class, ix86_register_move_cost): New function.

From-SVN: r39622

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

index aac7623..df04b03 100644 (file)
@@ -1,3 +1,14 @@
+Tue Feb 13 11:37:06 CET 2001  Jan Hubicka  <jh@suse.cz>
+
+       * i386.h (SSE_CLASS_P, MMX_CLASS_P, MAYBE_FLOAT_CLASS_P,
+       MAYBE_SSE_CLASS_P, MAYBE_MMX_CLASS_P): New macros.
+       (PREFERRED_RELOAD_CLASS, SECONDARY_MEMORY_NEEDED): Move offline.
+       (REGISTER_MOVE_COST): Likewise.
+       * i386-protos.h (ix86_secondary_memory_needed,
+       ix86_preferred_reload_class, ix86_register_move_cost): Declare.
+       * i386.c (ix86_secondary_memory_needed,
+       ix86_preferred_reload_class, ix86_register_move_cost): New function.
+
 Die Feb 13 11:04:25 CET 2001  Jan Hubicka  <jh@suse.cz>
 
        * i386.h (VALID_FP_MODE_P, VALID_INT_MODE_P): New.
index 683c881..4e5dffd 100644 (file)
@@ -8725,6 +8725,108 @@ ix86_free_from_memory (mode)
                                                 : 4))));
 }
 
+/* Put float CONST_DOUBLE in the constant pool instead of fp regs.
+   QImode must go into class Q_REGS.
+   Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
+   movdf to do mem-to-mem moves through integer regs. */
+enum reg_class
+ix86_preferred_reload_class (x, class)
+     rtx x;
+     enum reg_class class;
+{
+  if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
+    {
+      /* SSE can't load any constant directly yet.  */
+      if (SSE_CLASS_P (class))
+       return NO_REGS;
+      /* Floats can load 0 and 1.  */
+      if (MAYBE_FLOAT_CLASS_P (class) && standard_80387_constant_p (x))
+       {
+         /* Limit class to non-SSE.  Use GENERAL_REGS if possible.  */
+         if (MAYBE_SSE_CLASS_P (class))
+           return (reg_class_subset_p (class, GENERAL_REGS)
+                   ? GENERAL_REGS : FLOAT_REGS);
+         else
+           return class;
+       }
+      /* General regs can load everything.  */
+      if (reg_class_subset_p (class, GENERAL_REGS))
+       return GENERAL_REGS;
+      /* In case we haven't resolved FLOAT or SSE yet, give up.  */
+      if (MAYBE_FLOAT_CLASS_P (class) || MAYBE_SSE_CLASS_P (class))
+       return NO_REGS;
+    }
+  if (MAYBE_MMX_CLASS_P (class) && CONSTANT_P (x))
+    return NO_REGS;
+  if (GET_MODE (x) == QImode && ! reg_class_subset_p (class, Q_REGS))
+    return Q_REGS;
+  return class;
+}
+
+/* If we are copying between general and FP registers, we need a memory
+   location. The same is true for SSE and MMX registers.
+
+   The macro can't work reliably when one of the CLASSES is class containing
+   registers from multiple units (SSE, MMX, integer).  We avoid this by never
+   combining those units in single alternative in the machine description.
+   Ensure that this constraint holds to avoid unexpected surprises.
+
+   When STRICT is false, we are being called from REGISTER_MOVE_COST, so do not
+   enforce these sanity checks.  */
+int
+ix86_secondary_memory_needed (class1, class2, mode, strict)
+     enum reg_class class1, class2;
+     enum machine_mode mode;
+     int strict;
+{
+  if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
+      || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
+      || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
+      || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
+      || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
+      || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2))
+    {
+      if (strict)
+       abort ();
+      else
+       return 1;
+    }
+  return (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)
+         || (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
+             && (mode) != SImode)
+         || (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
+             && (mode) != SImode));
+}
+/* Return the cost of moving data from a register in class CLASS1 to
+   one in class CLASS2. 
+
+   It is not required that the cost always equal 2 when FROM is the same as TO;
+   on some machines it is expensive to move between registers if they are not
+   general registers.  */
+int
+ix86_register_move_cost (mode, class1, class2)
+     enum machine_mode mode;
+     enum reg_class class1, class2;
+{
+  /* In case we require secondary memory, compute cost of the store followed
+     by load.  In case of copying from general_purpose_register we may emit
+     multiple stores followed by single load causing memory size mismatch
+     stall.  Count this as arbitarily high cost of 20.  */
+  if (ix86_secondary_memory_needed (class1, class2, mode, 0))
+    {
+      if (CLASS_MAX_NREGS (CLASS1, MODE) > CLASS_MAX_NREGS (CLASS2, MODE))
+       return 10;
+      return (MEMORY_MOVE_COST (MODE, CLASS1, 0)
+             + MEMORY_MOVE_COST (MODE, CLASS2, 1));
+    }
+  /* Moves between SSE/MMX and integer unit are expensive.
+     ??? We should make this cost CPU specific.  */
+  if (MMX_CLASS_P (CLASS1) != MMX_CLASS_P (CLASS2)
+      || SSE_CLASS_P (CLASS1) != SSE_CLASS_P (CLASS2))
+    return 3;
+  return 2;
+}
+
 /* Return 1 if hard register REGNO can hold a value of machine-mode MODE.  */
 int
 ix86_hard_regno_mode_ok (regno, mode)
index 162da52..13ef600 100644 (file)
@@ -946,6 +946,11 @@ enum reg_class
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
 #define FLOAT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, FLOAT_REGS))
+#define SSE_CLASS_P(CLASS) (reg_class_subset_p (CLASS, SSE_REGS))
+#define MMX_CLASS_P(CLASS) (reg_class_subset_p (CLASS, MMX_REGS))
+#define MAYBE_FLOAT_CLASS_P(CLASS) (reg_classes_intersect_p (CLASS, FLOAT_REGS))
+#define MAYBE_SSE_CLASS_P(CLASS) (reg_classes_intersect_p (SSE_REGS, CLASS))
+#define MAYBE_MMX_CLASS_P(CLASS) (reg_classes_intersect_p (MMX_REGS, CLASS))
 
 #define Q_CLASS_P(CLASS) (reg_class_subset_p (CLASS, Q_REGS))
 
@@ -1112,22 +1117,12 @@ enum reg_class
    movdf to do mem-to-mem moves through integer regs. */
 
 #define PREFERRED_RELOAD_CLASS(X,CLASS)                                        \
-  (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode            \
-   ? (standard_80387_constant_p (X)                                    \
-      ? CLASS                                                          \
-      : (reg_class_subset_p (CLASS, FLOAT_REGS)                        \
-        ? NO_REGS                                                      \
-        : reg_class_subset_p (CLASS, GENERAL_REGS) ? CLASS : GENERAL_REGS)) \
-   : GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \
-   : (CLASS))
+   ix86_preferred_reload_class (X, CLASS)
 
 /* If we are copying between general and FP registers, we need a memory
-   location.  */
-/* The same is true for SSE and MMX registers.  */
+   location. The same is true for SSE and MMX registers.  */
 #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
-  (FLOAT_CLASS_P (CLASS1) != FLOAT_CLASS_P (CLASS2) \
-   || ((CLASS1 == SSE_REGS) != (CLASS2 == SSE_REGS)) \
-   || ((CLASS1 == MMX_REGS) != (CLASS2 == MMX_REGS) && (MODE) != SImode))
+  ix86_secondary_memory_needed (CLASS1, CLASS2, MODE, 1)
 
 /* QImode spills from non-QI registers need a scratch.  This does not
    happen often -- the only example so far requires an uninitialized 
@@ -1141,7 +1136,7 @@ enum reg_class
 /* On the 80386, this is the size of MODE in words,
    except in the FP regs, where a single reg is always enough.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)                                   \
- (FLOAT_CLASS_P (CLASS) || (CLASS) == SSE_REGS || (CLASS) == MMX_REGS  \
+ (FLOAT_CLASS_P (CLASS) || SSE_CLASS_P (CLASS) || MMX_CLASS_P (CLASS)  \
   ? 1                                                                  \
   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
@@ -2352,25 +2347,10 @@ while (0)
 
    It is not required that the cost always equal 2 when FROM is the same as TO;
    on some machines it is expensive to move between registers if they are not
-   general registers.
+   general registers.  */
 
-   On the i386, copying between floating-point and fixed-point
-   registers is done trough memory.  
-   Integer -> fp moves are noticeably slower than the opposite direction
-   because of the partial memory stall they cause.  Give it an
-   arbitary high cost.
- */
-
-#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)               \
-  ((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2))                \
-   ? (MEMORY_MOVE_COST (DFmode, CLASS1, 0)                     \
-     + MEMORY_MOVE_COST (DFmode, CLASS2, 1))                   \
-   : (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2)) ? 10 \
-   : ((CLASS1) == MMX_REGS && (CLASS2) == SSE_REGS) ? 10       \
-   : ((CLASS1) == SSE_REGS && (CLASS2) == MMX_REGS) ? 10       \
-   : ((CLASS1) == MMX_REGS) != ((CLASS2) == MMX_REGS) ? 3      \
-   : 2)
+#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
+   ix86_register_move_cost (mode, class1, class2);
 
 /* A C expression for the cost of moving data of mode M between a
    register and memory.  A value of 2 is the default; this cost is