blob: 75a9fdd441c712b76cc1ea1fa609ef8cc4aacdee [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001From 5c0092070253113cf0d9c45eacc884b3ecc34d81 Mon Sep 17 00:00:00 2001
2From: jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
3Date: Sat, 25 Oct 2014 00:23:17 +0000
4Subject: [PATCH] Only allow e500 double in SPE_SIMD_REGNO_P registers.
5
6rs6000_hard_regno_nregs_internal allows SPE vectors in single
7registers satisfying SPE_SIMD_REGNO_P (i.e. register numbers 0 to
831). However, the corresponding test for e500 double treats all
9registers as being able to store a 64-bit value, rather than just
10those GPRs.
11
12Logically this inconsistency is wrong; in addition, it causes problems
13unwinding from signal handlers. linux-unwind.h uses
14ARG_POINTER_REGNUM as a place to store the return address from a
15signal handler, but this logic in rs6000_hard_regno_nregs_internal
16results in that being considered an 8-byte register, resulting in
17assertion failures.
18(<https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02625.html> first
19needs to be applied for unwinding to work in general on e500.) This
20patch makes rs6000_hard_regno_nregs_internal handle the e500 double
21case consistently with SPE vectors.
22
23Tested with no regressions with cross to powerpc-linux-gnuspe (given
24the aforementioned patch applied). Failures of signal handling
25unwinding tests such as gcc.dg/cleanup-{8,9,10,11}.c are fixed by this
26patch.
27
28 * config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Do
29 not allow e500 double in registers not satisyfing
30 SPE_SIMD_REGNO_P.
31
32
33git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216688 138bc75d-0d04-0410-961f-82ee72b054a4
34
35Signed-off-by: Khem Raj <raj.khem@gmail.com>
36Upstream-Status: Backport [gcc 5.0]
37
38---
39 gcc/ChangeLog | 6 ++++++
40 gcc/config/rs6000/rs6000.c | 2 +-
41 2 files changed, 7 insertions(+), 1 deletion(-)
42
43Index: gcc-4.9.2/gcc/config/rs6000/rs6000.c
44===================================================================
45--- gcc-4.9.2.orig/gcc/config/rs6000/rs6000.c
46+++ gcc-4.9.2/gcc/config/rs6000/rs6000.c
47@@ -1703,7 +1703,7 @@ rs6000_hard_regno_nregs_internal (int re
48 SCmode so as to pass the value correctly in a pair of
49 registers. */
50 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
51- && !DECIMAL_FLOAT_MODE_P (mode))
52+ && !DECIMAL_FLOAT_MODE_P (mode) && SPE_SIMD_REGNO_P (regno))
53 reg_size = UNITS_PER_FP_WORD;
54
55 else