Word-mode paradoxical subregs have been problematic on big-endian architectures 
for ages, and the PA and SPARC ports have a workaround for this in the form of 
the CANNOT_CHANGE_MODE_CLASS macro.  The SPARC one was more limited in scope, 
but 10 ACATS tests fail at -O2 on the mainline because of this, so this patch 
extends it to fix them.

Tested on SPARC64/Solaris, applied on the mainline.


2012-02-12  Eric Botcazou  <ebotca...@adacore.com>

        * config/sparc/sparc.h (CANNOT_CHANGE_MODE_CLASS): In 64-bit mode,
        disallow changes from SFmode to mode with different size in FP regs.


-- 
Eric Botcazou
Index: config/sparc/sparc.h
===================================================================
--- config/sparc/sparc.h	(revision 183864)
+++ config/sparc/sparc.h	(working copy)
@@ -894,18 +894,21 @@ extern enum reg_class sparc_regno_reg_cl
 
 #define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
 
-/* Defines invalid mode changes.  Borrowed from pa64-regs.h.
+/* Defines invalid mode changes.  Borrowed from the PA port.
 
    SImode loads to floating-point registers are not zero-extended.
    The definition for LOAD_EXTEND_OP specifies that integer loads
    narrower than BITS_PER_WORD will be zero-extended.  As a result,
    we inhibit changes from SImode unless they are to a mode that is
-   identical in size.  */
+   identical in size.
+
+   Likewise for SFmode, since word-mode paradoxical subregs are
+   problematic on big-endian architectures.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)		\
   (TARGET_ARCH64						\
-   && (FROM) == SImode						\
-   && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)		\
+   && GET_MODE_SIZE (FROM) == 4					\
+   && GET_MODE_SIZE (TO) != 4					\
    ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
 
 /* This is the order in which to allocate registers normally.

Reply via email to