From patchwork Tue Mar 27 21:54:02 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: 149044 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 63DA6B6EEC for ; Wed, 28 Mar 2012 08:54:21 +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=1333490061; 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=73shnnhP5zMji02LsxPU y4v5mic=; b=U23xYp+r2qrs1efTq2p9A6XLDw4sXOAlYsMkj32dHrYpkO4wcz2s x2iq6604V0JJCj+/K+AUQ3FWRXJv+YWwXWcrXtx8XjkUXu+QLfNluHw0keILhIix L4WNEmvKYVZzQtHiEoFLCZax5f8K65M4iprNEHGSlBzWAAuC4xpI7wI= 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=d0sFnfwsYAriuxavCK7CMaON6HZcURuDCAHYnSS0uPeYVGu2vZHC7rb8ss2F04 +nSD6TmQluyubvsR5/9Cp5KnzDNtORpgZU0aYB3ryeODdCzb1+CKnEFizrcypjOy Upa35IoB3bnjK8PzhUPORP9VGEAyPaBB4eNPrr2z5wsTc=; Received: (qmail 2478 invoked by alias); 27 Mar 2012 21:54:17 -0000 Received: (qmail 2469 invoked by uid 22791); 27 Mar 2012 21:54:16 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL, BAYES_00, MEDICAL_SUBJECT, 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; Tue, 27 Mar 2012 21:54:04 +0000 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 27 Mar 2012 14:54:03 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.135]) by orsmga002.jf.intel.com with ESMTP; 27 Mar 2012 14:54:03 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id DDA1EC1F9A; Tue, 27 Mar 2012 14:54:02 -0700 (PDT) Date: Tue, 27 Mar 2012 14:54:02 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: rth@redhat.com Subject: PATCH: Remove *load_tp_x32 from i386.md Message-ID: <20120327215402.GA12115@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 Richard, Segment registers %fs and %gs are special in 64bit mode. For a memory operand "%fs:address", its effective address is the base address of %fs + address. The base address of %fs are hidden and "mov %fs, %ax" will only access the visible part of %fs, which is the 16bit segment selector. In 64bit mode, UNSPEC_TP refers to the base address of %fs. To access the base address of %fs, we can use system call: 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. we must use the system call to update the base address of %fs, To read the base address of %fs, OS arranges that the base address of %fs points to a struct: typedef struct { void *tcb; /* Pointer to the TCB. Not necessarily the thread descriptor used by libpthread. */ ... } and sets up "tcb" == the base address of %fs so that the address of "%fs:0" is the address of the tcb field. For x32, the base address of %fs is between 0 and 0xffffffff. We can use "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" to move the base address of %fs into %r32 and %r64 directly. In case of %r32, we are loading "tcb", which is a 32bit memory. For %r64, we are loading "tcb" and zero-extend it to 64bit. This patch is tested on Linux/x32 with GCC and glibc with both -maddress-mode=long and -maddress-mode=short. OK for trunk? Thanks. H.J. --- 2012-03-27 H.J. Lu * config/i386/i386.c (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. 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 @@ -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")