From patchwork Mon Dec 20 19:26:03 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 76219 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 9DC96B70AA for ; Tue, 21 Dec 2010 06:26:13 +1100 (EST) Received: (qmail 15071 invoked by alias); 20 Dec 2010 19:26:11 -0000 Received: (qmail 15049 invoked by uid 22791); 20 Dec 2010 19:26:10 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_ZJ X-Spam-Check-By: sourceware.org Received: from mail-px0-f176.google.com (HELO mail-px0-f176.google.com) (209.85.212.176) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 20 Dec 2010 19:26:05 +0000 Received: by pxi11 with SMTP id 11so826892pxi.21 for ; Mon, 20 Dec 2010 11:26:03 -0800 (PST) MIME-Version: 1.0 Received: by 10.142.57.19 with SMTP id f19mr3790004wfa.94.1292873163126; Mon, 20 Dec 2010 11:26:03 -0800 (PST) Received: by 10.142.252.8 with HTTP; Mon, 20 Dec 2010 11:26:03 -0800 (PST) In-Reply-To: References: Date: Mon, 20 Dec 2010 20:26:03 +0100 Message-ID: Subject: Re: Fix 64-bit Solaris 2/x86 IE TLS code sequence (PR target/43309) From: Uros Bizjak To: Rainer Orth Cc: gcc-patches@gcc.gnu.org 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, Dec 20, 2010 at 4:07 PM, Uros Bizjak wrote: > On Mon, Dec 20, 2010 at 1:02 PM, Rainer Orth > wrote: >> I've finally managed to fix PR target/43309, where Sun ld cannot handle >> the 64-bit TLS IE code sequence emitted by gcc. >> >> The issue was discussed within the original patch submission >> >>        PATCH: Fix 64-bit Solaris 2/x86 IE TLS code sequence >>        http://gcc.gnu.org/ml/gcc-patches/2010-02/msg00993.html >> >> and the PR. >> >> While the Solaris linker maintainers have meanwhile agreed that their >> literal interpretation of the AMD64 TLS IE code sequence is too strict >> and intend to relax that to accomodate the code GCC emits, for the time >> being it is still necessary to work around the issue in GCC as below. >> >> Bootstrapped on i386-pc-solaris2.11 with Sun as and ld without >> regressions, fixing all outstanding TLS IE testsuite failures. >> >> Ok for mainline now and 4.4/4.5 backports (slightly modified since they >> lack define_c_enum) later? >> >> Thanks. >>        Rainer >> >> >> 2010-03-06  Uros Bizjak >>            Rainer Orth   >> >>        PR target/43309 >>        * config/i386/i386.c (legitimize_tls_address) >>        : Handle TARGET_64BIT && TARGET_SUN_TLS. >>        * config/i386/i386.md (UNSPEC_TLS_IE_SUN): Declare. >>        (*tls_initial_exec_64_sun): New pattern. >>        (tls_initial_exec_64_sun): New expander. > > This can be handled without expander, by declaring named pattern only. Rainer, what do you think about attached patch? This patch splits TLS sequence into "movq" and "addq" insn, but decorates "add" insn with an unspec to separate it from generic add insn. Uros. Index: i386.c =================================================================== --- i386.c (revision 168050) +++ i386.c (working copy) @@ -12571,7 +12571,23 @@ legitimize_tls_address (rtx x, enum tls_ off = gen_const_mem (Pmode, off); set_mem_alias_set (off, ix86_GOT_alias_set ()); - if (TARGET_64BIT || TARGET_ANY_GNU_TLS) + if (TARGET_64BIT && TARGET_SUN_TLS) + { + /* The SUN linker took the AMD64 TLS spec literally + and can only handle %rax as destination of the + initial executable code sequence. */ + + rtx rax = gen_rtx_REG (Pmode, AX_REG); + + base = get_thread_pointer (false); + emit_insn (gen_rtx_SET (VOIDmode, rax, base)); + emit_insn (gen_add_tls_addr_di_sun (rax, rax, off)); + + dest = gen_reg_rtx (Pmode); + emit_move_insn (dest, rax); + return dest; + } + else if (TARGET_64BIT || TARGET_ANY_GNU_TLS) { base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS); off = force_reg (Pmode, off); Index: i386.md =================================================================== --- i386.md (revision 168050) +++ i386.md (working copy) @@ -93,6 +93,7 @@ UNSPEC_TLS_GD UNSPEC_TLS_LD_BASE UNSPEC_TLSDESC + UNSPEC_TLSDESC_SUN ;; Other random patterns UNSPEC_SCAS @@ -12661,6 +12664,31 @@ ;; Segment register for the thread base ptr load (define_mode_attr tp_seg [(SI "gs") (DI "fs")]) +;; The SUN linker took the AMD64 TLS spec literally and can only handle +;; %rax as the destination of the initial executable code sequence. +(define_insn "*load_tp_di_sun" + [(set (match_operand:DI 0 "register_operand" "=a") + (unspec:DI [(const_int 0)] UNSPEC_TP))] + "TARGET_64BIT && TARGET_SUN_TLS" + "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}" + [(set_attr "type" "imov") + (set_attr "modrm" "0") + (set_attr "length" "7") + (set_attr "memory" "load") + (set_attr "imm_disp" "false")]) + +(define_insn "add_tls_addr_di_sun" + [(set (match_operand:DI 0 "register_operand" "=a") + (plus:DI + (match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "memory_operand" "m"))) + (clobber (reg:CC FLAGS_REG)) + (unspec [(const_int 0)] UNSPEC_TLSDESC_SUN)] + "TARGET_64BIT && TARGET_SUN_TLS" + "add{q}\t{%2, %0|%0, %2}"; + [(set_attr "type" "alu") + (set_attr "mode" "DI")]) + ;; Load and add the thread base pointer from %gs:0. (define_insn "*load_tp_" [(set (match_operand:P 0 "register_operand" "=r")