From patchwork Tue May 8 10:32:39 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 157665 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 617BCB6F62 for ; Tue, 8 May 2012 20:33:15 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1337077995; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID: Mail-Followup-To:References:MIME-Version:Content-Type: Content-Disposition:In-Reply-To:User-Agent:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=bEqmU9GiNsnXBPjZMHBbTm2tOno=; b=pZNikfYKnjGbSv2oK3qSF9Bzcx1umxm2DmTWvYWRkbMmrjv5Ydbt8sTenFbWy0 R64nPYgiYNrW+UhOGdwSeHVI2kZcIgs8xsoY1Ib7tk35/M9vee+dIulHK326lDsR pJ0FHUdrcc2WYGAv288zD/hl155P3Oz0wegrh/Z7QDplM= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:Mail-Followup-To:References:MIME-Version:Content-Type:Content-Disposition:In-Reply-To:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=OIjFMWZ/J9GPDikASr1/d+OR2/mCzQ9MH8vqkyaRdhsL9kkzF0iNtReUWhhT2X HDV2wueKT5cUBT3BjMGMSuIvN4B5lyzbx3PJdAmZFbdwILL75wQ7dp9xzX9ETuOX +b+GUI3AEqyXuuJPpIIJBDuQs577qaxIHb/haD7Ungoww=; Received: (qmail 25443 invoked by alias); 8 May 2012 10:33:07 -0000 Received: (qmail 25146 invoked by uid 22791); 8 May 2012 10:33:02 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-pz0-f48.google.com (HELO mail-pz0-f48.google.com) (209.85.210.48) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 08 May 2012 10:32:46 +0000 Received: by dadz8 with SMTP id z8so4483508dad.21 for ; Tue, 08 May 2012 03:32:46 -0700 (PDT) Received: by 10.68.226.99 with SMTP id rr3mr6565920pbc.48.1336473165800; Tue, 08 May 2012 03:32:45 -0700 (PDT) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id s7sm1963441pbl.31.2012.05.08.03.32.43 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 08 May 2012 03:32:45 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 5DFDFEA1D74; Tue, 8 May 2012 20:02:39 +0930 (CST) Date: Tue, 8 May 2012 20:02:39 +0930 From: Alan Modra To: Olivier Hainque , David Edelsohn Cc: GCC Patches Subject: [RS6000] Fix PR53271 powerpc ports Message-ID: <20120508103239.GO17181@bubble.grove.modra.org> Mail-Followup-To: Olivier Hainque , David Edelsohn , GCC Patches References: <37BF2514-EA22-4DE4-8B77-53A6B63DE48C@adacore.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On Mon, May 07, 2012 at 05:23:33PM +0200, Olivier Hainque wrote: > (emit_frame_save): Don't handle reg+reg addressing. > > introduces an assert on which we now trip compiling unwind-dw2.c for SPE > configurations. We now fall into the TARGET_SPE_ABI part of > > /* Some cases that need register indexed addressing. */ > gcc_checking_assert (!((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) > || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode)) > || (TARGET_E500_DOUBLE && mode == DFmode) > || (TARGET_SPE_ABI > && SPE_VECTOR_MODE (mode) > && !SPE_CONST_OFFSET_OK (offset)))); > > in emit_frame_save while compiling uw_install_context. > > The call comes from this part of rs6000_emit_prologue: > > /* ??? There's no need to emit actual instructions here, but it's the > easiest way to get the frame unwind information emitted. */ OK, the assert is doing its job. I wanted to minimize the number of places that need temporary hard regs, so that tracking of which hard reg is in use can all be done in rs6000_emit_prologue. The problem is that the insns here need reg+reg addressing on SPE, but as the ??? comment says we really don't need insns, just the eh unwind reg info. So that is what the following patch does, attaching the eh info to a blockage. I also make use of gen_frame_store and siblings that I invented for generating the eh info, elsewhere in rs6000.c where doing so is blindingly obvious. We could probably use them in other places too, but I'll leave that for later. Bootstrapped and regression tested powerpc-linux. OK to apply? PR target/53271 * config/rs6000/rs6000.c (gen_frame_set): New function. (gen_frame_load, gen_frame_store): New functions. (rs6000_savres_rtx): Use the above. (rs6000_emit_epilogue, rs6000_emit_prologue): Here too. Correct mode used for CR2 in save/restore_world patterns. Don't emit instructions for eh_return frame unwind reg info. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 187275) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -18961,6 +18961,28 @@ return insn; } +static rtx +gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store) +{ + rtx addr, mem; + + addr = gen_rtx_PLUS (Pmode, frame_reg, GEN_INT (offset)); + mem = gen_frame_mem (GET_MODE (reg), addr); + return gen_rtx_SET (VOIDmode, store ? mem : reg, store ? reg : mem); +} + +static rtx +gen_frame_load (rtx reg, rtx frame_reg, int offset) +{ + return gen_frame_set (reg, frame_reg, offset, false); +} + +static rtx +gen_frame_store (rtx reg, rtx frame_reg, int offset) +{ + return gen_frame_set (reg, frame_reg, offset, true); +} + /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes. Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */ @@ -19301,27 +19323,14 @@ = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, use_reg)); for (i = 0; i < end_reg - start_reg; i++) - { - rtx addr, reg, mem; - reg = gen_rtx_REG (reg_mode, start_reg + i); - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (save_area_offset + reg_size * i)); - mem = gen_frame_mem (reg_mode, addr); + RTVEC_ELT (p, i + offset) + = gen_frame_set (gen_rtx_REG (reg_mode, start_reg + i), + frame_reg_rtx, save_area_offset + reg_size * i, + (sel & SAVRES_SAVE) != 0); - RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, - (sel & SAVRES_SAVE) ? mem : reg, - (sel & SAVRES_SAVE) ? reg : mem); - } - if ((sel & SAVRES_SAVE) && (sel & SAVRES_LR)) - { - rtx addr, reg, mem; - reg = gen_rtx_REG (Pmode, 0); - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (lr_offset)); - mem = gen_frame_mem (Pmode, addr); - RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg); - } + RTVEC_ELT (p, i + offset) + = gen_frame_store (gen_rtx_REG (Pmode, 0), frame_reg_rtx, lr_offset); par = gen_rtx_PARALLEL (VOIDmode, p); @@ -19479,59 +19488,33 @@ /* We do floats first so that the instruction pattern matches properly. */ for (i = 0; i < 64 - info->first_fp_reg_save; i++) - { - rtx reg = gen_rtx_REG ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), - info->first_fp_reg_save + i); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->fp_save_offset - + frame_off + 8 * i)); - rtx mem = gen_frame_mem ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); - } + RTVEC_ELT (p, j++) + = gen_frame_store (gen_rtx_REG (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT + ? DFmode : SFmode, + info->first_fp_reg_save + i), + frame_reg_rtx, + info->fp_save_offset + frame_off + 8 * i); for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++) - { - rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->altivec_save_offset - + frame_off + 16 * i)); - rtx mem = gen_frame_mem (V4SImode, addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); - } + RTVEC_ELT (p, j++) + = gen_frame_store (gen_rtx_REG (V4SImode, + info->first_altivec_reg_save + i), + frame_reg_rtx, + info->altivec_save_offset + frame_off + 16 * i); for (i = 0; i < 32 - info->first_gp_reg_save; i++) - { - rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset - + frame_off + reg_size * i)); - rtx mem = gen_frame_mem (reg_mode, addr); + RTVEC_ELT (p, j++) + = gen_frame_store (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), + frame_reg_rtx, + info->gp_save_offset + frame_off + reg_size * i); - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); - } - - { - /* CR register traditionally saved as CR2. */ - rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->cr_save_offset - + frame_off)); - rtx mem = gen_frame_mem (reg_mode, addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); - } + /* CR register traditionally saved as CR2. */ + RTVEC_ELT (p, j++) + = gen_frame_store (gen_rtx_REG (SImode, CR2_REGNO), + frame_reg_rtx, info->cr_save_offset + frame_off); /* Explain about use of R0. */ if (info->lr_save_p) - { - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->lr_save_offset - + frame_off)); - rtx mem = gen_frame_mem (reg_mode, addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0); - } + RTVEC_ELT (p, j++) + = gen_frame_store (reg0, + frame_reg_rtx, info->lr_save_offset + frame_off); /* Explain what happens to the stack pointer. */ { rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg); @@ -19834,17 +19817,10 @@ int i; p = rtvec_alloc (32 - info->first_gp_reg_save); for (i = 0; i < 32 - info->first_gp_reg_save; i++) - { - rtx addr, reg, mem; - reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset - + frame_off - + reg_size * i)); - mem = gen_frame_mem (reg_mode, addr); - - RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg); - } + RTVEC_ELT (p, i) + = gen_frame_store (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), + frame_reg_rtx, + info->gp_save_offset + frame_off + reg_size * i); insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, NULL_RTX, NULL_RTX); @@ -19860,22 +19836,37 @@ sp_off - frame_off); } - /* ??? There's no need to emit actual instructions here, but it's the - easiest way to get the frame unwind information emitted. */ if (crtl->calls_eh_return) { - unsigned int i, regno; + unsigned int i; + rtvec p; for (i = 0; ; ++i) { - regno = EH_RETURN_DATA_REGNO (i); + unsigned int regno = EH_RETURN_DATA_REGNO (i); if (regno == INVALID_REGNUM) break; + } - emit_frame_save (frame_reg_rtx, reg_mode, regno, - info->ehrd_offset + frame_off + reg_size * (int) i, - sp_off - frame_off); + p = rtvec_alloc (i); + + for (i = 0; ; ++i) + { + unsigned int regno = EH_RETURN_DATA_REGNO (i); + if (regno == INVALID_REGNUM) + break; + + insn + = gen_frame_store (gen_rtx_REG (reg_mode, regno), + sp_reg_rtx, + info->ehrd_offset + sp_off + reg_size * (int) i); + RTVEC_ELT (p, i) = insn; + RTX_FRAME_RELATED_P (insn) = 1; } + + insn = emit_insn (gen_blockage ()); + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_FRAME_RELATED_EXPR, gen_rtx_PARALLEL (VOIDmode, p)); } /* In AIX ABI we need to make sure r2 is really saved. */ @@ -20522,13 +20513,9 @@ { /* CR register traditionally saved as CR2. */ - rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->cr_save_offset)); - rtx mem = gen_frame_mem (reg_mode, addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); - + rtx reg = gen_rtx_REG (SImode, CR2_REGNO); + RTVEC_ELT (p, j++) + = gen_frame_load (reg, frame_reg_rtx, info->cr_save_offset); if (flag_shrink_wrap) { cfa_restores = alloc_reg_note (REG_CFA_RESTORE, @@ -20541,24 +20528,18 @@ for (i = 0; i < 32 - info->first_gp_reg_save; i++) { rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset - + reg_size * i)); - rtx mem = gen_frame_mem (reg_mode, addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); + RTVEC_ELT (p, j++) + = gen_frame_load (reg, + frame_reg_rtx, info->gp_save_offset + reg_size * i); if (flag_shrink_wrap) cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); } for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++) { rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->altivec_save_offset - + 16 * i)); - rtx mem = gen_frame_mem (V4SImode, addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); + RTVEC_ELT (p, j++) + = gen_frame_load (reg, + frame_reg_rtx, info->altivec_save_offset + 16 * i); if (flag_shrink_wrap) cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); } @@ -20567,13 +20548,8 @@ rtx reg = gen_rtx_REG ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT ? DFmode : SFmode), info->first_fp_reg_save + i); - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->fp_save_offset - + 8 * i)); - rtx mem = gen_frame_mem ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), addr); - - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); + RTVEC_ELT (p, j++) + = gen_frame_load (reg, frame_reg_rtx, info->fp_save_offset + 8 * i); if (flag_shrink_wrap) cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); } @@ -21076,16 +21052,10 @@ rtvec p; p = rtvec_alloc (32 - info->first_gp_reg_save); for (i = 0; i < 32 - info->first_gp_reg_save; i++) - { - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset - + frame_off - + reg_size * i)); - rtx mem = gen_frame_mem (reg_mode, addr); - rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - - RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem); - } + RTVEC_ELT (p, i) + = gen_frame_load (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), + frame_reg_rtx, + info->gp_save_offset + frame_off + reg_size * i); emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); } else @@ -21277,14 +21247,10 @@ ? 1 : 11)); for (i = 0; i < 64 - info->first_fp_reg_save; i++) { - rtx addr, mem, reg; + rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); - addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, - GEN_INT (info->fp_save_offset + 8 * i)); - mem = gen_frame_mem (DFmode, addr); - reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); - - RTVEC_ELT (p, i + 4) = gen_rtx_SET (VOIDmode, reg, mem); + RTVEC_ELT (p, i + 4) + = gen_frame_load (reg, sp_reg_rtx, info->fp_save_offset + 8 * i); if (flag_shrink_wrap) cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);