From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31259 invoked by alias); 26 Jun 2011 07:59:10 -0000 Received: (qmail 31044 invoked by uid 22791); 26 Jun 2011 07:59:08 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 26 Jun 2011 07:58:52 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id E8E53CB02A6; Sun, 26 Jun 2011 09:58:50 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9ZgAeVP+ZD2l; Sun, 26 Jun 2011 09:58:47 +0200 (CEST) Received: from [192.168.1.2] (bon31-9-83-155-120-49.fbx.proxad.net [83.155.120.49]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id B7FFACB0242; Sun, 26 Jun 2011 09:58:47 +0200 (CEST) From: Eric Botcazou To: Richard Henderson Subject: Re: [RFC] Fix unwind info for sparc -mflat Date: Sun, 26 Jun 2011 12:09:00 -0000 User-Agent: KMail/1.9.9 Cc: laurent.rouge@menta.fr, GCC Patches References: <4DFFE6DE.9050207@twiddle.net> In-Reply-To: <4DFFE6DE.9050207@twiddle.net> MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_eauBON6W46612Tk" Message-Id: <201106260958.22375.ebotcazou@adacore.com> 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-06/txt/msg01931.txt.bz2 --Boundary-00=_eauBON6W46612Tk Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 1385 > I tried to figure out why things had been done in this > slightly convoluted manner and failed. It seems to me that > this is easily represented with the individual instructions. > A comment indicated that there had been problems with the > copy to %o7 being deleted. Elsewhere we have successfully > used a naked USE pattern to keep such things from being > deleted. I have 4 regressions in the C testsuite with -mflat on SPARC/Solaris: FAIL: gcc.c-torture/execute/builtins/stpcpy-chk.c execution, -O2 -flto FAIL: gcc.c-torture/execute/nestfunc-4.c execution, -Os FAIL: gcc.c-torture/execute/pr19005.c execution, -O2 FAIL: gcc.c-torture/execute/strncmp-1.c execution, -O2 -flt The problem is that the blockage isn't emitted if the frame pointer isn't used. I have also fixed the swapping %o7/%i7 (despite the name, %o7 is the incoming return address register from GCC's viewpoint, and %i7 the register where you save the return address for the rest of the function). Tested on SPARC/Solaris, applied on the mainline. 2011-06-26 Eric Botcazou * config/sparc/sparc.c (save_local_or_in_reg_p): Adjust comment. (emit_save_register_window): Likewise. (sparc_expand_prologue): Use SIZE_INT_RTX and SIZE_RTX variables. (sparc_flat_expand_prologue): Add comment. Always emit blockage. Swap back %o7/%i7 in register naming. -- Eric Botcazou --Boundary-00=_eauBON6W46612Tk Content-Type: text/x-diff; charset="iso 8859-15"; name="p.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="p.diff" Content-length: 4584 Index: config/sparc/sparc.c =================================================================== --- config/sparc/sparc.c (revision 175398) +++ config/sparc/sparc.c (working copy) @@ -4149,7 +4149,7 @@ save_local_or_in_reg_p (unsigned int reg if (regno == RETURN_ADDR_REGNUM && return_addr_reg_needed_p (leaf_function)) return true; - /* PIC register (%l7) if needed. */ + /* GOT register (%l7) if needed. */ if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table) return true; @@ -4600,11 +4600,12 @@ emit_save_register_window (rtx increment insn = emit_insn (gen_save_register_window_1 (increment)); RTX_FRAME_RELATED_P (insn) = 1; - /* The return address (%i7) is saved in %o7. */ + /* The incoming return address (%o7) is saved in %i7. */ add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), - gen_rtx_REG (Pmode, INCOMING_RETURN_ADDR_REGNUM))); + gen_rtx_REG (Pmode, + INCOMING_RETURN_ADDR_REGNUM))); /* The window save event. */ add_reg_note (insn, REG_CFA_WINDOW_SAVE, const0_rtx); @@ -4688,8 +4689,10 @@ sparc_expand_prologue (void) ; /* do nothing. */ else if (sparc_leaf_function_p) { + rtx size_int_rtx = GEN_INT (-size); + if (size <= 4096) - insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-size))); + insn = emit_insn (gen_stack_pointer_inc (size_int_rtx)); else if (size <= 8192) { insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096))); @@ -4699,19 +4702,21 @@ sparc_expand_prologue (void) } else { - rtx reg = gen_rtx_REG (Pmode, 1); - emit_move_insn (reg, GEN_INT (-size)); - insn = emit_insn (gen_stack_pointer_inc (reg)); + rtx size_rtx = gen_rtx_REG (Pmode, 1); + emit_move_insn (size_rtx, size_int_rtx); + insn = emit_insn (gen_stack_pointer_inc (size_rtx)); add_reg_note (insn, REG_FRAME_RELATED_EXPR, - gen_stack_pointer_inc (GEN_INT (-size))); + gen_stack_pointer_inc (size_int_rtx)); } RTX_FRAME_RELATED_P (insn) = 1; } else { + rtx size_int_rtx = GEN_INT (-size); + if (size <= 4096) - emit_save_register_window (GEN_INT (-size)); + emit_save_register_window (size_int_rtx); else if (size <= 8192) { emit_save_register_window (GEN_INT (-4096)); @@ -4720,9 +4725,9 @@ sparc_expand_prologue (void) } else { - rtx reg = gen_rtx_REG (Pmode, 1); - emit_move_insn (reg, GEN_INT (-size)); - emit_save_register_window (reg); + rtx size_rtx = gen_rtx_REG (Pmode, 1); + emit_move_insn (size_rtx, size_int_rtx); + emit_save_register_window (size_rtx); } } @@ -4783,6 +4788,10 @@ sparc_flat_expand_prologue (void) size_rtx = size_int_rtx = GEN_INT (-size); + /* We establish the frame (i.e. decrement the stack pointer) first, even + if we use a frame pointer, because we cannot clobber any call-saved + registers, including the frame pointer, if we haven't created a new + register save area, for the sake of compatibility with the ABI. */ if (size <= 4096) insn = emit_insn (gen_stack_pointer_inc (size_int_rtx)); else if (size <= 8192 && !frame_pointer_needed) @@ -4801,6 +4810,9 @@ sparc_flat_expand_prologue (void) } RTX_FRAME_RELATED_P (insn) = 1; + /* Ensure nothing is scheduled until after the frame is established. */ + emit_insn (gen_blockage ()); + if (frame_pointer_needed) { insn = emit_insn (gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx, @@ -4813,26 +4825,22 @@ sparc_flat_expand_prologue (void) gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx, plus_constant (stack_pointer_rtx, size))); - - /* Make sure nothing is scheduled until after the frame - is established. */ - emit_insn (gen_blockage ()); } if (return_addr_reg_needed_p (sparc_leaf_function_p)) { - rtx i7 = gen_rtx_REG (Pmode, INCOMING_RETURN_ADDR_REGNUM); - rtx o7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + rtx o7 = gen_rtx_REG (Pmode, INCOMING_RETURN_ADDR_REGNUM); + rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); - insn = emit_move_insn (o7, i7); + insn = emit_move_insn (i7, o7); RTX_FRAME_RELATED_P (insn) = 1; add_reg_note (insn, REG_CFA_REGISTER, - gen_rtx_SET (VOIDmode, o7, i7)); + gen_rtx_SET (VOIDmode, i7, o7)); /* Prevent this instruction from ever being considered dead, even if this function has no epilogue. */ - emit_insn (gen_rtx_USE (VOIDmode, o7)); + emit_insn (gen_rtx_USE (VOIDmode, i7)); } } --Boundary-00=_eauBON6W46612Tk--