aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gcc.gnu.org>2011-12-06 14:11:44 +1030
committerAlan Modra <amodra@gcc.gnu.org>2011-12-06 14:11:44 +1030
commit59b719ec82d2d84286d8fdf86153a3261de0139e (patch)
treea7fdcab07896057cfb60354593240f5f906e4086
parent6184a33dce6c113cc602dbfbd48e0a1605836168 (diff)
downloadgcc-59b719ec82d2d84286d8fdf86153a3261de0139e.zip
gcc-59b719ec82d2d84286d8fdf86153a3261de0139e.tar.gz
gcc-59b719ec82d2d84286d8fdf86153a3261de0139e.tar.bz2
re PR target/50906 (e500 exception unwinding under "-Os" causes SIGSEGV)
PR target/50906 * config/rs6000/rs6000.c (rs6000_emit_prologue <TARGET_SPE_ABI>): Do not mark r11 setup as frame-related. Pass correct offset to rs6000_emit_savres_rtx. Correct out-of-line rs6000_frame_related arguments. Correct sp_offset. Remove "offset" fudge from in-line rs6000_frame_related call. Rename misleading variable. Fix comments and whitespace. Tidy some expressions. (rs6000_emit_epilogue <TARGET_SPE_ABI>): Always set frame_reg_rtx to r11 in out-of-line case. Correct sp_offset. Pass correct offset to rs6000_emit_savres_rtx. Rename misleading variable. Fix comments and whitespace. Tidy some expressions. (rs6000_emit_epilogue <non-TARGET_SPE_ABI>): Add sp_offset adjustment when !saving_GPRs_inline. Correct register mode used in address calcs. (rs6000_emit_epilogue <non-TARGET_SPE_ABI>): Similarly when !restoring_GPRs_inline. From-SVN: r182039
-rw-r--r--gcc/ChangeLog39
-rw-r--r--gcc/config/rs6000/rs6000.c176
2 files changed, 118 insertions, 97 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5939b74..18ad86a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,25 @@
+2011-12-06 Alan Modra <amodra@gmail.com>
+
+ PR target/50906
+ * config/rs6000/rs6000.c (rs6000_emit_prologue <TARGET_SPE_ABI>):
+ Do not mark r11 setup as frame-related. Pass correct offset to
+ rs6000_emit_savres_rtx. Correct out-of-line rs6000_frame_related
+ arguments. Correct sp_offset. Remove "offset" fudge from
+ in-line rs6000_frame_related call. Rename misleading variable.
+ Fix comments and whitespace. Tidy some expressions.
+ (rs6000_emit_epilogue <TARGET_SPE_ABI>): Always set frame_reg_rtx
+ to r11 in out-of-line case. Correct sp_offset. Pass correct
+ offset to rs6000_emit_savres_rtx. Rename misleading variable.
+ Fix comments and whitespace. Tidy some expressions.
+ (rs6000_emit_epilogue <non-TARGET_SPE_ABI>): Add sp_offset
+ adjustment when !saving_GPRs_inline. Correct register mode
+ used in address calcs.
+ (rs6000_emit_epilogue <non-TARGET_SPE_ABI>): Similarly when
+ !restoring_GPRs_inline.
+
2011-12-06 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
- * config/arm/vfp.md (*combine_vcvt_f64_<FCVTI32typename>): Fix
+ * config/arm/vfp.md (*combine_vcvt_f64_<FCVTI32typename>): Fix
formatting character for vmov.f64 case.
2011-12-05 Jakub Jelinek <jakub@redhat.com>
@@ -149,15 +168,15 @@
2011-12-05 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
- * config/arm/arm.c (vfp3_const_double_for_fract_bits): Define.
- * config/arm/arm-protos.h (vfp3_const_double_for_fract_bits): Declare.
- * config/arm/constraints.md ("Dt"): New constraint.
- * config/arm/predicates.md
- (const_double_vcvt_power_of_two_reciprocal): New.
- * config/arm/vfp.md (FCVTI32typename): New.
- (FCVT): New iterator.
- (*combine_vcvt_f32_<FCVTI32typename>): New.
- (*combine_vcvt_f64_<FCVTI32typename>): New.
+ * config/arm/arm.c (vfp3_const_double_for_fract_bits): Define.
+ * config/arm/arm-protos.h (vfp3_const_double_for_fract_bits): Declare.
+ * config/arm/constraints.md ("Dt"): New constraint.
+ * config/arm/predicates.md
+ (const_double_vcvt_power_of_two_reciprocal): New.
+ * config/arm/vfp.md (FCVTI32typename): New.
+ (FCVT): New iterator.
+ (*combine_vcvt_f32_<FCVTI32typename>): New.
+ (*combine_vcvt_f64_<FCVTI32typename>): New.
2011-12-05 Richard Guenther <rguenther@suse.de>
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 4c6d642..c8eacaf 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -19551,56 +19551,52 @@ rs6000_emit_prologue (void)
{
int i;
rtx spe_save_area_ptr;
-
+ int save_ptr_to_sp;
+ int ool_adjust = 0;
+
/* Determine whether we can address all of the registers that need
- to be saved with an offset from the stack pointer that fits in
+ to be saved with an offset from frame_reg_rtx that fits in
the small const field for SPE memory instructions. */
- int spe_regs_addressable_via_sp
- = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
- + (32 - info->first_gp_reg_save - 1) * reg_size)
+ int spe_regs_addressable
+ = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset
+ + reg_size * (32 - info->first_gp_reg_save - 1))
&& saving_GPRs_inline);
int spe_offset;
-
- if (spe_regs_addressable_via_sp)
+
+ if (spe_regs_addressable)
{
spe_save_area_ptr = frame_reg_rtx;
+ save_ptr_to_sp = info->total_size - sp_offset;
spe_offset = info->spe_gp_save_offset + sp_offset;
}
else
{
/* Make r11 point to the start of the SPE save area. We need
to be careful here if r11 is holding the static chain. If
- it is, then temporarily save it in r0. We would use r0 as
- our base register here, but using r0 as a base register in
- loads and stores means something different from what we
- would like. */
- int ool_adjust = (saving_GPRs_inline
- ? 0
- : (info->first_gp_reg_save
- - (FIRST_SAVRES_REGISTER+1))*8);
- HOST_WIDE_INT offset = (info->spe_gp_save_offset
- + sp_offset - ool_adjust);
+ it is, then temporarily save it in r0. */
+ int offset;
+
+ if (!saving_GPRs_inline)
+ ool_adjust = 8 * (info->first_gp_reg_save
+ - (FIRST_SAVRES_REGISTER + 1));
+ offset = info->spe_gp_save_offset + sp_offset - ool_adjust;
+ spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
+ save_ptr_to_sp = info->total_size - sp_offset + offset;
+ spe_offset = 0;
if (using_static_chain_p)
{
rtx r0 = gen_rtx_REG (Pmode, 0);
gcc_assert (info->first_gp_reg_save > 11);
-
- emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
+
+ emit_move_insn (r0, spe_save_area_ptr);
}
-
- spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
- insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
- frame_reg_rtx,
- GEN_INT (offset)));
- /* We need to make sure the move to r11 gets noted for
- properly outputting unwind information. */
- if (!saving_GPRs_inline)
- rs6000_frame_related (insn, frame_reg_rtx, offset,
- NULL_RTX, NULL_RTX);
- spe_offset = 0;
+ emit_insn (gen_addsi3 (spe_save_area_ptr,
+ frame_reg_rtx, GEN_INT (offset)));
+ if (REGNO (frame_reg_rtx) == 11)
+ sp_offset = -info->spe_gp_save_offset + ool_adjust;
}
-
+
if (saving_GPRs_inline)
{
for (i = 0; i < 32 - info->first_gp_reg_save; i++)
@@ -19612,58 +19608,65 @@ rs6000_emit_prologue (void)
/* We're doing all this to ensure that the offset fits into
the immediate offset of 'evstdd'. */
gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
-
+
offset = GEN_INT (reg_size * i + spe_offset);
addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
mem = gen_rtx_MEM (V2SImode, addr);
-
+
insn = emit_move_insn (mem, reg);
-
- rs6000_frame_related (insn, spe_save_area_ptr,
- info->spe_gp_save_offset
- + sp_offset + reg_size * i,
- offset, const0_rtx);
+
+ rs6000_frame_related (insn,
+ spe_save_area_ptr, save_ptr_to_sp,
+ NULL_RTX, NULL_RTX);
}
}
else
{
- insn = rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
- 0, reg_mode,
+ insn = rs6000_emit_savres_rtx (info, spe_save_area_ptr,
+ ool_adjust, reg_mode,
/*savep=*/true, /*gpr=*/true,
/*lr=*/false);
- rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+
+ rs6000_frame_related (insn, spe_save_area_ptr, save_ptr_to_sp,
NULL_RTX, NULL_RTX);
}
-
-
+
/* Move the static chain pointer back. */
- if (using_static_chain_p && !spe_regs_addressable_via_sp)
- emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
+ if (using_static_chain_p && !spe_regs_addressable)
+ emit_move_insn (spe_save_area_ptr, gen_rtx_REG (Pmode, 0));
}
else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
{
if (DEFAULT_ABI == ABI_DARWIN)
{
- rtx dest_reg = gen_rtx_REG (reg_mode, 11);
+ rtx dest_reg = gen_rtx_REG (Pmode, 11);
if (info->first_fp_reg_save == 64)
- /* we only need a copy, no fprs were saved. */
- emit_move_insn (dest_reg, frame_reg_rtx);
+ {
+ /* we only need a copy, no fprs were saved. */
+ if (dest_reg != frame_reg_rtx)
+ emit_move_insn (dest_reg, frame_reg_rtx);
+ }
else
{
- rtx offset = GEN_INT (sp_offset
- + (-8 * (64-info->first_fp_reg_save)));
+ int save_off = 8 * (64 - info->first_fp_reg_save);
+ rtx offset = GEN_INT (sp_offset - save_off);
+
+ if (REGNO (dest_reg) == REGNO (frame_reg_rtx))
+ sp_offset = save_off;
emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
}
}
/* Need to adjust r11 (r12) if we saved any FPRs. */
else if (info->first_fp_reg_save != 64)
- {
- rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
- ? 12 : 11);
- rtx offset = GEN_INT (sp_offset
- + (-8 * (64-info->first_fp_reg_save)));
+ {
+ rtx dest_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11);
+ int save_off = 8 * (64 - info->first_fp_reg_save);
+ rtx offset = GEN_INT (sp_offset - save_off);
+
+ if (REGNO (dest_reg) == REGNO (frame_reg_rtx))
+ sp_offset = save_off;
emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
- }
+ }
insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
info->gp_save_offset + sp_offset,
@@ -20577,40 +20580,39 @@ rs6000_emit_epilogue (int sibcall)
&& info->first_gp_reg_save != 32)
{
/* Determine whether we can address all of the registers that need
- to be saved with an offset from the stack pointer that fits in
- the small const field for SPE memory instructions. */
- int spe_regs_addressable_via_sp
- = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
- + (32 - info->first_gp_reg_save - 1) * reg_size)
+ to be saved with an offset from frame_reg_rtx that fits in
+ the small const field for SPE memory instructions. */
+ int spe_regs_addressable
+ = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + sp_offset
+ + reg_size * (32 - info->first_gp_reg_save - 1))
&& restoring_GPRs_inline);
int spe_offset;
+ int ool_adjust = 0;
- if (spe_regs_addressable_via_sp)
+ if (spe_regs_addressable)
spe_offset = info->spe_gp_save_offset + sp_offset;
else
- {
+ {
rtx old_frame_reg_rtx = frame_reg_rtx;
- /* Make r11 point to the start of the SPE save area. We worried about
- not clobbering it when we were saving registers in the prologue.
- There's no need to worry here because the static chain is passed
- anew to every function. */
- int ool_adjust = (restoring_GPRs_inline
- ? 0
- : (info->first_gp_reg_save
- - (FIRST_SAVRES_REGISTER + 1)) * 8);
-
- if (frame_reg_rtx == sp_reg_rtx)
- frame_reg_rtx = gen_rtx_REG (Pmode, 11);
- emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
+ /* Make r11 point to the start of the SPE save area. We worried about
+ not clobbering it when we were saving registers in the prologue.
+ There's no need to worry here because the static chain is passed
+ anew to every function. */
+
+ if (!restoring_GPRs_inline)
+ ool_adjust = 8 * (info->first_gp_reg_save
+ - (FIRST_SAVRES_REGISTER + 1));
+ frame_reg_rtx = gen_rtx_REG (Pmode, 11);
+ emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
GEN_INT (info->spe_gp_save_offset
+ sp_offset
- ool_adjust)));
/* Keep the invariant that frame_reg_rtx + sp_offset points
at the top of the stack frame. */
- sp_offset = -info->spe_gp_save_offset;
+ sp_offset = -info->spe_gp_save_offset + ool_adjust;
- spe_offset = 0;
- }
+ spe_offset = 0;
+ }
if (restoring_GPRs_inline)
{
@@ -20632,8 +20634,8 @@ rs6000_emit_epilogue (int sibcall)
}
}
else
- rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
- 0, reg_mode,
+ rs6000_emit_savres_rtx (info, frame_reg_rtx,
+ ool_adjust, reg_mode,
/*savep=*/false, /*gpr=*/true,
/*lr=*/true);
}
@@ -20646,22 +20648,22 @@ rs6000_emit_epilogue (int sibcall)
if (can_use_exit)
{
rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
- sp_offset, can_use_exit);
+ sp_offset, can_use_exit);
if (DEFAULT_ABI == ABI_DARWIN)
/* we only need a copy, no fprs were saved. */
- emit_move_insn (gen_rtx_REG (reg_mode, 11), frame_reg_rtx);
+ emit_move_insn (gen_rtx_REG (Pmode, 11), frame_reg_rtx);
if (info->cr_save_p)
rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
}
else
{
- emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
- ? 12 : 11),
- frame_reg_rtx,
+ rtx src_reg = gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX ? 12 : 11);
+
+ emit_insn (gen_add3_insn (src_reg, frame_reg_rtx,
GEN_INT (sp_offset - info->fp_size)));
- if (REGNO (frame_reg_rtx) == 11)
- sp_offset += info->fp_size;
+ if (REGNO (frame_reg_rtx) == REGNO (src_reg))
+ sp_offset = info->fp_size;
}
rs6000_emit_savres_rtx (info, frame_reg_rtx,