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

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

Comments

Uros Bizjak - May 16, 2011, 1:44 p.m.
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  <ubizjak@gmail.com>

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

Patch

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.