diff options
author | Joseph Myers <joseph@codesourcery.com> | 2014-10-25 01:23:17 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2014-10-25 01:23:17 +0100 |
commit | 4aa19422932112527ceb8cd3dd290bd9ff2b990c (patch) | |
tree | bacbecc9cfbc5d3479e0391be8141bb23aa5588e | |
parent | d80c2beaf7d6f117fa52486f1006faec559fe1d2 (diff) | |
download | gcc-4aa19422932112527ceb8cd3dd290bd9ff2b990c.zip gcc-4aa19422932112527ceb8cd3dd290bd9ff2b990c.tar.gz gcc-4aa19422932112527ceb8cd3dd290bd9ff2b990c.tar.bz2 |
Only allow e500 double in SPE_SIMD_REGNO_P registers.
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.
* config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Do
not allow e500 double in registers not satisyfing
SPE_SIMD_REGNO_P.
From-SVN: r216688
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 2 |
2 files changed, 7 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bc6908d..2b94c2b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-10-25 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. + 2014-10-24 Aldy Hernandez <aldyh@redhat.com> * dwarf2out.c (declare_in_namespace): Only emit external diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 2f14c2b..a5e5bcf 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1721,7 +1721,7 @@ rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode) 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 |