From patchwork Thu Oct 13 15:49:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 119562 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 1BA50B71C1 for ; Fri, 14 Oct 2011 02:51:35 +1100 (EST) Received: (qmail 28154 invoked by alias); 13 Oct 2011 15:51:32 -0000 Received: (qmail 28136 invoked by uid 22791); 13 Oct 2011 15:51:28 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e31.co.us.ibm.com (HELO e31.co.us.ibm.com) (32.97.110.149) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 13 Oct 2011 15:51:08 +0000 Received: from /spool/local by us.ibm.com with XMail ESMTP for from ; Thu, 13 Oct 2011 09:49:56 -0600 Received: from d03relay05.boulder.ibm.com ([9.17.195.107]) by us.ibm.com ([192.168.1.131]) with XMail ESMTP; Thu, 13 Oct 2011 09:49:50 -0600 Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by d03relay05.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p9DFnWwg022596 for ; Thu, 13 Oct 2011 09:49:37 -0600 Received: from d03av03.boulder.ibm.com (loopback [127.0.0.1]) by d03av03.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p9DFnVSH013479 for ; Thu, 13 Oct 2011 09:49:32 -0600 Received: from [192.168.1.101] (vorma.rchland.ibm.com [9.10.86.174]) by d03av03.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p9DFnSB5013190; Thu, 13 Oct 2011 09:49:29 -0600 Subject: Re: [PATCH, rs6000] Preserve link stack for 476 cpus From: Peter Bergner To: David Edelsohn Cc: gcc-patches In-Reply-To: References: <1315843660.6209.45.camel@otta> Date: Thu, 13 Oct 2011 10:49:27 -0500 Message-ID: <1318520967.3133.69.camel@otta> Mime-Version: 1.0 x-cbid: 11101315-7282-0000-0000-0000026E4F1C 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, 2011-09-12 at 15:29 -0400, David Edelsohn wrote: > First, please choose a more informative option name. > -mpreserve-link-stack seems like something generally useful for all > processors and someone may randomly add the option. It always is > useful to preserve the link stack -- that's why you're jumping through > hoops to fix this bug. Maybe -mpreserve-ppc476-link-stack . Done. > I would prefer that this patch were maintained by the chip vendors > distributing SDKs for PPC476 instead of complicating the FSF codebase. Talking with the chip folks, they said there were a number of companies already downloading the FSF gcc sources and building it unpatched and that they expected more to do so in the future, so I'm not sure how many (if any) are actually even relying on a SDK. So... > Otherwise, please implement this like Xilinx FPU in rs6000.opt, > rs6000.h, ppc476.h and config.gcc where TARGET_LINK_STACK is defined > as 0 unless GCC explicitly is configured for powerpc476. Here's a patch to do that, by adding a variant to the powerpc*-*-linux* target for the 476. I bootstrapped and regtested this as before, meaning I also tested this with the -mpreserve-ppc476-link-stack on by default, as well as configuring without 476 support and verified that the TARGET_LINK_STACK tests are not only optimized away, but so is the -mpreserve-ppc476-link-stack option itself. Is this ok for mainline now? Peter * config.gcc (powerpc*-*-linux*): Add powerpc*-*-linux*ppc476* variant. * config/rs6000/476.h: New file. * config/rs6000/476.opt: Likewise. * config/rs6000/rs6000.h (TARGET_LINK_STACK): New define. (SET_TARGET_LINK_STACK): Likewise. * config/rs6000/rs6000.c (rs6000_option_override_internal): Enable TARGET_LINK_STACK for -mtune=476 and -mtune=476fp. (rs6000_legitimize_tls_address): Emit the link stack preserving GOT code if TARGET_LINK_STACK. (rs6000_emit_load_toc_table): Likewise. (output_function_profiler): Likewise (macho_branch_islands): Likewise (machopic_output_stub): Likewise * config/rs6000/rs6000.md (load_toc_v4_PIC_1, load_toc_v4_PIC_1b): Convert to a define_expand. (load_toc_v4_PIC_1_normal): New define_insn. (load_toc_v4_PIC_1_476): Likewise. (load_toc_v4_PIC_1b_normal): Likewise. (load_toc_v4_PIC_1b_476): Likewise. Index: gcc/config.gcc =================================================================== --- gcc/config.gcc (revision 179091) +++ gcc/config.gcc (working copy) @@ -2133,6 +2133,9 @@ powerpc-*-linux* | powerpc64-*-linux*) esac tmake_file="${tmake_file} t-slibgcc-libgcc" case ${target} in + powerpc*-*-linux*ppc476*) + tm_file="${tm_file} rs6000/476.h" + extra_options="${extra_options} rs6000/476.opt" ;; powerpc*-*-linux*altivec*) tm_file="${tm_file} rs6000/linuxaltivec.h" ;; powerpc*-*-linux*spe*) Index: gcc/config/rs6000/476.h =================================================================== --- gcc/config/rs6000/476.h (revision 0) +++ gcc/config/rs6000/476.h (revision 0) @@ -0,0 +1,29 @@ +/* Enable IBM PowerPC 476 support. + Copyright (C) 2011 Free Software Foundation, Inc. + Contributed by Peter Bergner (bergner@vnet.ibm.com) + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#undef TARGET_LINK_STACK +#define TARGET_LINK_STACK (rs6000_link_stack) + +#undef SET_TARGET_LINK_STACK +#define SET_TARGET_LINK_STACK(X) do { TARGET_LINK_STACK = (X); } while (0) Index: gcc/config/rs6000/476.opt =================================================================== --- gcc/config/rs6000/476.opt (revision 0) +++ gcc/config/rs6000/476.opt (revision 0) @@ -0,0 +1,24 @@ +; IBM PowerPC 476 options. +; +; Copyright (C) 2011 Free Software Foundation, Inc. +; Contributed by Peter Bergner (bergner@vnet.ibm.com) +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +; WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +; for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +mpreserve-ppc476-link-stack +Target Var(rs6000_link_stack) Init(-1) Save +Preserve the PowerPC 476's link stack by matching up a blr with the bcl/bl insns used for GOT accesses Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 179091) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -3244,6 +3244,11 @@ rs6000_option_override_internal (bool gl target_option_default_node = target_option_current_node = build_target_option_node (); + /* If not explicitly specified via option, decide whether to generate the + extra blr's required to preserve the link stack on some cpus (eg, 476). */ + if (TARGET_LINK_STACK == -1) + SET_TARGET_LINK_STACK (rs6000_cpu == PROCESSOR_PPC476); + return ret; } @@ -5932,6 +5937,8 @@ rs6000_legitimize_tls_address (rtx addr, lab = gen_label_rtx (); emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab)); emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO)); + if (TARGET_LINK_STACK) + emit_insn (gen_addsi3 (tmp1, tmp1, GEN_INT (4))); emit_move_insn (tmp2, mem); last = emit_insn (gen_addsi3 (got, tmp1, tmp2)); set_unique_reg_note (last, REG_EQUAL, gsym); @@ -18923,6 +18930,8 @@ rs6000_emit_load_toc_table (int fromprol lab = gen_label_rtx (); emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab)); emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); + if (TARGET_LINK_STACK) + emit_insn (gen_addsi3 (dest, dest, GEN_INT (4))); emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest)); } emit_insn (gen_addsi3 (dest, temp0, dest)); @@ -22493,7 +22502,11 @@ output_function_profiler (FILE *file, in } else if (TARGET_SECURE_PLT && flag_pic) { - asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n", + if (TARGET_LINK_STACK) + asm_fprintf (file, "\tbl 1f\n\tb 2f\n1:\n\tblr\n2:\n"); + else + asm_fprintf (file, "\tbcl 20,31,1f\n1:\n"); + asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", reg_names[0], reg_names[1]); asm_fprintf (file, "\tmflr %s\n", reg_names[12]); asm_fprintf (file, "\t{cau|addis} %s,%s,", @@ -22518,10 +22531,22 @@ output_function_profiler (FILE *file, in asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", reg_names[0], reg_names[1]); /* Now, we need to get the address of the label. */ - fputs ("\tbcl 20,31,1f\n\t.long ", file); - assemble_name (file, buf); - fputs ("-.\n1:", file); - asm_fprintf (file, "\tmflr %s\n", reg_names[11]); + if (TARGET_LINK_STACK) + { + fputs ("\tbl 1f\n\tb 2f\n\t.long ", file); + assemble_name (file, buf); + fputs ("-.\n1:\n\tblr\n2:", file); + asm_fprintf (file, "\tmflr %s\n", reg_names[11]); + asm_fprintf (file, "\taddi %s,%s,4\n", + reg_names[11], reg_names[11]); + } + else + { + fputs ("\tbcl 20,31,1f\n\t.long ", file); + assemble_name (file, buf); + fputs ("-.\n1:", file); + asm_fprintf (file, "\tmflr %s\n", reg_names[11]); + } asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n", reg_names[0], reg_names[11]); asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", @@ -25004,11 +25029,22 @@ macho_branch_islands (void) #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ if (flag_pic) { - strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,"); - strcat (tmp_buf, label); - strcat (tmp_buf, "_pic\n"); - strcat (tmp_buf, label); - strcat (tmp_buf, "_pic:\n\tmflr r11\n"); + if (TARGET_LINK_STACK) + { + strcat (tmp_buf, ":\n\tmflr r0\n\tbl $+8\n"); + strcat (tmp_buf, label); + strcat (tmp_buf, "_pic:\n\tb $+8\n"); + strcat (tmp_buf, "\tblr\n"); + strcat (tmp_buf, "\tmflr r11\n"); + } + else + { + strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,"); + strcat (tmp_buf, label); + strcat (tmp_buf, "_pic\n"); + strcat (tmp_buf, label); + strcat (tmp_buf, "_pic:\n\tmflr r11\n"); + } strcat (tmp_buf, "\taddis r11,r11,ha16("); strcat (tmp_buf, name_buf); @@ -25154,8 +25190,16 @@ machopic_output_stub (FILE *file, const sprintf (local_label_0, "\"L%011d$spb\"", label); fprintf (file, "\tmflr r0\n"); - fprintf (file, "\tbcl 20,31,%s\n", local_label_0); - fprintf (file, "%s:\n\tmflr r11\n", local_label_0); + if (TARGET_LINK_STACK) + { + fprintf (file, "\tbl $+8\n"); + fprintf (file, "%s:\n\tb $+8\n\tblr\n\tmflr r11\n", local_label_0); + } + else + { + fprintf (file, "\tbcl 20,31,%s\n", local_label_0); + fprintf (file, "%s:\n\tmflr r11\n", local_label_0); + } fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n", lazy_ptr_name, local_label_0); fprintf (file, "\tmtlr r0\n"); Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (revision 179091) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -313,6 +313,14 @@ extern const char *host_detect_local_cpu #define HAVE_AS_TLS 0 #endif +#ifndef TARGET_LINK_STACK +#define TARGET_LINK_STACK 0 +#endif + +#ifndef SET_TARGET_LINK_STACK +#define SET_TARGET_LINK_STACK(X) do { } while (0) +#endif + /* Return 1 for a symbol ref for a thread-local storage symbol. */ #define RS6000_SYMBOL_REF_TLS_P(RTX) \ (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0) Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 179091) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -12081,27 +12081,65 @@ (define_insn "load_toc_v4_pic_si" [(set_attr "type" "branch") (set_attr "length" "4")]) -(define_insn "load_toc_v4_PIC_1" +(define_expand "load_toc_v4_PIC_1" + [(parallel [(set (reg:SI LR_REGNO) + (match_operand:SI 0 "immediate_operand" "s")) + (use (unspec [(match_dup 0)] UNSPEC_TOC))])] + "TARGET_ELF && DEFAULT_ABI != ABI_AIX + && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" + "") + +(define_insn "load_toc_v4_PIC_1_normal" [(set (reg:SI LR_REGNO) (match_operand:SI 0 "immediate_operand" "s")) (use (unspec [(match_dup 0)] UNSPEC_TOC))] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX + "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" "bcl 20,31,%0\\n%0:" [(set_attr "type" "branch") (set_attr "length" "4")]) -(define_insn "load_toc_v4_PIC_1b" +(define_insn "load_toc_v4_PIC_1_476" + [(set (reg:SI LR_REGNO) + (match_operand:SI 0 "immediate_operand" "s")) + (use (unspec [(match_dup 0)] UNSPEC_TOC))] + "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX + && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" + "bl $+8\n%0:\n\tb $+8\n\tblr" + [(set_attr "type" "branch") + (set_attr "length" "12")]) + +(define_expand "load_toc_v4_PIC_1b" + [(parallel [(set (reg:SI LR_REGNO) + (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") + (label_ref (match_operand 1 "" ""))] + UNSPEC_TOCPTR)) + (match_dup 1)])] + "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" + "") + +(define_insn "load_toc_v4_PIC_1b_normal" [(set (reg:SI LR_REGNO) (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") (label_ref (match_operand 1 "" ""))] UNSPEC_TOCPTR)) (match_dup 1)] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" + "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" "bcl 20,31,$+8\;.long %0-$" [(set_attr "type" "branch") (set_attr "length" "8")]) +(define_insn "load_toc_v4_PIC_1b_476" + [(set (reg:SI LR_REGNO) + (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") + (label_ref (match_operand 1 "" ""))] + UNSPEC_TOCPTR)) + (match_dup 1)] + "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" + "bl $+12\n\tb $+12\n\t.long %0-$\n\tblr" + [(set_attr "type" "branch") + (set_attr "length" "16")]) + (define_insn "load_toc_v4_PIC_2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")