From patchwork Tue Mar 6 20:57:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 145018 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 4F44DB6EEC for ; Wed, 7 Mar 2012 07:57:56 +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=1331672276; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:In-Reply-To:References:Date: Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=HNGeOfORSJ6hKXAAs0xMJqu8MrY=; b=mNdMADQJZwj6XADw3FKXK6KEt/w6yyc1D7Y782ADfevWPYjZWzv2s23jGshzP+ xSiiGwT9Pl6dGQgzZcgLoxCD7D2fIg3zDi7m11/DBI7/8VYG0lBfikyrhRtQddec 4VzIk72yW9zgVgZtLg1uDkrrnq/2g2ipMDWWmcrzKrS+g= 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:MIME-Version:Received:Received:In-Reply-To:References:Date:Message-ID:Subject:From:To:Cc:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=BidumtXEnvTsv0Qe5R6sC5jaydnVof6kKztB+PmtvbkvTj1Bf+P/IrBy+bnC/g wECHPikOt9Ejre9KXEtm/RrMscLY0isl7J5tJIasVHfQiKHbFehvEbf4VxiXhfEI FY4zCQCxFKQkXvHhYdUfpw5htcTUV0+SOL9XOIpATYb9E=; Received: (qmail 9321 invoked by alias); 6 Mar 2012 20:57:53 -0000 Received: (qmail 9305 invoked by uid 22791); 6 Mar 2012 20:57:51 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-qy0-f175.google.com (HELO mail-qy0-f175.google.com) (209.85.216.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 06 Mar 2012 20:57:37 +0000 Received: by qcso7 with SMTP id o7so2875447qcs.20 for ; Tue, 06 Mar 2012 12:57:36 -0800 (PST) MIME-Version: 1.0 Received: by 10.224.177.132 with SMTP id bi4mr32239qab.35.1331067456405; Tue, 06 Mar 2012 12:57:36 -0800 (PST) Received: by 10.229.89.137 with HTTP; Tue, 6 Mar 2012 12:57:36 -0800 (PST) In-Reply-To: <4F5669D2.8080805@redhat.com> References: <4F5669D2.8080805@redhat.com> Date: Tue, 6 Mar 2012 12:57:36 -0800 Message-ID: Subject: Re: PATCH: Properly check mode for x86 call/jmp address From: "H.J. Lu" To: Richard Henderson Cc: Uros Bizjak , gcc-patches@gcc.gnu.org, Jakub Jelinek 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 Tue, Mar 6, 2012 at 11:47 AM, Richard Henderson wrote: > On 03/06/12 11:10, H.J. Lu wrote: >>  (define_insn "*call" >> -  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "zw")) >> +  [(call (mem:QI (match_operand:C 0 "call_insn_operand" "zw")) >>        (match_operand 1 "" ""))] >> -  "!SIBLING_CALL_P (insn)" >> +  "!SIBLING_CALL_P (insn) >> +   && (GET_CODE (operands[0]) == SYMBOL_REF >> +       || GET_MODE (operands[0]) == word_mode)" > > There are enough copies of this extra constraint that I wonder > if it simply ought to be folded into call_insn_operand. > > Which would need to be changed to define_special_predicate, > since you'd be doing your own mode checking. > > Probably similar changes to sibcall_insn_operand. > > > r~ Here is the updated patch. I changed constant_call_address_operand and call_register_no_elim_operand to use define_special_predicate. OK for trunk? Thanks. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 973bbeb..7ee71fa 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -22940,14 +22940,18 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0))); - else if (sibcall - ? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode) - : !call_insn_operand (XEXP (fnaddr, 0), Pmode)) + else if (!(constant_call_address_operand (XEXP (fnaddr, 0), Pmode) + || call_register_no_elim_operand (XEXP (fnaddr, 0), + word_mode) + || (!sibcall + && !TARGET_X32 + && memory_operand (XEXP (fnaddr, 0), word_mode)))) { fnaddr = XEXP (fnaddr, 0); - if (GET_MODE (fnaddr) != Pmode) - fnaddr = convert_to_mode (Pmode, fnaddr, 1); - fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (Pmode, fnaddr)); + if (GET_MODE (fnaddr) != word_mode) + fnaddr = convert_to_mode (word_mode, fnaddr, 1); + fnaddr = gen_rtx_MEM (QImode, + copy_to_mode_reg (word_mode, fnaddr)); } vec_len = 0; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index bfbf5bf..801ffa2 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -896,6 +896,16 @@ ;; ptr_mode sized quantities. (define_mode_iterator PTR [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")]) + +;; This mode iterator allows :W to be used for patterns that operate on +;; word_mode sized quantities. +(define_mode_iterator W + [(SI "word_mode == SImode") (DI "word_mode == DImode")]) + +;; This mode iterator allows :C to be used for patterns that operate on +;; pointer-sized and word_mode sized quantities. +(define_mode_iterator C + [(SI "Pmode == SImode") (DI "word_mode == DImode")]) ;; Scheduling descriptions @@ -11076,10 +11086,15 @@ (set_attr "modrm" "0")]) (define_expand "indirect_jump" - [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]) + [(set (pc) (match_operand 0 "indirect_branch_operand" ""))] + "" +{ + if (TARGET_X32) + operands[0] = convert_memory_address (word_mode, operands[0]); +}) (define_insn "*indirect_jump" - [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))] + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))] "" "jmp\t%A0" [(set_attr "type" "ibr") @@ -11121,12 +11136,12 @@ operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, OPTAB_DIRECT); } - else if (TARGET_X32) - operands[0] = convert_memory_address (Pmode, operands[0]); + if (TARGET_X32) + operands[0] = convert_memory_address (word_mode, operands[0]); }) (define_insn "*tablejump_1" - [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw")) + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw")) (use (label_ref (match_operand 1 "" "")))] "" "jmp\t%A0" @@ -11213,7 +11228,7 @@ }) (define_insn_and_split "*call_vzeroupper" - [(call (mem:QI (match_operand:P 0 "call_insn_operand" "zw")) + [(call (mem:QI (match_operand:C 0 "call_insn_operand" "zw")) (match_operand 1 "" "")) (unspec [(match_operand 2 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] @@ -11225,7 +11240,7 @@ [(set_attr "type" "call")]) (define_insn "*call" - [(call (mem:QI (match_operand:P 0 "call_insn_operand" "zw")) + [(call (mem:QI (match_operand:C 0 "call_insn_operand" "zw")) (match_operand 1 "" ""))] "!SIBLING_CALL_P (insn)" "* return ix86_output_call_insn (insn, operands[0]);" @@ -11277,7 +11292,7 @@ [(set_attr "type" "call")]) (define_insn_and_split "*sibcall_vzeroupper" - [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) + [(call (mem:QI (match_operand:C 0 "sibcall_insn_operand" "Uz")) (match_operand 1 "" "")) (unspec [(match_operand 2 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] @@ -11289,7 +11304,7 @@ [(set_attr "type" "call")]) (define_insn "*sibcall" - [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) + [(call (mem:QI (match_operand:C 0 "sibcall_insn_operand" "Uz")) (match_operand 1 "" ""))] "SIBLING_CALL_P (insn)" "* return ix86_output_call_insn (insn, operands[0]);" @@ -11386,7 +11401,7 @@ (define_insn_and_split "*call_value_vzeroupper" [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:P 1 "call_insn_operand" "zw")) + (call (mem:QI (match_operand:C 1 "call_insn_operand" "zw")) (match_operand 2 "" ""))) (unspec [(match_operand 3 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] @@ -11399,7 +11414,7 @@ (define_insn "*call_value" [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:P 1 "call_insn_operand" "zw")) + (call (mem:QI (match_operand:C 1 "call_insn_operand" "zw")) (match_operand 2 "" "")))] "!SIBLING_CALL_P (insn)" "* return ix86_output_call_insn (insn, operands[1]);" @@ -11407,7 +11422,7 @@ (define_insn_and_split "*sibcall_value_vzeroupper" [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) + (call (mem:QI (match_operand:C 1 "sibcall_insn_operand" "Uz")) (match_operand 2 "" ""))) (unspec [(match_operand 3 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] @@ -11420,7 +11435,7 @@ (define_insn "*sibcall_value" [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) + (call (mem:QI (match_operand:C 1 "sibcall_insn_operand" "Uz")) (match_operand 2 "" "")))] "SIBLING_CALL_P (insn)" "* return ix86_output_call_insn (insn, operands[1]);" diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 32f73da..4853bff 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -492,9 +492,11 @@ (match_test "op == ix86_tls_module_base ()"))) ;; Test for a pc-relative call operand -(define_predicate "constant_call_address_operand" +(define_special_predicate "constant_call_address_operand" (match_code "symbol_ref") { + if (mode != Pmode) + return false; if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) return false; if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op)) @@ -506,9 +508,12 @@ ;; is used as a call operand, so they will execute return address as a code. ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. -(define_predicate "call_register_no_elim_operand" +(define_special_predicate "call_register_no_elim_operand" (match_operand 0 "register_operand") { + if (mode != word_mode) + return false; + if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op);