diff mbox

Only allow e500 double in SPE_SIMD_REGNO_P registers

Message ID Pine.LNX.4.64.1410242307360.9806@digraph.polyomino.org.uk
State New
Headers show

Commit Message

Joseph Myers Oct. 24, 2014, 11:09 p.m. UTC
rs6000_hard_regno_nregs_internal allows SPE vectors in single
registers satisfying SPE_SIMD_REGNO_P (i.e. register numbers 0 to
31).  However, the corresponding test for e500 double treats all
registers as being able to store a 64-bit value, rather than just
those GPRs.

Logically this inconsistency is wrong; in addition, it causes problems
unwinding from signal handlers.  linux-unwind.h uses
ARG_POINTER_REGNUM as a place to store the return address from a
signal handler, but this logic in rs6000_hard_regno_nregs_internal
results in that being considered an 8-byte register, resulting in
assertion failures.
(<https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02625.html> first
needs to be applied for unwinding to work in general on e500.)  This
patch makes rs6000_hard_regno_nregs_internal handle the e500 double
case consistently with SPE vectors.

Tested with no regressions with cross to powerpc-linux-gnuspe (given
the aforementioned patch applied).  Failures of signal handling
unwinding tests such as gcc.dg/cleanup-{8,9,10,11}.c are fixed by this
patch.  OK to commit?

2014-10-24  Joseph Myers  <joseph@codesourcery.com>

	* config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Do
	not allow e500 double in registers not satisyfing
	SPE_SIMD_REGNO_P.

Comments

David Edelsohn Oct. 24, 2014, 11:38 p.m. UTC | #1
On Fri, Oct 24, 2014 at 7:09 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> rs6000_hard_regno_nregs_internal allows SPE vectors in single
> registers satisfying SPE_SIMD_REGNO_P (i.e. register numbers 0 to
> 31).  However, the corresponding test for e500 double treats all
> registers as being able to store a 64-bit value, rather than just
> those GPRs.
>
> Logically this inconsistency is wrong; in addition, it causes problems
> unwinding from signal handlers.  linux-unwind.h uses
> ARG_POINTER_REGNUM as a place to store the return address from a
> signal handler, but this logic in rs6000_hard_regno_nregs_internal
> results in that being considered an 8-byte register, resulting in
> assertion failures.
> (<https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02625.html> first
> needs to be applied for unwinding to work in general on e500.)  This
> patch makes rs6000_hard_regno_nregs_internal handle the e500 double
> case consistently with SPE vectors.
>
> Tested with no regressions with cross to powerpc-linux-gnuspe (given
> the aforementioned patch applied).  Failures of signal handling
> unwinding tests such as gcc.dg/cleanup-{8,9,10,11}.c are fixed by this
> patch.  OK to commit?
>
> 2014-10-24  Joseph Myers  <joseph@codesourcery.com>
>
>         * config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Do
>         not allow e500 double in registers not satisyfing
>         SPE_SIMD_REGNO_P.

Okay.

Thanks, David
diff mbox

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 216673)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -1721,7 +1721,7 @@  rs6000_hard_regno_nregs_internal (int regno, enum
      SCmode so as to pass the value correctly in a pair of
      registers.  */
   else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
-	   && !DECIMAL_FLOAT_MODE_P (mode))
+	   && !DECIMAL_FLOAT_MODE_P (mode) && SPE_SIMD_REGNO_P (regno))
     reg_size = UNITS_PER_FP_WORD;
 
   else