diff options
author | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-28 19:49:18 +0000 |
---|---|---|
committer | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-28 19:49:18 +0000 |
commit | 7dce9bb8623c6dd047497b8c8974c96683d723de (patch) | |
tree | 651ad4f0809a5d3f077e4144b065108d3a4a9533 | |
parent | 7638d82cc5841b8a5a91d9ed133ec344877c2a75 (diff) |
Make tonto, gamess, and calculix work again.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ibm/gcc-4_3-branch@153684 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.ibm | 14 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 32 |
3 files changed, 35 insertions, 16 deletions
diff --git a/gcc/ChangeLog.ibm b/gcc/ChangeLog.ibm index 850762c0331..54dbbb00f61 100644 --- a/gcc/ChangeLog.ibm +++ b/gcc/ChangeLog.ibm @@ -1,3 +1,17 @@ +2009-10-28 Michael Meissner <meissner@linux.vnet.ibm.com> + + * config/rs6000/predicates.md (vrsave_operation): Allow for there + to be no CLOBBERs on a vrsave instruction. + + * config/rs6000/rs6000.c (direct_return): Functions that use VSX + vectors in registers that overlap with fprs but no registers that + overlap with the Altivec registers sets VRSAVE to non-zero even + though the vrsave mask is 0. + (rs6000_stack_info): Ditto. + (rs6000_emit_prologue): Ditto. + (rs6000_emit_epilogue): Ditto. + (compute_vrsave_mask): Undo 2009-10-22 change here. + 2009-10-23 Michael Meissner <meissner@linux.vnet.ibm.com> * config/rs6000/rs6000-c.c (altivec_categorize_keyword): Undo diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 2cabf0943b5..5476312e4f4 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1131,7 +1131,7 @@ unsigned int dest_regno, src_regno; int i; - if (count <= 1 + if (count == 0 || GET_CODE (XVECEXP (op, 0, 0)) != SET || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE @@ -1144,6 +1144,9 @@ if (dest_regno != VRSAVE_REGNO || src_regno != VRSAVE_REGNO) return 0; + /* Under VSX it is possible for there to be no clobbers if the function uses + vector registers that overlap with the floating point registers, but no + registers that overlap the altivec registers. */ for (i = 1; i < count; i++) { rtx elt = XVECEXP (op, 0, i); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 1064f5fecd3..be0fab7b8ad 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3631,6 +3631,7 @@ direct_return (void) && ! info->lr_save_p && ! info->cr_save_p && info->vrsave_mask == 0 + && ! cfun->machine->vsx_or_altivec_used_p && ! info->push_p) return 1; } @@ -16724,15 +16725,6 @@ compute_vrsave_mask (void) if (df_regs_ever_live_p (i)) mask |= ALTIVEC_REG_BIT (i); - /* If VSX is used, we might have used a traditional floating point register - in a vector mode without using any altivec registers. However the VRSAVE - register does not have room to indicate the floating point registers. - Modern kernels only look to see if the value is non-zero to determine if - they need to save the vector registers, so we just set an arbitrary - value if any vector type was used. */ - if (mask == 0 && TARGET_VSX && cfun->machine->vsx_or_altivec_used_p) - mask = 0xFFF; - if (mask == 0) return mask; @@ -17054,7 +17046,8 @@ rs6000_stack_info (void) else info_ptr->vrsave_mask = 0; - if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask) + if (TARGET_ALTIVEC_VRSAVE && + (info_ptr->vrsave_mask || cfun->machine->vsx_or_altivec_used_p)) info_ptr->vrsave_size = 4; else info_ptr->vrsave_size = 0; @@ -17208,7 +17201,8 @@ rs6000_stack_info (void) if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0) info_ptr->altivec_save_offset = 0; - if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0) + if (! TARGET_ALTIVEC_ABI + || (info_ptr->vrsave_mask == 0 && !cfun->machine->vsx_or_altivec_used_p)) info_ptr->vrsave_save_offset = 0; if (! TARGET_SPE_ABI @@ -18860,6 +18854,7 @@ rs6000_emit_prologue (void) (frame_reg_rtx != sp_reg_rtx && ((info->altivec_size != 0) || (info->vrsave_mask != 0) + || cfun->machine->vsx_or_altivec_used_p )), FALSE); if (frame_reg_rtx != sp_reg_rtx) @@ -18915,10 +18910,17 @@ rs6000_emit_prologue (void) epilogue. */ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE - && info->vrsave_mask != 0) + && (info->vrsave_mask != 0 || cfun->machine->vsx_or_altivec_used_p)) { rtx reg, mem, vrsave; int offset; + unsigned int mask = info->vrsave_mask; + + /* If we only used VSX vector registers that overlap with floating point + registers, just set VRSAVE to non-zero to tell the kernel that we need + to save the vector registers. */ + if (!mask && cfun->machine->vsx_or_altivec_used_p) + mask = 0x1; /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12 as frame_reg_rtx and r11 as the static chain pointer for @@ -18941,7 +18943,7 @@ rs6000_emit_prologue (void) } /* Include the registers in the mask. */ - emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask))); + emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) mask))); insn = emit_insn (generate_set_vrsave (reg, info, 0)); } @@ -19316,7 +19318,7 @@ rs6000_emit_epilogue (int sibcall) /* Restore VRSAVE if we must do so before adjusting the stack. */ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE - && info->vrsave_mask != 0 + && (info->vrsave_mask != 0 || cfun->machine->vsx_or_altivec_used_p) && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP || (DEFAULT_ABI != ABI_V4 && info->vrsave_save_offset < (TARGET_32BIT ? -220 : -288)))) @@ -19429,7 +19431,7 @@ rs6000_emit_epilogue (int sibcall) if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP && TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE - && info->vrsave_mask != 0 + && (info->vrsave_mask != 0 || cfun->machine->vsx_or_altivec_used_p) && (DEFAULT_ABI == ABI_V4 || info->vrsave_save_offset >= (TARGET_32BIT ? -220 : -288))) { |