This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Only allow e500 double in SPE_SIMD_REGNO_P registers
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Cc: Olivier Hainque <hainque at adacore dot com>, <dje dot gcc at gmail dot com>
- Date: Fri, 24 Oct 2014 23:09:14 +0000
- Subject: Only allow e500 double in SPE_SIMD_REGNO_P registers
- Authentication-results: sourceware.org; auth=none
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.
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
--
Joseph S. Myers
joseph@codesourcery.com