From patchwork Mon May 16 13:44:38 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 95755 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 C0C2CB6EE6 for ; Mon, 16 May 2011 23:45:11 +1000 (EST) Received: (qmail 18518 invoked by alias); 16 May 2011 13:45:05 -0000 Received: (qmail 18258 invoked by uid 22791); 16 May 2011 13:44:59 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST, TW_ZJ, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-pv0-f175.google.com (HELO mail-pv0-f175.google.com) (74.125.83.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 16 May 2011 13:44:39 +0000 Received: by pvc30 with SMTP id 30so2372359pvc.20 for ; Mon, 16 May 2011 06:44:38 -0700 (PDT) MIME-Version: 1.0 Received: by 10.142.113.16 with SMTP id l16mr2758429wfc.97.1305553478641; Mon, 16 May 2011 06:44:38 -0700 (PDT) Received: by 10.143.158.12 with HTTP; Mon, 16 May 2011 06:44:38 -0700 (PDT) Date: Mon, 16 May 2011 15:44:38 +0200 Message-ID: Subject: [PATCH, i386]: Introduce "z" constraint and merge call patterns From: Uros Bizjak To: 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 Hello! Attached patch introduces "z" constraint that matches constant_call_address_operand predicate. Using this constraint, several similar call patterns can be merged into one, substantially lowering the number of similar call patterns. Please note, that the patch also merges SImode and DImode call patterns, although SImode patterns use "lsm" constraint originally. The "l" constraint prevents %esp register, but since operand predicate already rejects %esp hard reg and %rsp itself is marked as fixed reg, RA won't allocate %rsp even when "l" constraint is changed to "r". Using new "z" constraint, *_rex64 and *_rex64_large call patterns can be merged into one. A remaining constraint-less call_0 pattern can also be merged with base call pattern, and finally, using "P" mode iterator, 32bit and 64bit patterns can be merged into one. The patch also changes TLS patterns to accept only constant_call_address_operands for __tls_get_addr symbol. The patch is big, but it removes 300 lines and hopefully brings some sanity to call patterns. 2011-05-16 Uros Bizjak * config/i386/constraints.md (z): New constraint. * config/i386/i386.c (*call): Merge insn pattern from *call_0, *call_1, *call_1_rex64 and *call_1_rex64_large patterns using "P" mode iterator. Use "rzm" constraint for operand 0. (*call_vzeroupper): Ditto. (*call_rex64_ms_sysv): Ditto. (*call_rex64_ms_sysv_vzeroupper): Ditto. (*call_pop): Merge insn pattern from *call_pop_0 and *call_pop_1. Use "rzm" constraint for operand 0. (*call_pop_vzeroupper): Ditto. (*sibcall): Merge insn pattern from *sibcall_0, *sibcall_1 and *sibcall_1_rex64 patterns using "P" mode iterator. Use "Uz" constraint for operand 0. (*sibcall_vzeroupper): Ditto. (*sibcall_rex64_ms_sysv): Ditto. (*sibcall_rex64_ms_sysv_vzeroupper): Ditto. (*sibcall_pop): Merge insn pattern from *sibcall_pop_0 and *sibcall_pop_1. Use "rzm" constraint for operand 0. (*sibcall_pop_vzeroupper): Ditto. (*call_value): Merge insn pattern from *call_value_0, *call_value_1, *call_value_1_rex64 and *call_value_1_rex64_large patterns using "P" mode iterator. Use "rzm" constraint for operand 1. (*call_value_vzeroupper): Ditto. (*call_value_rex64_ms_sysv): Ditto. (*call_value_rex64_ms_sysv_vzeroupper): Ditto. (*call_value_pop): Merge insn pattern from *call_value_pop_0 and *call_value_pop_1. Use "rzm" constraint for operand 1. (*call_value_pop_vzeroupper): Ditto. (*sibcall_value): Merge insn pattern from *sibcall_value_0, *sibcall_value_1 and *sibcall_value_1_rex64 patterns using "P" mode iterator. Use "Uz" constraint for operand 1. (*sibcall_value_vzeroupper): Ditto. (*sibcall_value_rex64_ms_sysv): Ditto. (*sibcall_value_rex64_ms_sysv_vzeroupper): Ditto. (*sibcall_value_pop): Rename from *sibcall_pop_1. Use "rzm" constraint for operand 1. (*sibcall_value_pop_vzeroupper): Ditto. (*tls_global_dynamic_64): Use constant_call_address_operand predicate and "z" constraint for operand 2. (*tls_global_dynamic_32_gnu): Ditto. (*tls_local_dynamic_base_32_gnu): Ditto. (*tls_local_dynamic_base_64): Ditto. (*tls_local_dynamic_32_once): Ditto. * config/i386/i386.c (ix86_output_call_insn): Remove int_addr argument, update all callers. * config/i386/i386-protos.h (ix86_output_call_insn): Update prototype. Patch was tested on x86_64-pc-linux-gnu {,-m32} AVX and non-AVX target. I will wait for eventual comments before committing it to mainline SVN. Uros. Index: i386.md =================================================================== --- i386.md (revision 173786) +++ i386.md (working copy) @@ -11064,56 +11064,131 @@ ;; P6 processors will jump to the address after the decrement when %esp ;; 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. - + ;; Call subroutine returning no value. -(define_expand "call_pop" - [(parallel [(call (match_operand:QI 0 "" "") - (match_operand:SI 1 "" "")) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 3 "" "")))])] - "!TARGET_64BIT" +(define_expand "call" + [(call (match_operand:QI 0 "" "") + (match_operand 1 "" "")) + (use (match_operand 2 "" ""))] + "" { ix86_expand_call (NULL, operands[0], operands[1], - operands[2], operands[3], 0); + operands[2], NULL, 0); + DONE; +}) + +(define_expand "sibcall" + [(call (match_operand:QI 0 "" "") + (match_operand 1 "" "")) + (use (match_operand 2 "" ""))] + "" +{ + ix86_expand_call (NULL, operands[0], operands[1], + operands[2], NULL, 1); DONE; }) -(define_insn_and_split "*call_pop_0_vzeroupper" +(define_insn_and_split "*call_vzeroupper" + [(call (mem:QI (match_operand:P 0 "call_insn_operand" "rzm")) + (match_operand 1 "" "")) + (unspec [(match_operand 2 "const_int_operand" "")] + UNSPEC_CALL_NEEDS_VZEROUPPER)] + "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" + "#" + "&& reload_completed" + [(const_int 0)] + "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" + [(set_attr "type" "call")]) + +(define_insn "*call" + [(call (mem:QI (match_operand:P 0 "call_insn_operand" "rzm")) + (match_operand 1 "" ""))] + "!SIBLING_CALL_P (insn)" + "* return ix86_output_call_insn (insn, operands[0]);" + [(set_attr "type" "call")]) + +(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper" [(parallel - [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) - (match_operand:SI 1 "" "")) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 2 "immediate_operand" "")))]) - (unspec [(match_operand 3 "const_int_operand" "")] + [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm")) + (match_operand 1 "" "")) + (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) + (clobber (reg:TI XMM6_REG)) + (clobber (reg:TI XMM7_REG)) + (clobber (reg:TI XMM8_REG)) + (clobber (reg:TI XMM9_REG)) + (clobber (reg:TI XMM10_REG)) + (clobber (reg:TI XMM11_REG)) + (clobber (reg:TI XMM12_REG)) + (clobber (reg:TI XMM13_REG)) + (clobber (reg:TI XMM14_REG)) + (clobber (reg:TI XMM15_REG)) + (clobber (reg:DI SI_REG)) + (clobber (reg:DI DI_REG))]) + (unspec [(match_operand 2 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT" + "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" "#" "&& reload_completed" [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" + "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" [(set_attr "type" "call")]) -(define_insn "*call_pop_0" - [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) - (match_operand:SI 1 "" "")) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 2 "immediate_operand" "")))] +(define_insn "*call_rex64_ms_sysv" + [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm")) + (match_operand 1 "" "")) + (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) + (clobber (reg:TI XMM6_REG)) + (clobber (reg:TI XMM7_REG)) + (clobber (reg:TI XMM8_REG)) + (clobber (reg:TI XMM9_REG)) + (clobber (reg:TI XMM10_REG)) + (clobber (reg:TI XMM11_REG)) + (clobber (reg:TI XMM12_REG)) + (clobber (reg:TI XMM13_REG)) + (clobber (reg:TI XMM14_REG)) + (clobber (reg:TI XMM15_REG)) + (clobber (reg:DI SI_REG)) + (clobber (reg:DI DI_REG))] + "TARGET_64BIT && !SIBLING_CALL_P (insn)" + "* return ix86_output_call_insn (insn, operands[0]);" + [(set_attr "type" "call")]) + +(define_insn_and_split "*sibcall_vzeroupper" + [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) + (match_operand 1 "" "")) + (unspec [(match_operand 2 "const_int_operand" "")] + UNSPEC_CALL_NEEDS_VZEROUPPER)] + "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" + "#" + "&& reload_completed" + [(const_int 0)] + "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" + [(set_attr "type" "call")]) + +(define_insn "*sibcall" + [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz")) + (match_operand 1 "" ""))] + "SIBLING_CALL_P (insn)" + "* return ix86_output_call_insn (insn, operands[0]);" + [(set_attr "type" "call")]) + +(define_expand "call_pop" + [(parallel [(call (match_operand:QI 0 "" "") + (match_operand:SI 1 "" "")) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) + (match_operand:SI 3 "" "")))])] "!TARGET_64BIT" { - if (SIBLING_CALL_P (insn)) - return "jmp\t%P0"; - else - return "call\t%P0"; -} - [(set_attr "type" "call")]) + ix86_expand_call (NULL, operands[0], operands[1], + operands[2], operands[3], 0); + DONE; +}) -(define_insn_and_split "*call_pop_1_vzeroupper" +(define_insn_and_split "*call_pop_vzeroupper" [(parallel - [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm")) + [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rzm")) (match_operand:SI 1 "" "")) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) @@ -11127,27 +11202,23 @@ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" [(set_attr "type" "call")]) -(define_insn "*call_pop_1" - [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm")) - (match_operand:SI 1 "" "")) +(define_insn "*call_pop" + [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rzm")) + (match_operand 1 "" "")) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand:SI 2 "immediate_operand" "i")))] "!TARGET_64BIT && !SIBLING_CALL_P (insn)" -{ - if (constant_call_address_operand (operands[0], Pmode)) - return "call\t%P0"; - return "call\t%A0"; -} + "* return ix86_output_call_insn (insn, operands[0]);" [(set_attr "type" "call")]) -(define_insn_and_split "*sibcall_pop_1_vzeroupper" +(define_insn_and_split "*sibcall_pop_vzeroupper" [(parallel - [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U")) - (match_operand:SI 1 "" "")) + [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) + (match_operand 1 "" "")) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) - (match_operand:SI 2 "immediate_operand" "i,i")))]) + (match_operand:SI 2 "immediate_operand" "i")))]) (unspec [(match_operand 3 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" @@ -11157,120 +11228,89 @@ "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" [(set_attr "type" "call")]) -(define_insn "*sibcall_pop_1" - [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U")) - (match_operand:SI 1 "" "")) +(define_insn "*sibcall_pop" + [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz")) + (match_operand 1 "" "")) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) - (match_operand:SI 2 "immediate_operand" "i,i")))] + (match_operand:SI 2 "immediate_operand" "i")))] "!TARGET_64BIT && SIBLING_CALL_P (insn)" - "@ - jmp\t%P0 - jmp\t%A0" + "* return ix86_output_call_insn (insn, operands[0]);" [(set_attr "type" "call")]) -(define_expand "call" - [(call (match_operand:QI 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" ""))] +;; Call subroutine, returning value in operand 0 + +(define_expand "call_value" + [(set (match_operand 0 "" "") + (call (match_operand:QI 1 "" "") + (match_operand 2 "" ""))) + (use (match_operand 3 "" ""))] "" { - ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0); + ix86_expand_call (operands[0], operands[1], operands[2], + operands[3], NULL, 0); DONE; }) -(define_expand "sibcall" - [(call (match_operand:QI 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" ""))] +(define_expand "sibcall_value" + [(set (match_operand 0 "" "") + (call (match_operand:QI 1 "" "") + (match_operand 2 "" ""))) + (use (match_operand 3 "" ""))] "" { - ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1); + ix86_expand_call (operands[0], operands[1], operands[2], + operands[3], NULL, 1); DONE; }) -(define_insn_and_split "*call_0_vzeroupper" - [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) - (match_operand 1 "" "")) - (unspec [(match_operand 2 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" - [(set_attr "type" "call")]) - -(define_insn "*call_0" - [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) - (match_operand 1 "" ""))] - "" - { return ix86_output_call_insn (insn, operands[0], 0); } - [(set_attr "type" "call")]) - -(define_insn_and_split "*call_1_vzeroupper" - [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm")) - (match_operand 1 "" "")) - (unspec [(match_operand 2 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" - [(set_attr "type" "call")]) - -(define_insn "*call_1" - [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm")) - (match_operand 1 "" ""))] - "!TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[0], 0); } - [(set_attr "type" "call")]) - -(define_insn_and_split "*sibcall_1_vzeroupper" - [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U")) - (match_operand 1 "" "")) - (unspec [(match_operand 2 "const_int_operand" "")] +(define_insn_and_split "*call_value_vzeroupper" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:P 1 "call_insn_operand" "rzm")) + (match_operand 2 "" ""))) + (unspec [(match_operand 3 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" + "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)" "#" "&& reload_completed" [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" - [(set_attr "type" "call")]) + "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" + [(set_attr "type" "callv")]) -(define_insn "*sibcall_1" - [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U")) - (match_operand 1 "" ""))] - "!TARGET_64BIT && SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[0], 0); } - [(set_attr "type" "call")]) +(define_insn "*call_value" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:P 1 "call_insn_operand" "rzm")) + (match_operand 2 "" "")))] + "!SIBLING_CALL_P (insn)" + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) -(define_insn_and_split "*call_1_rex64_vzeroupper" - [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) - (match_operand 1 "" "")) - (unspec [(match_operand 2 "const_int_operand" "")] +(define_insn_and_split "*sibcall_value_vzeroupper" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) + (match_operand 2 "" ""))) + (unspec [(match_operand 3 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn) - && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" + "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)" "#" "&& reload_completed" [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" - [(set_attr "type" "call")]) + "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" + [(set_attr "type" "callv")]) -(define_insn "*call_1_rex64" - [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) - (match_operand 1 "" ""))] - "TARGET_64BIT && !SIBLING_CALL_P (insn) - && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" - { return ix86_output_call_insn (insn, operands[0], 0); } - [(set_attr "type" "call")]) +(define_insn "*sibcall_value" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz")) + (match_operand 2 "" "")))] + "SIBLING_CALL_P (insn)" + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) -(define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper" +(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper" [(parallel - [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) - (match_operand 1 "" "")) + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm")) + (match_operand 2 "" ""))) (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) (clobber (reg:TI XMM6_REG)) (clobber (reg:TI XMM7_REG)) @@ -11284,18 +11324,19 @@ (clobber (reg:TI XMM15_REG)) (clobber (reg:DI SI_REG)) (clobber (reg:DI DI_REG))]) - (unspec [(match_operand 2 "const_int_operand" "")] + (unspec [(match_operand 3 "const_int_operand" "")] UNSPEC_CALL_NEEDS_VZEROUPPER)] "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" "#" "&& reload_completed" [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" - [(set_attr "type" "call")]) + "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" + [(set_attr "type" "callv")]) -(define_insn "*call_1_rex64_ms_sysv" - [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) - (match_operand 1 "" "")) +(define_insn "*call_value_rex64_ms_sysv" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm")) + (match_operand 2 "" ""))) (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) (clobber (reg:TI XMM6_REG)) (clobber (reg:TI XMM7_REG)) @@ -11310,48 +11351,9 @@ (clobber (reg:DI SI_REG)) (clobber (reg:DI DI_REG))] "TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[0], 0); } - [(set_attr "type" "call")]) - -(define_insn_and_split "*call_1_rex64_large_vzeroupper" - [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm")) - (match_operand 1 "" "")) - (unspec [(match_operand 2 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" - [(set_attr "type" "call")]) - -(define_insn "*call_1_rex64_large" - [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm")) - (match_operand 1 "" ""))] - "TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[0], 0); } - [(set_attr "type" "call")]) - -(define_insn_and_split "*sibcall_1_rex64_vzeroupper" - [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U")) - (match_operand 1 "" "")) - (unspec [(match_operand 2 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;" - [(set_attr "type" "call")]) - -(define_insn "*sibcall_1_rex64" - [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U")) - (match_operand 1 "" ""))] - "TARGET_64BIT && SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[0], 0); } - [(set_attr "type" "call")]) + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) -;; Call subroutine, returning value in operand 0 (define_expand "call_value_pop" [(parallel [(set (match_operand 0 "" "") (call (match_operand:QI 1 "" "") @@ -11366,31 +11368,61 @@ DONE; }) -(define_expand "call_value" +(define_insn_and_split "*call_value_pop_vzeroupper" + [(parallel + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rzm")) + (match_operand 2 "" ""))) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) + (match_operand:SI 3 "immediate_operand" "i")))]) + (unspec [(match_operand 4 "const_int_operand" "")] + UNSPEC_CALL_NEEDS_VZEROUPPER)] + "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" + "#" + "&& reload_completed" + [(const_int 0)] + "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" + [(set_attr "type" "callv")]) + +(define_insn "*call_value_pop" [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "" "") - (match_operand:SI 2 "" ""))) - (use (match_operand:SI 3 "" ""))] - ;; Operand 3 is not used on the i386. - "" -{ - ix86_expand_call (operands[0], operands[1], operands[2], - operands[3], NULL, 0); - DONE; -}) + (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rzm")) + (match_operand 2 "" ""))) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) + (match_operand:SI 3 "immediate_operand" "i")))] + "!TARGET_64BIT && !SIBLING_CALL_P (insn)" + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) -(define_expand "sibcall_value" +(define_insn_and_split "*sibcall_value_pop_vzeroupper" + [(parallel + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) + (match_operand 2 "" ""))) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) + (match_operand:SI 3 "immediate_operand" "i")))]) + (unspec [(match_operand 4 "const_int_operand" "")] + UNSPEC_CALL_NEEDS_VZEROUPPER)] + "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" + "#" + "&& reload_completed" + [(const_int 0)] + "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" + [(set_attr "type" "callv")]) + +(define_insn "*sibcall_value_pop" [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "" "") - (match_operand:SI 2 "" ""))) - (use (match_operand:SI 3 "" ""))] - ;; Operand 3 is not used on the i386. - "" -{ - ix86_expand_call (operands[0], operands[1], operands[2], - operands[3], NULL, 1); - DONE; -}) + (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz")) + (match_operand 2 "" ""))) + (set (reg:SI SP_REG) + (plus:SI (reg:SI SP_REG) + (match_operand:SI 3 "immediate_operand" "i")))] + "!TARGET_64BIT && SIBLING_CALL_P (insn)" + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) ;; Call subroutine returning any type. @@ -12322,7 +12354,7 @@ [(set (match_operand:SI 0 "register_operand" "=a") (unspec:SI [(match_operand:SI 1 "register_operand" "b") (match_operand:SI 2 "tls_symbolic_operand" "") - (match_operand:SI 3 "call_insn_operand" "")] + (match_operand:SI 3 "constant_call_address_operand" "z")] UNSPEC_TLS_GD)) (clobber (match_scratch:SI 4 "=d")) (clobber (match_scratch:SI 5 "=c")) @@ -12337,7 +12369,7 @@ (unspec:SI [(match_operand:SI 2 "register_operand" "") (match_operand:SI 1 "tls_symbolic_operand" "") - (match_operand:SI 3 "call_insn_operand" "")] + (match_operand:SI 3 "constant_call_address_operand" "")] UNSPEC_TLS_GD)) (clobber (match_scratch:SI 4 "")) (clobber (match_scratch:SI 5 "")) @@ -12345,8 +12377,9 @@ (define_insn "*tls_global_dynamic_64" [(set (match_operand:DI 0 "register_operand" "=a") - (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" "")) - (match_operand:DI 3 "" ""))) + (call:DI + (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z")) + (match_operand:DI 3 "" ""))) (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] UNSPEC_TLS_GD)] "TARGET_64BIT" @@ -12357,7 +12390,7 @@ (define_expand "tls_global_dynamic_64" [(parallel [(set (match_operand:DI 0 "register_operand" "") (call:DI - (mem:QI (match_operand:DI 2 "call_insn_operand" "")) + (mem:QI (match_operand:DI 2 "constant_call_address_operand" "")) (const_int 0))) (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] UNSPEC_TLS_GD)])]) @@ -12365,7 +12398,7 @@ (define_insn "*tls_local_dynamic_base_32_gnu" [(set (match_operand:SI 0 "register_operand" "=a") (unspec:SI [(match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "call_insn_operand" "")] + (match_operand:SI 2 "constant_call_address_operand" "z")] UNSPEC_TLS_LD_BASE)) (clobber (match_scratch:SI 3 "=d")) (clobber (match_scratch:SI 4 "=c")) @@ -12378,7 +12411,7 @@ (define_expand "tls_local_dynamic_base_32" [(parallel [(set (match_operand:SI 0 "register_operand" "") (unspec:SI [(match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "call_insn_operand" "")] + (match_operand:SI 2 "constant_call_address_operand" "")] UNSPEC_TLS_LD_BASE)) (clobber (match_scratch:SI 3 "")) (clobber (match_scratch:SI 4 "")) @@ -12386,7 +12419,7 @@ (define_insn "*tls_local_dynamic_base_64" [(set (match_operand:DI 0 "register_operand" "=a") - (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" "")) + (call:DI (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z")) (match_operand:DI 2 "" ""))) (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] "TARGET_64BIT" @@ -12397,7 +12430,7 @@ (define_expand "tls_local_dynamic_base_64" [(parallel [(set (match_operand:DI 0 "register_operand" "") (call:DI - (mem:QI (match_operand:DI 1 "call_insn_operand" "")) + (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) (const_int 0))) (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]) @@ -12407,7 +12440,7 @@ (define_insn_and_split "*tls_local_dynamic_32_once" [(set (match_operand:SI 0 "register_operand" "=a") (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "call_insn_operand" "")] + (match_operand:SI 2 "constant_call_address_operand" "z")] UNSPEC_TLS_LD_BASE) (const:SI (unspec:SI [(match_operand:SI 3 "tls_symbolic_operand" "")] @@ -17160,338 +17193,6 @@ operands[0] = dest; }) -;; Call-value patterns last so that the wildcard operand does not -;; disrupt insn-recog's switch tables. - -(define_insn_and_split "*call_value_pop_0_vzeroupper" - [(parallel - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) - (match_operand:SI 2 "" ""))) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 3 "immediate_operand" "")))]) - (unspec [(match_operand 4 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_pop_0" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) - (match_operand:SI 2 "" ""))) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 3 "immediate_operand" "")))] - "!TARGET_64BIT" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_pop_1_vzeroupper" - [(parallel - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm")) - (match_operand:SI 2 "" ""))) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 3 "immediate_operand" "i")))]) - (unspec [(match_operand 4 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_pop_1" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm")) - (match_operand:SI 2 "" ""))) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 3 "immediate_operand" "i")))] - "!TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*sibcall_value_pop_1_vzeroupper" - [(parallel - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U")) - (match_operand:SI 2 "" ""))) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 3 "immediate_operand" "i,i")))]) - (unspec [(match_operand 4 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*sibcall_value_pop_1" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U")) - (match_operand:SI 2 "" ""))) - (set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) - (match_operand:SI 3 "immediate_operand" "i,i")))] - "!TARGET_64BIT && SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_0_vzeroupper" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) - (match_operand:SI 2 "" ""))) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_0" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) - (match_operand:SI 2 "" "")))] - "!TARGET_64BIT" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_0_rex64_vzeroupper" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) - (match_operand:DI 2 "const_int_operand" ""))) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_0_rex64" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) - (match_operand:DI 2 "const_int_operand" "")))] - "TARGET_64BIT" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_0_rex64_ms_sysv_vzeroupper" - [(parallel - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) - (match_operand:DI 2 "const_int_operand" ""))) - (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) - (clobber (reg:TI XMM6_REG)) - (clobber (reg:TI XMM7_REG)) - (clobber (reg:TI XMM8_REG)) - (clobber (reg:TI XMM9_REG)) - (clobber (reg:TI XMM10_REG)) - (clobber (reg:TI XMM11_REG)) - (clobber (reg:TI XMM12_REG)) - (clobber (reg:TI XMM13_REG)) - (clobber (reg:TI XMM14_REG)) - (clobber (reg:TI XMM15_REG)) - (clobber (reg:DI SI_REG)) - (clobber (reg:DI DI_REG))]) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_0_rex64_ms_sysv" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) - (match_operand:DI 2 "const_int_operand" ""))) - (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) - (clobber (reg:TI XMM6_REG)) - (clobber (reg:TI XMM7_REG)) - (clobber (reg:TI XMM8_REG)) - (clobber (reg:TI XMM9_REG)) - (clobber (reg:TI XMM10_REG)) - (clobber (reg:TI XMM11_REG)) - (clobber (reg:TI XMM12_REG)) - (clobber (reg:TI XMM13_REG)) - (clobber (reg:TI XMM14_REG)) - (clobber (reg:TI XMM15_REG)) - (clobber (reg:DI SI_REG)) - (clobber (reg:DI DI_REG))] - "TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_1_vzeroupper" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm")) - (match_operand:SI 2 "" ""))) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_1" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm")) - (match_operand:SI 2 "" "")))] - "!TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*sibcall_value_1_vzeroupper" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U")) - (match_operand:SI 2 "" ""))) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*sibcall_value_1" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U")) - (match_operand:SI 2 "" "")))] - "!TARGET_64BIT && SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_1_rex64_vzeroupper" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) - (match_operand:DI 2 "" ""))) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn) - && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_1_rex64" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) - (match_operand:DI 2 "" "")))] - "TARGET_64BIT && !SIBLING_CALL_P (insn) - && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper" - [(parallel - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) - (match_operand:DI 2 "" ""))) - (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) - (clobber (reg:TI XMM6_REG)) - (clobber (reg:TI XMM7_REG)) - (clobber (reg:TI XMM8_REG)) - (clobber (reg:TI XMM9_REG)) - (clobber (reg:TI XMM10_REG)) - (clobber (reg:TI XMM11_REG)) - (clobber (reg:TI XMM12_REG)) - (clobber (reg:TI XMM13_REG)) - (clobber (reg:TI XMM14_REG)) - (clobber (reg:TI XMM15_REG)) - (clobber (reg:DI SI_REG)) - (clobber (reg:DI DI_REG))]) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_1_rex64_ms_sysv" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) - (match_operand:DI 2 "" ""))) - (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) - (clobber (reg:TI XMM6_REG)) - (clobber (reg:TI XMM7_REG)) - (clobber (reg:TI XMM8_REG)) - (clobber (reg:TI XMM9_REG)) - (clobber (reg:TI XMM10_REG)) - (clobber (reg:TI XMM11_REG)) - (clobber (reg:TI XMM12_REG)) - (clobber (reg:TI XMM13_REG)) - (clobber (reg:TI XMM14_REG)) - (clobber (reg:TI XMM15_REG)) - (clobber (reg:DI SI_REG)) - (clobber (reg:DI DI_REG))] - "TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*call_value_1_rex64_large_vzeroupper" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm")) - (match_operand:DI 2 "" ""))) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*call_value_1_rex64_large" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm")) - (match_operand:DI 2 "" "")))] - "TARGET_64BIT && !SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - -(define_insn_and_split "*sibcall_value_1_rex64_vzeroupper" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U")) - (match_operand:DI 2 "" ""))) - (unspec [(match_operand 3 "const_int_operand" "")] - UNSPEC_CALL_NEEDS_VZEROUPPER)] - "TARGET_VZEROUPPER && TARGET_64BIT && SIBLING_CALL_P (insn)" - "#" - "&& reload_completed" - [(const_int 0)] - "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;" - [(set_attr "type" "callv")]) - -(define_insn "*sibcall_value_1_rex64" - [(set (match_operand 0 "" "") - (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U")) - (match_operand:DI 2 "" "")))] - "TARGET_64BIT && SIBLING_CALL_P (insn)" - { return ix86_output_call_insn (insn, operands[1], 1); } - [(set_attr "type" "callv")]) - ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. ;; That, however, is usually mapped by the OS to SIGSEGV, which is often ;; caught for use by garbage collectors and the like. Using an insn that Index: constraints.md =================================================================== --- constraints.md (revision 173786) +++ constraints.md (working copy) @@ -19,7 +19,7 @@ ;;; Unused letters: ;;; B H T W -;;; h jk vw z +;;; h jk vw ;; Integer register constraints. ;; It is not necessary to define 'r' here. @@ -115,6 +115,10 @@ "optimize_function_for_speed_p (cfun) ? GENERAL_REGS : NO_REGS" "@internal Any integer register when integer XFmode moves are enabled.") +(define_constraint "z" + "@internal Constant call address operand." + (match_operand 0 "constant_call_address_operand")) + ;; Integer constant constraints. (define_constraint "I" "Integer constant in the range 0 @dots{} 31, for 32-bit shifts." Index: i386-protos.h =================================================================== --- i386-protos.h (revision 173786) +++ i386-protos.h (working copy) @@ -270,7 +270,7 @@ extern int asm_preferred_eh_data_format extern enum attr_cpu ix86_schedule; #endif -extern const char * ix86_output_call_insn (rtx insn, rtx call_op, int addr_op); +extern const char * ix86_output_call_insn (rtx insn, rtx call_op); #ifdef RTX_CODE /* Target data for multipass lookahead scheduling. Index: i386.c =================================================================== --- i386.c (revision 173786) +++ i386.c (working copy) @@ -22073,23 +22073,25 @@ ix86_split_call_vzeroupper (rtx insn, rt /* Output the assembly for a call instruction. */ const char * -ix86_output_call_insn (rtx insn, rtx call_op, int addr_op) +ix86_output_call_insn (rtx insn, rtx call_op) { bool direct_p = constant_call_address_operand (call_op, Pmode); bool seh_nop_p = false; - - gcc_assert (addr_op == 0 || addr_op == 1); + const char *xasm; if (SIBLING_CALL_P (insn)) { if (direct_p) - return addr_op ? "jmp\t%P1" : "jmp\t%P0"; + xasm = "jmp\t%P0"; /* SEH epilogue detection requires the indirect branch case to include REX.W. */ else if (TARGET_SEH) - return addr_op ? "rex.W jmp %A1" : "rex.W jmp %A0"; + xasm = "rex.W jmp %A0"; else - return addr_op ? "jmp\t%A1" : "jmp\t%A0"; + xasm = "jmp\t%A0"; + + output_asm_insn (xasm, &call_op); + return ""; } /* SEH unwinding can require an extra nop to be emitted in several @@ -22123,19 +22125,16 @@ ix86_output_call_insn (rtx insn, rtx cal } if (direct_p) - { - if (seh_nop_p) - return addr_op ? "call\t%P1\n\tnop" : "call\t%P0\n\tnop"; - else - return addr_op ? "call\t%P1" : "call\t%P0"; - } + xasm = "call\t%P0"; else - { - if (seh_nop_p) - return addr_op ? "call\t%A1\n\tnop" : "call\t%A0\n\tnop"; - else - return addr_op ? "call\t%A1" : "call\t%A0"; - } + xasm = "call\t%A0"; + + output_asm_insn (xasm, &call_op); + + if (seh_nop_p) + return "nop"; + + return ""; } /* Clear stack slot assignments remembered from previous functions.