Patchwork [i386] : Introduce "z" constraint and merge call patterns

login
register
mail settings
Submitter Uros Bizjak
Date May 16, 2011, 6:27 p.m.
Message ID <BANLkTimofG2ruC_bw3CcuW8j0qUjaEnqZg@mail.gmail.com>
Download mbox | patch
Permalink /patch/95799/
State New
Headers show

Comments

Uros Bizjak - May 16, 2011, 6:27 p.m.
On Mon, May 16, 2011 at 3:44 PM, Uros Bizjak <ubizjak@gmail.com> wrote:

> 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".

This in fact does not work... a slightly changed patch that leaves "l"
constraint for 32bit targets was committed to SVN.

2011-05-16  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/constraints.md (z): New constraint.
	* config/i386/i386.c (c): New mode attribute.
	(*call): Merge insn pattern from *call_0, *call_1, *call_1_rex64 and
	*call_1_rex64_large patterns using "P" mode iterator. Use "<c>zm"
	constraint for operand 0.
	(*call_vzeroupper): Ditto.
	(*call_rex64_ms_sysv): Ditto.  Use "rzm" constraint for operand 0.
	(*call_rex64_ms_sysv_vzeroupper): Ditto.
	(*call_pop): Merge insn pattern from *call_pop_0 and *call_pop_1.
	Use "lzm" 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 "Uz" 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 "<c>zm" constraint for operand 1.
	(*call_value_vzeroupper): Ditto.
	(*call_value_rex64_ms_sysv): Ditto.  Use "rzm" constraint
	for operand 0.
	(*call_value_rex64_ms_sysv_vzeroupper): Ditto.
	(*call_value_pop): Merge insn pattern from *call_value_pop_0 and
	*call_value_pop_1.  Use "lzm" 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 "Uz"
	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.

testsuite/ChangeLog:

2011-05-16  Uros Bizjak  <ubizjak@gmail.com>

	* gcc.target/i386/avx-vzeroupper-16.c: Update scan-assembler-times
	scan pattern.
	* gcc.target/i386/avx-vzeroupper-17.c: Ditto.
	* gcc.target/i386/avx-vzeroupper-18.c: Ditto.

Re-tested on x86_64-pc-linux-gnu {,-m32} AVX and non-AVX target,
committed to mainline SVN.

Uros.

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 173775)
+++ config/i386/i386.md	(working copy)
@@ -11064,56 +11064,134 @@ 
 ;; 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.
- 
+
+;; Register constraint for call instruction.
+(define_mode_attr c [(SI "l") (DI "r")])
+
 ;; 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_insn_and_split "*call_pop_0_vzeroupper"
+(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_vzeroupper"
+  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zm"))
+	 (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" "<c>zm"))
+	 (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" "lzm"))
 	   (match_operand:SI 1 "" ""))
      (set (reg:SI SP_REG)
 	  (plus:SI (reg:SI SP_REG)
@@ -11127,27 +11205,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" "lzm"))
+	 (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 +11231,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" "")]
+(define_insn_and_split "*call_value_vzeroupper"
+  [(set (match_operand 0 "" "")
+	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+	      (match_operand 2 "" "")))
+   (unspec [(match_operand 3 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
-  "TARGET_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")])
+  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
+  [(set_attr "type" "callv")])
 
-(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 "*call_value"
+  [(set (match_operand 0 "" "")
+	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zm"))
+	      (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_vzeroupper"
-  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
-	 (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)"
+  "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"
-  [(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 "*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 "*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" "")]
-   	   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"
-  [(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_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" "")]
-   	   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[2]); DONE;"
-  [(set_attr "type" "call")])
-
-(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_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 +11327,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 +11354,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")])
+  "* return ix86_output_call_insn (insn, operands[1]);"
+  [(set_attr "type" "callv")])
 
-(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")])
-
-;; Call subroutine, returning value in operand 0
 (define_expand "call_value_pop"
   [(parallel [(set (match_operand 0 "" "")
 		   (call (match_operand:QI 1 "" "")
@@ -11366,31 +11371,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" "lzm"))
+		(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" "lzm"))
+	      (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 +12357,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 +12372,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 +12380,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 +12393,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 +12401,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 +12414,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 +12422,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 +12433,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 +12443,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 +17196,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: config/i386/constraints.md
===================================================================
--- config/i386/constraints.md	(revision 173775)
+++ config/i386/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: config/i386/i386-protos.h
===================================================================
--- config/i386/i386-protos.h	(revision 173775)
+++ config/i386/i386-protos.h	(working copy)
@@ -270,7 +270,7 @@ 
 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: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 173775)
+++ config/i386/i386.c	(working copy)
@@ -22073,23 +22073,25 @@ 
 /* 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;
+  const char *xasm;
 
-  gcc_assert (addr_op == 0 || addr_op == 1);
-
   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 @@ 
     }
 
   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.
Index: testsuite/gcc.target/i386/avx-vzeroupper-17.c
===================================================================
--- testsuite/gcc.target/i386/avx-vzeroupper-17.c	(revision 173425)
+++ testsuite/gcc.target/i386/avx-vzeroupper-17.c	(working copy)
@@ -15,4 +15,4 @@ 
 }
 
 /* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
-/* { dg-final { scan-assembler-times "\\*call_value_1_rex64_ms_sysv" 1 } } */
+/* { dg-final { scan-assembler-times "\\*call_value_rex64_ms_sysv" 1 } } */
Index: testsuite/gcc.target/i386/avx-vzeroupper-16.c
===================================================================
--- testsuite/gcc.target/i386/avx-vzeroupper-16.c	(revision 173425)
+++ testsuite/gcc.target/i386/avx-vzeroupper-16.c	(working copy)
@@ -6,7 +6,7 @@ 
 
 extern __m256 x;
 
-extern __m256 __attribute__ ((sysv_abi))  bar (__m256);
+extern __m256 __attribute__ ((sysv_abi)) bar (__m256);
 
 void
 foo (void)
@@ -15,4 +15,4 @@ 
 }
 
 /* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
-/* { dg-final { scan-assembler-times "\\*call_value_0_rex64_ms_sysv" 1 } } */
+/* { dg-final { scan-assembler-times "\\*call_value_rex64_ms_sysv" 1 } } */
Index: testsuite/gcc.target/i386/avx-vzeroupper-18.c
===================================================================
--- testsuite/gcc.target/i386/avx-vzeroupper-18.c	(revision 173425)
+++ testsuite/gcc.target/i386/avx-vzeroupper-18.c	(working copy)
@@ -15,4 +15,4 @@ 
 }
 
 /* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
-/* { dg-final { scan-assembler-times "\\*call_1_rex64_ms_sysv" 1 } } */
+/* { dg-final { scan-assembler-times "\\*call_rex64_ms_sysv" 1 } } */