From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9476 invoked by alias); 25 Sep 2011 17:27:44 -0000 Received: (qmail 9463 invoked by uid 22791); 25 Sep 2011 17:27:43 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-wy0-f175.google.com (HELO mail-wy0-f175.google.com) (74.125.82.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Sep 2011 17:27:28 +0000 Received: by wyh5 with SMTP id 5so5645536wyh.20 for ; Sun, 25 Sep 2011 10:27:27 -0700 (PDT) Received: by 10.227.2.206 with SMTP id 14mr5976445wbk.94.1316971647504; Sun, 25 Sep 2011 10:27:27 -0700 (PDT) Received: from localhost (rsandifo.gotadsl.co.uk. [82.133.89.107]) by mx.google.com with ESMTPS id fr18sm26920819wbb.9.2011.09.25.10.27.24 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 25 Sep 2011 10:27:25 -0700 (PDT) From: Richard Sandiford To: Bernd Schmidt Mail-Followup-To: Bernd Schmidt ,Richard Henderson , GCC Patches , rdsandiford@googlemail.com Cc: Richard Henderson , GCC Patches Subject: Re: Handle multi-word regsiters in REG_CFA_RESTORE notes References: <4E7150E4.10004@codesourcery.com> <4E72551E.3060307@redhat.com> <4E79FAD7.8000908@codesourcery.com> <4E7A2004.8080603@redhat.com> <4E7B9C2E.2090102@codesourcery.com> Date: Sun, 25 Sep 2011 19:54:00 -0000 In-Reply-To: <4E7B9C2E.2090102@codesourcery.com> (Bernd Schmidt's message of "Thu, 22 Sep 2011 22:35:58 +0200") Message-ID: <87mxdso7lw.fsf@firetop.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-09/txt/msg01524.txt.bz2 Bernd Schmidt writes: > On 09/21/11 19:33, Richard Henderson wrote: >> Why, then, is this the only place in dwarf2cfi that needs to handle >> registers via a loop over nregs? It seems to me that we should either >> be handling multi-register spans everywhere or nowhere. >> >> Because alternately, this could be a bug in your backend that you >> failed to add two RESTORE notes instead of just one... > > Well, changing the backend works too. Patch below. > > > Bernd > > * mips.c (mips_restore_reg): Split multiword registers for > REG_CFA_RESTORE notes. > > Index: gcc/config/mips/mips.c > =================================================================== > --- gcc/config/mips/mips.c (revision 178847) > +++ gcc/config/mips/mips.c (working copy) > @@ -10286,16 +10286,28 @@ mips_epilogue_set_cfa (rtx reg, HOST_WID > static void > mips_restore_reg (rtx reg, rtx mem) > { > + enum machine_mode mode = GET_MODE (reg); > + unsigned regno = REGNO (reg); > + > /* There's no MIPS16 instruction to load $31 directly. Load into > $7 instead and adjust the return insn appropriately. */ > - if (TARGET_MIPS16 && REGNO (reg) == RETURN_ADDR_REGNUM) > - reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7); > + if (TARGET_MIPS16 && regno == RETURN_ADDR_REGNUM) > + reg = gen_rtx_REG (mode, GP_REG_FIRST + 7); > + else if (GET_MODE_SIZE (mode) != 8 || !mips_split_64bit_move_p (reg, mem)) > + mips_epilogue.cfa_restores > + = alloc_reg_note (REG_CFA_RESTORE, reg, mips_epilogue.cfa_restores); > else > - mips_epilogue.cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, > - mips_epilogue.cfa_restores); > + { > + rtx word1 = mips_subword (reg, true); > + rtx word2 = mips_subword (reg, false); > + mips_epilogue.cfa_restores > + = alloc_reg_note (REG_CFA_RESTORE, word1, mips_epilogue.cfa_restores); > + mips_epilogue.cfa_restores > + = alloc_reg_note (REG_CFA_RESTORE, word2, mips_epilogue.cfa_restores); > + } I think the condition ought to match that in mips_save_reg: static void mips_save_reg (rtx reg, rtx mem) { if (GET_MODE (reg) == DFmode && !TARGET_FLOAT64) { rtx x1, x2; if (mips_split_64bit_move_p (mem, reg)) mips_split_doubleword_move (mem, reg); else mips_emit_move (mem, reg); x1 = mips_frame_set (mips_subword (mem, false), mips_subword (reg, false)); x2 = mips_frame_set (mips_subword (mem, true), mips_subword (reg, true)); mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x1, x2))); } else mips_emit_save_slot_move (mem, reg, MIPS_PROLOGUE_TEMP (GET_MODE (reg))); } The store itself can still be a single SDC1 instruction, so we should generate the same notes regardless of mips_split_64bit_move_p. If that's right, then how about the patch below (tested on mips64-linux-gnu, but without the shrink-wrap patches)? Richard gcc/ 2011-09-25 Bernd Schmidt Richard Sandiford * config/mips/mips.c (mips_add_cfa_restore): New function. (mips16e_save_restore_reg): Use it. (mips_restore_reg): Likewise. Split double FPRs for REG_CFA_RESTORE notes. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2011-09-25 18:16:38.000000000 +0100 +++ gcc/config/mips/mips.c 2011-09-25 18:19:15.000000000 +0100 @@ -8202,6 +8202,15 @@ mips_frame_set (rtx mem, rtx reg) return set; } + +/* Record that the epilogue has restored call-saved register REG. */ + +static void +mips_add_cfa_restore (rtx reg) +{ + mips_epilogue.cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, + mips_epilogue.cfa_restores); +} /* If a MIPS16e SAVE or RESTORE instruction saves or restores register mips16e_s2_s8_regs[X], it must also save the registers in indexes @@ -8393,8 +8402,7 @@ mips16e_save_restore_reg (bool restore_p reg = gen_rtx_REG (SImode, regno); if (restore_p) { - mips_epilogue.cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, - mips_epilogue.cfa_restores); + mips_add_cfa_restore (reg); return gen_rtx_SET (VOIDmode, reg, mem); } if (reg_parm_p) @@ -10290,9 +10298,13 @@ mips_restore_reg (rtx reg, rtx mem) $7 instead and adjust the return insn appropriately. */ if (TARGET_MIPS16 && REGNO (reg) == RETURN_ADDR_REGNUM) reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7); + else if (GET_MODE (reg) == DFmode && !TARGET_FLOAT64) + { + mips_add_cfa_restore (mips_subword (reg, true)); + mips_add_cfa_restore (mips_subword (reg, false)); + } else - mips_epilogue.cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, - mips_epilogue.cfa_restores); + mips_add_cfa_restore (reg); mips_emit_save_slot_move (reg, mem, MIPS_EPILOGUE_TEMP (GET_MODE (reg))); if (REGNO (reg) == REGNO (mips_epilogue.cfa_reg))