Eric, this is just something I noticed while trying to fix the
vec_init problems last week.

I'm confident that the issue is real, however I can't point to any
real bugs that are caused by this.

Therefore I'm reluctant to commit this change.

What do you think?

gcc/

        * config/sparc/sparc.c (sparc_regmode_natural_size): New function
        implementing REGMODE_NATURAL_SIZE taking into consideration vector
        modes.
        (sparc_modes_tieable_p): Similarly for MODES_TIEABLE_P.
        * config/sparc/sparc-protos.h (sparc_regmode_natural_size,
        sparc_modes_tieable_p): Declare.
        * gcc/config/sparc/sparc.h (REGMODE_NATURAL_SIZE,
        MODES_TIEABLE_P): Use new helper functions.
---
 gcc/ChangeLog                   |    9 +++++
 gcc/config/sparc/sparc-protos.h |    2 +
 gcc/config/sparc/sparc.c        |   65 +++++++++++++++++++++++++++++++++++++++
 gcc/config/sparc/sparc.h        |   18 +---------
 4 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cf4e66b..3544d38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
 2011-11-11  David S. Miller  <da...@davemloft.net>
 
+       * config/sparc/sparc.c (sparc_regmode_natural_size): New function
+       implementing REGMODE_NATURAL_SIZE taking into consideration vector
+       modes.
+       (sparc_modes_tieable_p): Similarly for MODES_TIEABLE_P.
+       * config/sparc/sparc-protos.h (sparc_regmode_natural_size,
+       sparc_modes_tieable_p): Declare.
+       * gcc/config/sparc/sparc.h (REGMODE_NATURAL_SIZE,
+       MODES_TIEABLE_P): Use new helper functions.
+
        Revert
        2011-11-05  David S. Miller  <da...@davemloft.net>
 
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index ccf20b1..10fa5ed 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -109,6 +109,8 @@ extern void sparc_expand_vector_init (rtx, rtx);
 extern void sparc_expand_vec_perm_bmask(enum machine_mode, rtx);
 extern bool sparc_expand_conditional_move (enum machine_mode, rtx *);
 extern void sparc_expand_vcond (enum machine_mode, rtx *, int, int);
+unsigned int sparc_regmode_natural_size (enum machine_mode);
+bool sparc_modes_tieable_p (enum machine_mode, enum machine_mode);
 #endif /* RTX_CODE */
 
 #endif /* __SPARC_PROTOS_H__ */
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 55759a0..b315698 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -11616,4 +11616,69 @@ sparc_expand_vcond (enum machine_mode mode, rtx 
*operands, int ccode, int fcode)
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], bshuf));
 }
 
+/* On sparc, any mode which naturally allocates into the float
+   registers should return 4 here.  */
+
+unsigned int
+sparc_regmode_natural_size (enum machine_mode mode)
+{
+  int size = UNITS_PER_WORD;
+
+  if (TARGET_ARCH64)
+    {
+      enum mode_class mclass = GET_MODE_CLASS (mode);
+
+      if (mclass == MODE_FLOAT || mclass == MODE_VECTOR_INT)
+       size = 4;
+    }
+
+  return size;
+}
+
+/* Return TRUE if it is a good idea to tie two pseudo registers
+   when one has mode MODE1 and one has mode MODE2.
+   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+   for any hard reg, then this must be FALSE for correct output.
+
+   For V9 we have to deal with the fact that only the lower 32 floating
+   point registers are 32-bit addressable.  */
+
+bool
+sparc_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+  enum mode_class mclass1, mclass2;
+  unsigned short size1, size2;
+
+  if (mode1 == mode2)
+    return true;
+
+  mclass1 = GET_MODE_CLASS (mode1);
+  mclass2 = GET_MODE_CLASS (mode2);
+  if (mclass1 != mclass2)
+    return false;
+
+  if (! TARGET_V9)
+    return true;
+
+  /* Classes are the same and we are V9 so we have to deal with upper
+     vs. lower floating point registers.  If one of the modes is a
+     4-byte mode, and the other is not, we have to mark them as not
+     tieable because only the lower 32 floating point register are
+     addressable 32-bits at a time.
+
+     We can't just test explicitly for SFmode, otherwise we won't
+     cover the vector mode cases properly.  */
+
+  if (mclass1 != MODE_FLOAT && mclass1 != MODE_VECTOR_INT)
+    return true;
+
+  size1 = GET_MODE_SIZE (mode1);
+  size2 = GET_MODE_SIZE (mode2);
+  if ((size1 > 4 && size2 == 4)
+      || (size2 > 4 && size1 == 4))
+    return false;
+
+  return true;
+}
+
 #include "gt-sparc.h"
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index e8707f5..32f8c10 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -716,8 +716,7 @@ extern enum cmodel sparc_cmodel;
 
 /* Due to the ARCH64 discrepancy above we must override this next
    macro too.  */
-#define REGMODE_NATURAL_SIZE(MODE) \
-  ((TARGET_ARCH64 && FLOAT_MODE_P (MODE)) ? 4 : UNITS_PER_WORD)
+#define REGMODE_NATURAL_SIZE(MODE) sparc_regmode_natural_size (MODE)
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
    See sparc.c for how we initialize this.  */
@@ -735,20 +734,7 @@ extern int sparc_mode_class[];
    register window instruction in the prologue.  */
 #define HARD_REGNO_RENAME_OK(FROM, TO) ((FROM) != 1)
 
-/* Value is 1 if it is a good idea to tie two pseudo registers
-   when one has mode MODE1 and one has mode MODE2.
-   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.
-
-   For V9: SFmode can't be combined with other float modes, because they can't
-   be allocated to the %d registers.  Also, DFmode won't fit in odd %f
-   registers, but SFmode will.  */
-#define MODES_TIEABLE_P(MODE1, MODE2) \
-  ((MODE1) == (MODE2)                                          \
-   || (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)                \
-       && (! TARGET_V9                                         \
-          || (GET_MODE_CLASS (MODE1) != MODE_FLOAT             \
-              || (MODE1 != SFmode && MODE2 != SFmode)))))
+#define MODES_TIEABLE_P(MODE1, MODE2) sparc_modes_tieable_p (MODE1, MODE2)
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
-- 
1.7.6.401.g6a319

Reply via email to