From patchwork Sat Mar 24 18:00:39 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 148530 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 C1433B6EEC for ; Sun, 25 Mar 2012 05:01:02 +1100 (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=1333216864; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Date:From:To:Cc:Subject:Message-ID:Reply-To: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=R7H+1fPbzGaXREpC3g11 CKQi8Hk=; b=pKUacO43Vh1239L5n6Cn7jUqcATgzv64L9LXkbaXgJqSwo+NI6IF PctGkSbMzPTqrmdGDhc79yPHSpbMj69bFsxg13AVFEM8B64JP0mnExxeVGtQYwXh udjb8om8XxcuTw5cd8qhQb7yzYLU2kFbmJQMX+XuFCHoPmh5/nGbGgo= 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:X-ExtLoop1:Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=fH6WFvAWLseliDMYuq4LE1UwRLsnqWnogwEU76CnE/nyKLE3xOzuSUpjE++3Qp xfyc19dCqH097DhCxflqx0kMqNrlLnFuPkBPZxF7vDh1N91wahPeL53DLGrzx/9L GWZpw2Xlck6gAtfWPARsM9+D2RA/hBAZ+sIySDEgUnyGQ=; Received: (qmail 6363 invoked by alias); 24 Mar 2012 18:00:56 -0000 Received: (qmail 6350 invoked by uid 22791); 24 Mar 2012 18:00:54 -0000 X-SWARE-Spam-Status: No, hits=-4.2 required=5.0 tests=AWL, BAYES_00, NO_DNS_FOR_FROM, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga09.intel.com (HELO mga09.intel.com) (134.134.136.24) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 24 Mar 2012 18:00:40 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 24 Mar 2012 11:00:39 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.135]) by orsmga001.jf.intel.com with ESMTP; 24 Mar 2012 11:00:39 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id 5BA1CC1DE6; Sat, 24 Mar 2012 11:00:39 -0700 (PDT) Date: Sat, 24 Mar 2012 11:00:39 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: Uros Bizjak Subject: PATCH: PR target/52698: -maddress-mode=long doesn't work Message-ID: <20120324180039.GA10735@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) 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 Hi, Zero-extend UNSPEC_TP leads problems in ix86_decompose_address. In 64bit mode for both x32 and x86-64, thread pointer is an address stored in %fs, which is a 64bit segment register. Since there is no direct access to %fs from user space, OS provides a system call to write/read %fs: int arch_prctl(int code, unsigned long addr); int arch_prctl(int code, unsigned long *addr); ARCH_SET_FS Set the 64-bit base for the FS register to addr. ARCH_GET_FS Return the 64-bit base value for the FS register of the current thread in the unsigned long pointed to by addr. To avoid a call of arch_prctl (ARCH_GET_FS, &addr) to read %fs, OS arrangs %fs points to a struct: typedef struct { void *tcb; /* Pointer to the TCB. Not necessarily the thread descriptor used by libpthread. */ ... } OS sets up tcb == %fs. Then we can use (define_insn "*load_tp_" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(const_int 0)] UNSPEC_TP))] "!TARGET_X32" "mov{}\t{%%:0, %0|%0, PTR :0}" [(set_attr "type" "imov") (set_attr "modrm" "0") (set_attr "length" "7") (set_attr "memory" "load") (set_attr "imm_disp" "false")]) instead of void * get_tp (void) { unsigned long long addr; arch_prctl (ARCH_GET_FS, &addr); return (void *) addr; } Since x32 address space is 32bit, the upper 32bits of %fs are always zero and we can still use a pointer to store %fs value. To load TP into SImode or DImode register we can use (define_insn "*load_tp_x32_" [(set (match_operand:SWI48x 0 "register_operand" "=r") (unspec:SWI48x [(const_int 0)] UNSPEC_TP))] "TARGET_X32" "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" [(set_attr "type" "imov") (set_attr "modrm" "0") (set_attr "length" "7") (set_attr "memory" "load") (set_attr "imm_disp" "false")]) instead of get_tp calls void * get_tp_si (void) { unsigned long long addr; arch_prctl (ARCH_GET_FS, &addr); return (void *) (unsigned long) addr; } long long get_tp_di (void) { unsigned long long addr; arch_prctl (ARCH_GET_FS, &addr); return addr; } H.J. --- gcc/ 2012-03-24 H.J. Lu PR target/52698 * config/i386/i386.c (ix86_decompose_address): Remove for UNSPEC_TP references. (legitimize_pic_address): Load UNSPEC_TP into tp_mode register directly. * config/i386/i386.md (*load_tp_x32): Removed. (*load_tp_x32_zext): Likewise. (*load_tp_x32_): New. gcc/testsuite/ 2012-03-24 H.J. Lu PR target/52698 * gcc.target/i386/pr52698-1.c: New. * gcc.target/i386/pr52698-2.c: Likewise. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a21f2da..14c4056 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -11514,12 +11514,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) scale = 1 << scale; break; - case ZERO_EXTEND: - op = XEXP (op, 0); - if (GET_CODE (op) != UNSPEC) - return 0; - /* FALLTHRU */ - case UNSPEC: if (XINT (op, 1) == UNSPEC_TP && TARGET_TLS_DIRECT_SEG_REFS @@ -12491,15 +12485,7 @@ legitimize_pic_address (rtx orig, rtx reg) static rtx get_thread_pointer (enum machine_mode tp_mode, bool to_reg) { - rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP); - - if (GET_MODE (tp) != tp_mode) - { - gcc_assert (GET_MODE (tp) == SImode); - gcc_assert (tp_mode == DImode); - - tp = gen_rtx_ZERO_EXTEND (tp_mode, tp); - } + rtx tp = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP); if (to_reg) tp = copy_to_mode_reg (tp_mode, tp); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2d20a52..ac6124e 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12748,20 +12748,9 @@ (define_mode_attr tp_seg [(SI "gs") (DI "fs")]) ;; Load and add the thread base pointer from %:0. -(define_insn "*load_tp_x32" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(const_int 0)] UNSPEC_TP))] - "TARGET_X32" - "mov{l}\t{%%fs:0, %0|%0, DWORD 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 "*load_tp_x32_zext" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))] +(define_insn "*load_tp_x32_" + [(set (match_operand:SWI48x 0 "register_operand" "=r") + (unspec:SWI48x [(const_int 0)] UNSPEC_TP))] "TARGET_X32" "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" [(set_attr "type" "imov") diff --git a/gcc/testsuite/gcc.target/i386/pr52698-1.c b/gcc/testsuite/gcc.target/i386/pr52698-1.c new file mode 100644 index 0000000..0395521 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr52698-1.c @@ -0,0 +1,18 @@ +/* PR target/52698 */ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-options "-mx32 -O2 -maddress-mode=short" } */ + +extern void abort (void); +static __thread unsigned char foo [32] + __attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *)))); +void +test2 (void) +{ + unsigned int s; + for (s = 0; s < sizeof (foo); ++s) + { + if (foo [s] != s) + abort (); + foo [s] = sizeof (foo) - s; + } +} diff --git a/gcc/testsuite/gcc.target/i386/pr52698-2.c b/gcc/testsuite/gcc.target/i386/pr52698-2.c new file mode 100644 index 0000000..8ad470a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr52698-2.c @@ -0,0 +1,18 @@ +/* PR target/52698 */ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-options "-mx32 -O2 -maddress-mode=long" } */ + +extern void abort (void); +static __thread unsigned char foo [32] + __attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *)))); +void +test2 (void) +{ + unsigned int s; + for (s = 0; s < sizeof (foo); ++s) + { + if (foo [s] != s) + abort (); + foo [s] = sizeof (foo) - s; + } +}